We recently announced our open GraphQL API, giving anyone full access to integrate with our platform. In two weeks, we went from an internal GraphQL API used by our dashboard to having a public version usable by everyone.
Opening up your API and enabling third-party developers to integrate with your systems is a powerful way to create business value. That’s why our current mission to make open GraphQL APIs ubiquitous, and our first step towards that was opening up our own GraphQL API to allow anyone to build an integration with our platform.
If you’re also curious about opening up your own GraphQL API, we’re running an invite-only pilot program where our GraphQL experts help you successfully open up your GraphQL API. In return, all we ask is that you share your experience with us. Apply today by telling us more about your use case!
Let’s dive into how we got the operational readiness and developer experience of our GraphQL API up to the task.
Getting Our GraphQL API Operationally Ready
Having people outside of our own company use our GraphQL API put additional operational constraints on the endpoint. To address these constraints, we used Pothos, Envelop, graphql-armor, and our own GraphQL Metrics to help us get our API open and operational very quickly.
To protect our open API from common abuse scenarios, we used the Pothos Complexity plugin to limit the maximum depth and cost of queries based on the number of nodes in the response. We also added graphql-armor to have basic limits for the maximum number of aliases, characters, directives and tokens in queries. This prevents most of the common GraphQL-specific abuse angles.
We selected the subset of our overall schema that we wanted to expose in the public schema and used the Pothos SubGraph plugin to explicitly mark those types and fields as such.
To ensure we don’t leak any sensitive implementation details, we added error masking via the Envelop error masking plugin. With that plugin, only explicitly marked errors are visible to users and any other thrown error or rejected promise is masked behind a generic error message.
To centralize our authorization checks across our external and internal API surface, we used Pothos’ Auth plugin to move checks spread across various resolvers into a central place.
To get full visibility into the use of the open API, we set up dedicated GraphQL Metrics on top of our DataDog setup to give us full insight into the traffic coming from external users.
To be able to take action if we get alerted of abusive behavior, we added a way to block API tokens and prevent the associated users from creating new API tokens.
Improving the Developer Experience
The second part we spent time on was making sure developers could actually use our new open GraphQL API:
We upgraded all Stellate services, including the one for our open API, to show GraphiQL v2 with its all-new design and schema explorer.
We established conventions for our GraphQL schema design to make sure it’s consistent and intuitive to use. We also updated some of the older types and fields to match our new conventions.
We turned all of our IDs into globally-unique IDs with Pothos’ Relay plugin to establish consistency across all the different types.
We created some basic documentation on how to use the new public API, particularly around how to authenticate and send queries to it.
While none of this would have strictly been necessary for an internal-only API, much of this actually makes for great general hygiene for any GraphQL API! Malicious actors could have already sent abusive requests or tried to leak sensitive implementation details in error messages to our dashboard API, and having a consistent schema and documentation on how to use it has already proven useful to our own engineering team.
If you’re also curious about opening up your own GraphQL API, we’re running an invite-only pilot program where our GraphQL experts help you successfully open up your GraphQL API. In return, all we ask is that you share your experience with us. Apply today by telling us more about your use case!