Design a Schema with Interfaces

Connect to multiple backends from a single GraphQL type

In the majority of cases, you don't need to use interfaces in order to build a schema using StepZen. However, interfaces are needed in cases where you want to define more than one backend against the same type.

We've covered how to connect a single backend such as a REST API or a MySQL database, but one of the powerful things that StepZen allows is for you to connect multiple backends to a single type. Imagine a shipping scenario where you have multiple shipping providers. StepZen would allow you to access shipping data via a single type that connects to all the backends for your various shipping providers.

If you want to connect multiple backends with a single type, you'll need to define interfaces. In that case, we recommend the following four-step iterative process:

  1. Create an interface and queries for a type that a front-end application will query. This could be a customer type, an order type, a ticket, whatever.

  2. Create one or more concrete types in support of the interface type you created. These are the types that implement the interface and they represent the backends that provide data to the interface. You can use StepZen's custom directives like @rest and @dbquery to specify to StepZen how to access and process the backends.

If you want to run your endpoint live as you iterate it, you can do so by running stepzen start on the StepZen CLI.

Create an Interface

Let's use an example to illustrate how to write the .graphql files you'll need in order for your type to connect with multiple backend data sources. This example will create a Delivery type that connects to both FedEx and UPS backends.

For each type we want to expose, we need to create an interface. For each backend we want to connect, we need to create a type that implements the interface.

Let's create the Delivery interface:

interface Delivery {
  carrier: String!
  status: String
  statusDate: Date
  trackingId: String!
}
type Query {
  delivery(trackingId: String!, carrier: String!): Delivery
}

Create Concrete Types that Implements the Interface

The concrete types needs to implement all of the required properties defined by the interface (we need to include them here as well for this to be valid GraphQL).

type FedEx implements Delivery {
  carrier: String!
  status: String
  statusDate: Date
  trackingId: String!
}
type UPS implements Delivery {
  carrier: String!
  status: String
  statusDate: Date
  trackingId: String!
}
type Query {
  fedexDelivery(trackingId: String!, carrier: String!): FedEx
    @supplies(query: "delivery")
    @connector(type: "FedEx", configuration: "fedex_default")
  upsDelivery(trackingId: String!, carrier: String!): UPS
    @supplies(query: "delivery")
    @connector(type: "UPS", configuration: "ups_default")
}

Let's explore what's in this code:

  • FedEx and UPS are concrete types that implement the interface Delivery.
  • @connector is a StepZen custom directive for utilizing some of StepZen's prebuilt connectors for common backends.
  • @supplies- tells StepZen the name of the query on the interface that this query will populate. In this case, both fedexDelivery and upsDelivery populate the delivery query on interface Delivery. The @supplies directive connects a backend query to an interface query. In other words, the result of invoking the interface query delivery is the result of executing fedexDelivery and upsDelivery with the same arguments.

This site uses cookies: By using this website, you consent to our use of cookies in accordance with our Website Terms of Use and Cookie Policy.