Early on in my journey with GraphQL I was faced with a number of options for implementation. Sure, the ideas behind GraphQL are simple enough, and the official webpage does a very good job of explaining them. However, the implementation was another matter, especially in the Javascript ecosystem. You can start with the basic Express implementation, or jump in to any number of tools like Apollo or Hasura.
The more I dug into it though, the more I wanted to find a modular, cohesive solution that would allow me to build things flexibly. Hasura is linked direct to a data source, so the 1-1 mapping looked like it would cause issues in the way I wanted to store data vs the way I wanted to present the data. Apollo on the other hand, allowed more flexibility in how I designed data transforms in the resolvers, and it seemed that the majority of blog posts and tutorials I came across were using it. But Apollo is heavier in file size and runtime overhead, and also tries to steer you toward a paid offering. So I kept looking.
And then I found The Guild.
Who is "The Guild?"
The Guild is a collective of open source developers that are working together to construct a unified, modular approach to GraphQL API development. On their "about us" page, they outline how they view open source and the work that they do, and their willingness to help and to grow the community.
As of the date of this post, their ecosystem lists 20 different projects under their care. And today, I would like to highlight just a few of them that I have found useful over the past year of exploration.
A quick disclaimer: I am not a member of The Guild, and as of the time of this article I have joined in on some discussion on one project, but that is it. My hope in the next few months is to jump in and help them with anything I can. Their offerings have been a huge help to me and I'm looking for ways to give back.
Let's look at some of their tools, shall we?
GraphQL Code Generator
This was one of the first tools I came across, because I was looking for a way to get Typescript typings for a GraphQL Schema. And this tool does this and much, much more.
The premise behind this one is simple: Feed a GraphQL schema into it, and it will spit out code that you can use in your codebase. And it does this very well. This is achieved through a plugin architecture that allows you to pick and choose what you need outputs for, and then configure them to further tailor the experience. They also maintain a plugin hub of the most common plugins used in the ecosystem, so solutions are easy to locate.
But what if your schema is distributed across several sources? You can still use it, and the generator can be configured to pick it up. Made a mistake in your schema definition? The generator validates the schema before generating the output. If something is wrong, it generates and error and in most cases, even points right to the error to help you fix it.
There is quite a bit more to it though. Starting with the Javascript and Typescript ecosystem, there is a massive list of configuration options you can use to do all manner of amazing things. You can include a type you already have in the generated output using Type Mapping. You can use the "Add" plugin to inject things like comments, imports, and es-lint modifiers right into your generated code. They even have a VSCode extension to run the generator when you save GraphQL files.
The plugin hub has plugins to help you generate code for all sorts of things, from backend stuff like Typescript types and MongoDB ORM schemas, to frontend stuff like integrations for React, Vue, Urql, and even Apollo.
Then, there are also generators for Java and C# classes from your schema, saving users of either language from the hassle of having to keep code aligned between codebases.
And if you can't find quite the right plugin for your needs, they also have documentation on how you can write your own.
GraphQL-Tools
The landing page for GraphQL-Tools calls this "A set of utilities for faster development of GraphQL Schemas". I think this is accurate, but also a bit incomplete. I think that they should also mention that the Tools offering is also the starting point that many of their other tools are built from.
GraphQL-Tools is actually many things that aid in development, but the overall idea is to get you from defining your schema to getting working, executable code as fast as possible. This isn't a full featured server. This is just the pieces that do the GraphQL work. What this gives you is an "Executable schema" that you can then build in to any data or HTTP pipeline to start using GraphQL.
There are a few niceties that the tools provide. The first that I really like is the ability to load schemas from a variety of sources and in a variety of formats. These can be local files, URLS, or even schema fragments plucked out of Javascript files.
The next one I really appreciate is the ability to automatically map scalar types that a data source provides, as long as they have the same name (key). They call this "default resolvers", and this feature saves a mountain of time and upkeep as you build out your resolver maps.
GraphQL-Tools gives you what you need to get the logic portion of a GraphQL endpoint up and running with minimal fuss. But what if you want to take advantage of a more modular architecture, especially as your application grows?
They have something for that also.
GraphQL-Modules
The idea is simple enough: What if you could build your schema and resolvers in small vertical "slices" that would allow you to isolate each piece? This is what you get with Modules. You also get a tool set for testing and mocking, allowing you to build out portions of the schema and related functionality in isolation, test it, and then merge it in with the greater whole.
The basics alone are enough of a reason to start using it, but it's also got support for middleware and Dependency Injection, allowing for multiple setups to test and deploy your endpoint. This means you can start off simple, and then grow into more complex patterns as needed, like utilizing dependency injection to decouple providers from the places they are used, and composing providers as needed to architect more complex operations. All while maintaining testability.
Modules has one more trick up it's sleeve though: It works with the Code Generator mentioned above.
In Modules, you can define your schema using tagged template literals, so your schema slices look like this:
const schema = gql`
type Query {
hello: string!
}
`;
You can set up the generator to use your modules source code as input files, and it will pull out the tagged template schemas, stitch them together into one overall schema, validate the overall schema, and then generate any outputs you need. In the case of Modules, there is a dedicated Generator plugin designed to output just the types you need for the module you are working on. These types can then be used for autocompletion and catching bugs during development time, right in the module they are needed.
So what do you do if you need other functionality in your GraphQL endpoint? You could build it all yourself. OR.... you could reach for a solution built for the job. And The Guild has that for you also.
Envelop
This one is really cool. Envelop is based on a community supported plugin architecture and allows you to compose elements together to get exactly the GraphQL execution layer that you need. What's more, many of the plugins available are maintained by the same teams that offer the tools to begin with, like Auth0, Sentry, and New Relic just to name a few.
What this means is that if you want to add something like auth, there is a plugin for that. (actually many!) If you want rate limiting, add the plugin and configure. You get the point.
Now here is where it gets really interesting. Do you want to add .... GraphQL-Modules, as I just described above? Surprise surprise, there is a plugin for that as well. Now you can write small modules for schema execution, compose them together using the plugin, compose the plugin with other plugins to extend functionality, and get one unified execution layer for GraphQL.
And to this point the whole setup is still framework agnostic, meaning no HTTP server, no preferred data sources, and no opinions on how to use those. We are still just building the execution layer for GraphQL, and you can use whatever server you like. (I like fastify ;), You can use whatever data provider you like including calls to other servers or a database. (or Prisma!) Envelop doesn't care. It just does it's job and makes it easy.
And remember, so far we're built on top of the last several tools mentioned, to make it easy to build, type check, and validate schemas and the execution layer. But maybe you just want a simple to use GraphQL server and don't want to worry about any of the config?
Wouldn't you know it, they have something for that as well.
Yoga
Yoga is where The Guild ties everything together into a simple to use, feature rich, and performant HTTP server. It is opinionated by design, and even then only far enough to get you going in the right direction. All the tools mentioned earlier still work with Yoga, including the full Envelop ecosystem. (Yoga is actually built on top of Envelop) This means that you can get a server going in no time at all. In fact, the quick start in the docs has a server running in 3 lines of code. Three!
Not that the simple server is doing very much. You still need to add your own functionality to it. But since it uses Envelop, this is very easy to do. Build schemas in module files, use the generator to output types, use the types to guide you in building resolver maps, plug the modules into the Envelop plugin, add the plugin to Yoga. A dash of auth, a bit of reporting and metrics, you're looking pretty good in just an afternoon!
What else does The Guild offer?
Well, to start, they have some other very handy things to help you build your GraphQL services. Here are a few examples:
- Instead of building the logic out for your own custom scalars, try out GraphQL-Scalars and work with ready made scalar types such as Date, Latitude and Longitude, and IPv4, just to name a few.
- Need to merge together data from a variety of sources into one common GraphQL endpoint? GraphQL-Mesh has you covered.
- Need some linting for your GraphQL files and schema objects? GraphQL-Eslint plugs right in to EsLint and gets you running.
Then, if you need some help, you can reach out to The Guild on chat and they will jump in and see how to get you taken care of. The people I have connected with have all been extremely kind, helpful, and genuine. And if you need even more help at an organizational level, you can hire them as consultants for training, engineering, mentorship, and code reviews.
Conclusion
The Guild has become my one stop shop for all things GraphQL, and with good reason. The projects they are offering are all precise in scope and work well. The ecosystem fits together nicely. The maintainers are all good people. But perhaps most of all, the options they make available give you a range of choices, from an easy to work with tool set in GraphQL-Tools to the full featured server experience in Yoga. If you are interested in getting started with GraphQL, or if you already have with another tool set, I encourage you to give The Guild a try. You might be surprised at how easy GraphQL can be.
Special thanks to the team at The Guild for allowing me to use their logo as the image in this post. They were very kind in allowing someone who is unaffiliated to use a trademark, and very welcoming when I asked. I strongly encourage everyone to check with the owner before using any image, trademark, or other intellectual property, and to respect their wishes and limitations on use.
Top comments (2)
I was planning to add New Relics to my project. I wonder if it is worth considering ‘Envelop’. Haven’t made up my mind yet about Auth0….
I would recommend you give Envelop a try regardless. I've been building a side project with it in a Sveltekit endpoint and it's been awesome, especially with the "useJit" plugin that converts queries to a function tree before execution. It's running really fast and I don't even have dataloader set up yet.