Seven ways to improve your GraphQL API in less than an hour

MS
Mike Solomon

CEO

17th Aug 2020

At Meeshkan, we work with lots of teams building GraphQL APIs. In doing so, we've seen several techniques that have provided high value to teams with minimal effort. These are some amazing force multipliers, and we thought it'd be nice to collect them into one article that you can use as a checklist.

All of the techniques that make the cut below take less than an hour to implement. As we like to brag a bit (can you blame us?) our solution will be one of them, but there are many others that are equally deserving of your attention! They're all complementary, and we think you'll get a lot of milage out of them. Enjoy!

1. Enums and scalars#

GraphQL gives you the power to define custom enums, scalars and directives. These make validation easier for your entire team.

Compare the two ways of defining color below.

I've seen a lot of teams that use a String even though their business case would warant an enum, like the color example above. This leads to unnecessary validation burden. Let your GraphQL framework do the heavy lifting for you by using enums!

The same is true for scalars.

Even though graphql can't validate a Gmail_email out of the box, you can write one recipe for your entire codebase.

If you're already well into a GraphQL project, it may be impossible to modify your API, but if you're adding to it or starting a new project, building with an enum-first and scalar-first mindset saves tons of time down the line and takes minutes to set up.

2. Schema linting#

While GraphQL schemas are pretty open-ended, there are certain design choices that will leave your colleagues scratching their heads. For example:

Let's take a peek at tags. We are saying "You may get an array of tags, or you may get null, and inside the array, there will be some strings and some nulls." What?!? What we probably actually wanted was a list of strings that may be empty:

Just because you can use the type system a certain way in GraphQL doesn't mean you should. Usually, when types are used this way, it is not intentional - it just means someone didn't think it through. That's totally normal, but it leads to a lot of confusion in teams and is totally avoidable by using a GraphQL schema linter.

Here are a few linters and validators you can use in your GraphQL pipeline starting today. If you're developing in JavaScript, all it takes is adding a linting step to your package.json file and you get automatic linting with every build.

Also, have a look at GraphQL config for a nice way to set these things up to run automatically in your IDE so that you can reuse the same linting and validation config in a variety of setups.

3. Type-safe resolvers#

Resolvers in most GraphQL frameworks are born type-safe, meaning that it will give you an String if you need an String and otherwise will throw an error back to the client. But what about the return types? To make sure you're returning the correct types, you can auto-generate type-safe resolvers. You can then use these resolvers as a middle-layer between your business logic and your graphql framework.

They will make sure that, however messy the typing is inside your business logic, the value going to the resolver is type-safe at compile time. Most GraphQL frameworks will throw a runtime error as well if there is an issue with type safety, but that's exactly the type of breakage you want to avoid in production. Given how easy it is to generate type-safe resolvers from a schema (it literally takes seconds - try the site!), you can use this as an added validation layer in your code.

4. Meeshkan#

One of the most exciting advancements in software development is the use of AI to learn how software works and generate tests based on those learnings. At Meeshkan, we use NLP libraries like spacy to analyze terrabytes of log files data generated by GraphQL APIs. We then use QuickCheck to compose data-based predictions into rich test suites.

The Meeshkan dashboard

Signing up for Meeshkan takes minutes, and you'll see your first test report within hours of interacting with your server. We provide a generous free tier that makes use of our most popular data-driven algorithms, and our paid tier runs over 10,000 tests on each project every day for added security.

5. Build a contract#

As a backend GraphQL developer, when you launch an API and someone else uses it, a de facto contract emerges around yout API. While your GraphQL API can be used a lot of different ways, this contract represents how it is actually used by your users.

The good news is that this contract can be enforced automatically with a little bit of setup. Check out pact.io, which will figure out what this contract is and alert you when it is broken. It will even generate test cases to validate this contract when you build and deploy your code. Deploying a pact server in a local environment can be done in less than an hour, and you'll be amazed how powerful the idea is!

6. Property-based testing#

This section is not relevant to all GraphQL backend devs, but if you are considering opening up your GraphQL API to people outside your company or you want to invest in security-testing, read on!

If you share your GraphQL API with the world, the contract becomes a lot broader because it is defined as much by potential usage as by actual usage.

Before you advertise your GraphQL API for public use, you should write some integration tests. While we will cover integration testing GraphQL in a separate article, in this article, I'd like to mention one method related to integration testing called property-based testing.

Property-based tests use randomly-generated data to confirm that a set of properties hold for a given system under test. The good news is that, for a GraphQL API, a lot of the properties are pre-defined by virute of the schema and can be tested automatically using a framework like schemathesis.

For some more resources on property-based testing, you can check out these articles:

7. Generate a model#

One of the hardest bugs to catch in testing is the software equivalent of DC-offset. In signals like audio, DC-offset is when you have a little bit of direct current going into a system, which makes the receiver (ie microphone) more rigid so that it doesn't vibrate as freely. That results in a lower variation of amplitude, which results in poor signal (sound) quality.

In software, something like DC-offset occurs when a piece of software should return a range of values (ie robust search results) but in reality returns a subset of this range (ie the 3-4 top results) due to a malformed query. It is super hard to catch this type of bug, and it has the same effect as DC-offset on an album: underwhelming performance.

Software DC-offset has a particularly crippling effect on businesses because it is immediately felt by users and leads to churn. If you have a menu that accidentally only shows two options, followed by a color palette that accidentally only shows one color, followed by a list of your creations that does not paginate, your users will bounce.

Fixing DC-offset in software is one of the hardest problems in testing, but GraphQL makes it much easier to do this than before. Using the same methods as property-based testing, you can generate a mock GraphQL server. You can use this to compare how mock output data compares to real output data.

Projects like graphql-tools automatically generate mock servers from a schema in less than a minute. If you plot a histogram of features of responses, which can be done with tools like Jupyter and matplotlib, you'll notice when the histograms are radically different. Glancing over 2-3 of these charts once a week can help you nip software DC-offset in the proverbial bud!

Parting shot#

I hope that you get the chance to try out some of the tools and technologies linked in this article. Those who consume your GraphQL API will thank you for it, and you'll have a much more pleasurable experience developing it!

Newer postOlder post

Don’t miss the next post!

Absolutely no spam. Unsubscribe anytime.

Company

About usContactPricingT&C