Build a Production-ready GraphQL API Using StepZen’s Declarative Approach
The code you write to create the API is approximately the code you need to write to run, manage and maintain that API. — Why StepZen
Deploying a GraphQL API to production means taking careful consideration of how you handle certain aspects of your API: pagination, performance, and security. It also means having a plan for how you manage changes such as the inevitable additions and manipulations of your data sources.
With StepZen, the code that you write to create a GraphQL API amounts to the code you write to run and manage your API in production. Parallelism is built-in, pagination is configurable, and adding or changing backends, parameters, queries, and mutations is a matter of slipping in a custom directive. The endpoints are protected with an API key by default, and JWT-based protection is configurable. Schemas and resolvers are autogenerated for you, so you don’t have to write them. And as a result, StepZen provides built-in performance optimizations. Let’s take a deeper look at this schema-based approach to readying your API for production.
Speed Up Response Time
Swift response time is paramount for any production-ready API. In the internal processing of a GraphQL request, a single request can call multiple backends. StepZen’s service is aware of which of those backend requests can be made in parallel, and which are dependent on other requests. That means StepZen automatically parallelizes the execution of a query when possible, which speeds up response time.
Adding and Changing Backends
Before you deploy a GraphQL API to production, you want to connect your backends according to the demands of your data sources, but you also want to be able to change and add backends after you’ve deployed to production, in case the needs of your frontend change, or if you have a new CMS or database to integrate. To connect a new backend with StepZen you can run a single command from the StepZen CLI. For example, to add a REST backend, you’d run:
stepzen import curl "https://introspection.apis.stepzen.com/customers"
You can copy-paste this command and try it out on your machine, if you like! You'll need to be signed up for StepZen and have downloaded the CLI. This command introspects the REST endpoint and generates a schema for you. In the schema, you can see queries written in this manner:
type Query {
myQuery: RootEntry
@rest(
endpoint: "https://introspection.apis.stepzen.com/customers"
headers: [{ name: "Content-Type", value: "$Content-Type;" }]
configuration: "json_introspection_config"
)
}
As you can see, inside the introspected schema, a custom directive @rest
points StepZen at the REST endpoint, as well as setting the header and configuration details through the corresponding arguments. In this manner, StepZen connects to the REST endpoint, eliminating the task of writing resolvers.
To connect another data source, such as a SQL or NoSQL database, or even another GraphQL API, you’d use a stepzen import
command as well. As is the case with stepzen import curl
, StepZen introspects the database backends and autogenerates the schemas and resolvers for you. The schemas generated by these commands will include custom @dbquery
and @graphql
directives that connect to the backends from within the schema.
You can combine data from multiple endpoints with another of StepZen’s directives, @materializer
. Here’s an example of @materializer
in action:
type GetCustomer {
address: Address
email: String
id: Int
name: String
orders: [Order]
@materializer(
query: "getOrderListByCustomerId"
arguments: [{ name: "customerId", field: "id" }]
)
}
Here, @materializer
is feeding results from a query to a separate database into the GetCustomer
type. Again, no resolvers for you to write.
Configurable Pagination
Production-ready APIs include pagination where necessary. You can configure pagination on a REST API on your terms by adding a pagination
argument to a @rest
directive. The type
determines the type of pagination (page number, offset, or cursor) and the setters
value determine the total number of results/pages.
type Query {
getPaginatedCustomerList(first: Int!, after: Int!): CustomerConnection
@rest(
endpoint: "https://introspection.apis.stepzen.com/customers?limit=$first&offset=$after"
pagination: {
type: PAGE_NUMBER
setters: [{ field: "total", path: "total_pages" }]
}
)
}
Endpoint Protection
In other methods of deploying GraphQL APIs, you often have to bring in separate libraries like graphql-shield
to protect your API properly for production. With StepZen, the endpoints are protected with an API key by default. If you’d like to add JWT-based protection, you can add code like this to your configuration file.
deployment:
identity:
keys:
- algorithm: HS256
key: my-little-secret
[... other configuration]
- rootoperationtype: Query
privatefieldspredicate: "?jwt"
To learn how to add authorization as well, you can take a look at StepZen’s docs.
Wrap Up
StepZen’s declarative approach means that you don’t have to code the schemas or resolvers from scratch - StepZen introspects your data sources, generates the schema and resolvers for you, and provides a powerful set of custom directives (@rest, @dbquery, @graphql, etc.) that allow you to customize with just a few lines of code. Your GraphQL endpoint, running on StepZen, has built-in parallelism and other performance and reliability optimizations.
To get started quickly, visit the Getting Started and select the datasource to begin with. Consult StepZen docs for information about the CLI, customizing and enhancing your schemas, and more. And hop into the Discord Community to see what your peers are working on, share your projects, ask questions ... we’d love to see you there.