StepZen Instant-on Subgraph Support for Apollo Federation
Using REST APIs directly from your web, mobile, and wearable apps often results in poor performance. However, for app developers, a larger problem exists: finding the right REST APIs, manually stitching them together in each app, and managing new REST API versions that often include breaking changes. The careful rollout and coordination required to avoid breaking REST API changes can be a huge time sink for all teams – time that is not spent delivering new app experiences.
GraphQL is a layer on top of your existing microservices and REST APIs that makes it easy for app developers to find the data they need and craft a single fast GraphQL query. GraphQL provides a facade that decouples frontend and backend teams so underlying REST APIs can be refactored more easily.
A GraphQL query can retrieve the exact data needed to power a new app experience, like listing all the products a customer has bought and the date they bought them:
{
customer (email: “john.doe@example.com”) {
name
purchased {
orderedOn
name
}
}
}
The above fetches customer and order data from a single GraphQL server that retrieves JSON results from each underlying REST API (with both customer data and order data), merges them into a new JSON object that is transformed into the demand-oriented shape of the client query and returns a single result to the client. This presents a unified GraphQL API with an integrated schema that app developers can browse and query.
However, running everything through a single GraphQL server creates a bottleneck for teams that need to collaborate on a single codebase, slowing the growth of your graph.
Apollo Federation
A modular API layer allows each team to independently own their slice of the graph and release on their own schedules. Backend teams can refactor REST APIs behind the GraphQL facade and rely on observed GraphQL usage (like in Apollo Studio) to understand which fields are used, by which clients, and how much traffic each field receives per day. Schema changes can then be validated against actual usage to identify and assess the impact of a potentially breaking change – as part of your graph CI/CD workflow.
A supergraph is composed of smaller graphs called subgraphs and benefits both frontend and backend teams. It’s a unified API layer built with Apollo Federation, which is a declarative and modular GraphQL architecture. Teams can evolve their subgraphs independently, and their changes will be automatically rolled into the overall supergraph, allowing them to deliver autonomously and incrementally.
The Apollo Router is a supergraph runtime that dynamically plans queries and optimally fetches data from the subgraphs. This is similar to how a database query planner optimally plans SQL queries across multiple database tables. However, unlike a database join, a federated graph can do API-side joins of entities that span subgraphs all while presenting a single unified API that apps developers can use to build and power new experiences.
However, hand-crafting a GraphQL server to implement each subgraph whose resolver functions talk to the underlying REST APIs can be time-consuming and error-prone.
Building subgraphs quickly and efficiently with StepZen
Whether you want to build new subgraphs quickly or proxy existing subgraphs that you do not want to modify, StepZen can significantly accelerate your development and deliver subgraphs ready for the Apollo Federation layer.
StepZen can introspect the backend service (REST, SOAP/XML, database, or GraphQL), or you can write your SDL and attach
@rest
, @dbquery
or @graphql
directives to it. Either way, you get a compact intuitive code that represents the
GraphQL-ization of a backend or domain.
-
Autogenerate your schemas and resolvers: Specify an existing data source (REST, SOAP, Database or GraphQL) using the
stepzen import
command. StepZen introspects the backend and generates the GraphQL schema (SDL) for you.-- REST Endpoints:
stepzen import curl https://... -H "..."
-- Databases:
stepzen import [mysql | postgresql |...]
-- GraphQL Endpoints:
stepzen import graphql
-
Write your SDL: Attach
@rest
,@dbquery
and@graphql
directives to your SDL.
Assembling subgraphs
To explore how to create subgraphs and enable them for Apollo Federation, let's take a Customer subgraph and an Orders subgraph:
Customers subgraph (equivalently produced by stepzen import curl https://api.acme.com/customers
)
type User {
id: ID
name: String
email: String
}
type Query {
userByEmail (email: String): User
@rest (endpoint: “https://api.acme.com/customers?email=$email”)
userById (id: ID): User
@rest (endpoint: “https://api.acme.com/customers/$id”)
}
Orders subgraph (equivalently produced by stepzen import postgresql
)
type Order {
id: ID
createdOn: Date
carrier: String
trackingId: String
}
type Query {
orders (customerId: ID): [Order]
@dbquery (type: “postgresql”, table: “orders”)
}
As you can see, StepZen’s directives take away much of the heavy lifting for you; the entirety of the code above represents two GraphQL APIs.
Extending subgraphs with the @key
directive
StepZen’s non-root resolvers use a directive @materializer
. To see how it works, let us extend these two subgraphs with the @key
directive that Apollo Federation requires. The code will look like this:
Customers subgraph
type User @key (fields: “id”){
id: ID
name: String
email: String
}
type Query {
userByEmail (email: String): User
@rest (endpoint: “https://api.acme.com/customers?email=$email”)
userById (id: ID): User
@rest (endpoint: “https://api.acme.com/customers/$id”)
}
Orders subgraph
type User @key (fields: “id”) {
id: ID
orders: [Order]
@materializer (query: “orders”,
arguments: [{name: “customerId”, field: “id”}])
}
type Order {
id: ID
createdOn: Date
carrier: String
trackingId: String
}
type Query {
orders (customerId: ID): [Order]
@dbquery (type: “postgresql”, table: “orders”)
}
The Customers subgraph is self-explanatory. The Orders subgraph shows that to populate User.orders, issue the query “orders” and pass in User.id
as the argument customerId
for that query. That’s it. (You can attach a series of transformations if needed, but that is outside the scope of this blog.)
Non-root resolvers are created by @materializer
— it connects the data in the enclosing type (its scalar fields are always produced first in the execution step) with a query/mutation, which in turn returns the data of the type of that field being resolved.
You can run these subgraphs in the StepZen cloud, or (soon) you can host these subgraphs deployed in StepZen containers yourself. Either way, you get high performance because the REST, database, and GraphQL calls are all optimized for efficiencies — with inbuilt caching, pushdowns, and scaling.
Summary
Producing Apollo compatible subgraphs in StepZen is quick and easy:
-
Either run the
stepzen import [curl | database | graphql]
command to get a subgraph against a backend, or write your own subgraph using@rest
,@dbquery
or@graphql
. A few lines of code is all that is needed. -
Add
@key
notations and@materializer
at the right place, and these subgraphs are now Apollo Federation ready. A few lines of code is all that is needed. -
Deploy your graph to StepZen cloud or (soon) run it on your own — you get a scaled, performant subgraph.
While Apollo leaves how you build your subgraphs up to you, there are obvious advantages of doing it using StepZen:
-
Speed of development. A few lines of code get you a subgraph against any backend.
-
Optimized backend access. Many StepZen engineers have built database query optimizations in the past and have brought those techniques to the world of GraphQL.
-
No code change required to enable Apollo Federation. Sometimes the GraphQL backend that you want to federate over is from a software provider that you do not have control over, or sometimes your teams might build their subgraphs using libraries that have no support for Apollo Federation. Either way, a simple
stepzen import graphql
allows you to create a proxy layer in StepZen that then easily enables your backend for Apollo Federation!
So whether you want to build new subgraphs quickly, or proxy existing subgraphs that you do not want to modify, StepZen can significantly accelerate your development and connect many more well-designed subgraphs to the Apollo Federation layer.
Where to go from here
Go to Get started with StepZen and Apollo and to get hands-on right away, follow the instructions in the stepzen-dev/examples repo to create two subgraphs in StepZen and federate them in Apollo.
There are many more Apollo Federation capabilities (@external
, @requires,
etc.) that are easily enabled in StepZen. No libraries to import, no code to write–it is all taken care of for you.
The StepZen product is built by the folks who built Apigee. With the explosion in microservices and SaaS services, we realized that quickly GraphQL-izing these microservices was key to building out an enterprise-wide graph. We also realized that a declarative way of building these subgraphs was both a faster (with cleaner code) and better (from a run-time execution) perspective.
If you've got questions, want to brainstorm a project, or see what people are building with StepZen, we'd love to see you over on our Community Discord. Or grab some time via our Calendly for a short demo.