GraphQL — Schemas Inheritance & Generic Types

Nicolas Dao
Neap For Startups
Published in
4 min readMay 6, 2018

--

When your business domain is small, modeling it using a GraphQL schema is easy. However, as it grows bigger and more complex, out-of-the-box, there are not a lot of features to help you to organize and structure it. This post will show you how to address this short-coming using an open-source library that I built recently called graphql-s2s. This library will allow you to construct GraphQL schemas similar to this example:

This post is structured in two sections:

  1. Intro — Why GraphQL Is Replacing REST
  2. Main Content — Pushing The GraphQL Schema One Step Further

Quick Note: This post will not cover how to organize the files containing your GraphQL schema. If you’re interested in that topic, please refer to my post called GraphQL Schemas — Easier & Better Structure, where I explain how to use a library called SchemaGlue.js.

Why GraphQL Is Replacing REST

Since Facebook publicly released GraphQL in 2015, GraphQL has been establishing itself as the new standard for web APIs. It has solved many problems faced by REST APIs:

  1. Redundant endpoints (e.g., GET productLight, GET productFull, GET productSpecialClient) — REST exposes static resources. If you’re building an endpoint for all the product data, to power an admin panel, for example, that endpoint might be inefficient to expose frequently accessed data for a mobile app. That’s why you would have to create another product endpoint optimized for mobile data.
  2. APIs Spaghetti & Versioning Hassle — The size of your API can go out-of-control when your business domain is vast, or when it continually changes due to constant business changes (e.g., early-stage startup). This problem is amplified by the redundant endpoints issue mentioned previously.
  3. Chatty APIs — Your client might have to make too many HTTP calls to get the data your app needs. Because REST APIs are organized around domain model entities (e.g., one endpoint for the product and another for the user), your app will have to perform two separate requests if it needs to display both the product and the user information.

GraphQL solves the redundant endpoints issue by allowing the client to cherrypick any property rather than having to consume an entire resource. No need for a GET productLight endpoint and another GET productFull. Just expose a GraphQL product and let your client choose which field they need. This ability kills two birds with one stone as it allows to introduce new properties later if the domain evolves while the documentation can deprecate old properties. The older clients will still be able to use the deprecated fields, while the new ones will favor the new ones. This ability highly reduces the risk of creating APIs spaghetti and can delay your API versioning. Finally, GraphQL allows you to compose queries, which means you can request multiple entities in a single request. That means less chatty APIs.

All this goodness is mainly made possible by the GraphQL schema. The schema is similar to a SQL schema. It defines your business domain model as well as their relations to each other. The GraphQL Schema is extremely easy to build and understand, however, as it grows bigger and more complex, out-of-the-box, there are not a lot of features to help you to organize and structure it. The next section addresses this short-coming.

Pushing The GraphQL Schema One Step Further

Adding Inheritance

For the past couple of years, my team and I have created a lot of GraphQL APIs to power mobile apps and website in our lovely town of Sydney. During that journey, I realized that we were duplicating a lot of code. We created graphql-s2s to be able to rewrite schema from:

to:

graphql-s2s also supports multiple inheritance thanks to Pankaj Parkar. For more details about multiple inheritance, please refer to the documentation.

Adding Generic Typing

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

you can now write:

To see how you would resolve the Paged<Student>, please refer to the documentation on GitHub.

How The Hell Is It Possible?

graphql-s2s is just a transpiler. It stands for GraphQL Schema-to-Schema. There is no need to transpile using Babel or any other tool. Instead, write your schema as a string, or using separated .graphql files (more about this in GraphQL Schemas — Easier & Better Structure). Then use graphql-s2s in your code as follow:

When your server starts, it will transpile your graphql-s2s schema into a standard schema.

In the case of the generic types, graphql-s2s will create new types 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:

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

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

Coming Next…

Hope this tool will help you. If you want extra features or if you feel there could be improvements, please leave me a comment on GitHub.

Follow me on Medium — Nicolas Dao — If you’re interested in what’s coming next. These days, I’m writing a lot about Serverless and GraphQL:

GraphQL

Serverless

--

--

Focused on nurturing happiness in tech. and in life. Co-founder of Neap (https://neap.co), a Tech. Consultancy based in Sydney.