0.2.1 • Published 3 years ago

graph-squirrel v0.2.1

Weekly downloads
6
License
MIT
Repository
github
Last release
3 years ago

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

  1. 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
}
  1. 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.

License

MIT

0.2.1

3 years ago

0.2.0

3 years ago

0.1.2

3 years ago

0.1.1

3 years ago

0.1.0

3 years ago