GraphQL Schemas — Easier & Better Structure

Written by neapnic | Published 2017/08/07
Tech Story Tags: apollo | api | graphql

TLDRvia the TL;DR App

SchemaGlue.js and graphql-s2s.js will respectively help breaking down your schema into modules and add support for inheritance and generic types.

Part I — Organising Your GraphQL Schema & Resolvers

If you’ve been using the awesome graphql-tools from Apollo to build GraphQL server on node.js, and if your codebase has started to grow beyond the usual HelloWorld demo project, then you must have started to wonder what would be a good way to organise your schema beyond the usual big monolithic string. For example, let’s have a look at the following:

<a href="https://medium.com/media/0ceab86c0c492e1b828b5fc4c016e12c/href">https://medium.com/media/0ceab86c0c492e1b828b5fc4c016e12c/href</a>

The above demonstrates the usual HelloWorld project with a monolithic schema.js file under the src folder. That schema.js contains both the GraphQL schema and the resolvers. But as your code grows, what would be better is to organise your code around something like this instead:

<a href="https://medium.com/media/d852015e6795beb1dab1b6141bd531c0/href">https://medium.com/media/d852015e6795beb1dab1b6141bd531c0/href</a>

Where the code could be refactor this way:

<a href="https://medium.com/media/c210b4bc38a404d8c3ccb16f0ecfbda4/href">https://medium.com/media/c210b4bc38a404d8c3ccb16f0ecfbda4/href</a>

SchemaGlue.js is our nice addition to the Apollo ecosystem to organise your code. Our team at Neap has just opened source it, so feel free to give it a go here.

Part II — Adding Support For GraphQL Type Inheritance & Generic Typing

After having written a series of GraphQL APIs, we’ve realised that we were duplicating a lot of code as we’re writing our GraphQL schemas. We created _graphql-s2_s (schema-2-schema) to be able to rewrite schema that looked like this:

<a href="https://medium.com/media/209bc0e8dd5e20178f4d8bfef0f8be33/href">https://medium.com/media/209bc0e8dd5e20178f4d8bfef0f8be33/href</a>

to something like this:

<a href="https://medium.com/media/8275a1304642f6d372b817a956ae68e7/href">https://medium.com/media/8275a1304642f6d372b817a956ae68e7/href</a>

Another chore is to deal with paging. We added support for generic typing to deal with such problems. Instead of writing this:

<a href="https://medium.com/media/a8bb11ff27223d7ebf4d86e00eb656c4/href">https://medium.com/media/a8bb11ff27223d7ebf4d86e00eb656c4/href</a>

you can now write:

<a href="https://medium.com/media/8fda79e1c149826c03f6e7f6a1f3acac/href">https://medium.com/media/8fda79e1c149826c03f6e7f6a1f3acac/href</a>

To use this new schema, simply transpile the new schema using graphql-s2s:

<a href="https://medium.com/media/cd77c0ab624d30ab0fc359efc8da407e/href">https://medium.com/media/cd77c0ab624d30ab0fc359efc8da407e/href</a>

In the case of the generic types, graphql-s2s will create new type for each concrete generic types it finds (e.g. Paged<Product> will become PagedProduct). graphql-s2s also supports metadata (more details here) to define custom names on a generic type.

<a href="https://medium.com/media/47aef31f7664b643a0be4bbf4522d608/href">https://medium.com/media/47aef31f7664b643a0be4bbf4522d608/href</a>

The example above will convert the new concrete generic types as follow:

  • Paged<Product>: Products
  • Paged<Inventory>: Inventories
  • Paged<Business>: Businesses

Hope those tools will help you. Let us know what you think about those. Leave us comments here or on our github pages if you want more features or if you feel there could be improvements.

Cheers,

The Neap Team :)


Published by HackerNoon on 2017/08/07