0.2.1 • Published 3 years ago
graph-squirrel v0.2.1
Graph Squirrel
Graph Squirrel is a JavaScript/TypeScript library to translate GraphQL requests with your SQL query:
- 🚀 Efficient: Graph Squirrel leverages join information in your schema to retrieve all required data in a single query.
- 🧬 Generic: Use Graph Squirrel with a server implementation or SQL library of your own choice.
- 🔌 Pluggable: Since Graph Squirrel is an implementation detail of your resolvers, it can be used at any level of your resolver chain. Entities retrieved from your SQL database can then be enriched with child resolvers.
Supported features
- Joins
- Filters
- Sort
- Offset-based pagination
Installation
npm i graph-quirrel # using npm
yarn graph-squirrel # using yarn
Basic usage
- Use directives to map object fields with SQL tables and columns:
type Query {
# use @join to map a field to a SQL table
users: [User] @join(name: "tickets_table")
}
type User {
# use @column to map a field with a SQL column
id: GraphQLInt @column
# if a field depends on multiple SQL columns, you can provide
# the corresponding column names as a list
# note: you'll have to implement a resolver for `displayName`
displayName: GraphQLString @column(names: ["givenName", "surname"])
# use @join with ownKey/foreignKey to link your SQL tables together
# and retrieve all data in a single query
tickets: [Ticket]
@join(name: "tickets_table", ownKey: "id", foreignKey: "userId")
}
type Ticket {
id: GraphQLInt @column
title: GraphQLString @column
}
- Within your resolvers, use
ASTQueryTranslator
to translate GraphQL resolve information into a SQL query:
const queryResolver = {
users(source, args, parent, info) {
const translator = new ASTQueryTranslator(info),
query = translator.run();
const [queryStr, bindings] = query.buildQuery();
// run your query against a MS SQL database
return new Promise((resolve, reject) => {
sql.query(
process.env.CONNECTION_STRING,
queryStr,
bindings,
(err, rows) => {
if (err || !rows) reject(err);
// use `transform` to convert rows into a GraphQL result
else resolve(translator.transform(rows!));
}
);
});
},
};
Query example
{
users {
id
displayName
tickets {
title
}
}
}
The above query will give you the following JSON data:
{
"users": [
{
"id": 1,
"givenName": "Bob",
"surname": "McCain",
"tickets": [{ "title": "Ticket #1" }, { "title": "Ticket #2" }]
}
]
}
Note: givenName
and surname
are automatically retrieved as dependencies for displayName
. However, it's up to you to define a custom resolver to compute its effective value, e.g.:
const userResolver = {
displayName(source) {
return `${source.givenName} ${source.surname}`;
},
};
Contributing
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
Please make sure to update tests as appropriate.