Connect a REST Service

Connect any REST API as data source for a GraphQL schema

The @rest directive is a custom StepZen directive for connecting to REST APIs. It can be applied to a GraphQL query so that the result of the query is populated with data coming from a REST API that returns a JSON result.

Configuration Properties

endpoint (required)

This determines the REST endpoint that will be used to populate the query result. Endpoint is a string value that can contain variables preceeded by a $ that will be replaced by StepZen. These variables can match query arguments or configuration variables of the same name. For example, $username in the endpoint string would be replaced by the value of a username query argument.

configuration (optional)

This tells StepZen which configuration to use for this endpoint. StepZen configurations are stored in a config.yaml file and are given a name. For example, a named configuration within config.yaml called github_config would be referenced by a configuration property of @rest as configuration: github_config. A configuration can contain things like API keys needed to connect to a REST API or other configuration values that may be needed to construct the endpoint URL.

resultroot (optional)

In cases where the data to populate the GraphQL type is not in the root object of the result from a REST API, you can utilize resultroot to specify the path StepZen should use as the root. Let's look at an example.

This is the structure of a response from the Contentful Delivery API:

{
  "fields": {
    "title": {
      "en-US": "Hello, World!"
    },
    "body": {
      "en-US": "Bacon is healthy!"
    }
  },
  "metadata": {
    ...
  },
  "sys": {
    ...
  }
}

In this example, fields contains all the data that we would use to populate a type representing this content object. Therefore, we would set the resultroot to "fields" as in the below example.

contentfulPost(id: ID!): Post
    @rest(
      endpoint: "https://cdn.contentful.com/spaces/$spaceid/entries/$id"
      resultroot: "fields"
      configuration: "contentful_config"
    )

It's important to note that the value of setters will be mapped from the resultroot, which, in this case, would make the data under metadata and sys inaccessible in this example.

In some cases, you'll want to set the resultroot inside of an array of items. In this example, Contentful is returning all entries and we again need to set the value of the root to fields inside the array of items.

{
  "sys": { "type": "Array" },
  "skip": 0,
  "limit": 100,
  "total": 1256,
  "items": [
    {
      "fields": {
        /* list of fields for this entry */
      }
    }
  ]
}

You can do this by adding an empty array notation in the resultroot as in the following example:

contentfulBlogs: [Blog]
    @rest(
      endpoint: "https://cdn.contentful.com/spaces/$spaceid/entries"
      resultroot: "items[].fields"
      configuration: "contentful_config"
    )

setters (optional)

Sometimes the name or structure of the content returned by a REST API doesn't exactly match the GraphQL type that the query will populate. In these cases, you can use setters to map the values returned by a REST API result to the appropriate fields within the returned GraphQL type.

setters takes an array of objects containing a path and a field. The path is the path to the value in the endpoint's JSON result. The field is the property in the GraphQL type returned by the query that the value of field should be set to.

To illustrate this concept, let's look at the following example JSON response:

{
    "id": 194541,
    "title": "The Title",
    "slug": "the-url-2kgk",
    "published_at": "2019-10-24T13:52:17Z",
    "user": {
      "name": "Brian Rinaldi",
      "username": "remotesynth",
    }
  }

If the corresponding Article GraphQL type has a field of published but not published_at, StepZen will not be able to automatically map the value returned by the REST API to the value in the GraphQL type. To resolve this, we'd add a setter with the following values:

{ field: "published", path: "published_at" }

Setters are also useful for mapping values in nested objects returned by a REST API. In the example above, we cannot automatically map the value of user.name to a field in the GraphQL type. We have two options, one is to create another type for User that has the corresponding fields and then use the resultroot property to user or to flatten the values and add them to the Article type using the following setters:

{ field: "author", path: "user.name" }
{ field: "username", path: "user.username" }

Here's an example of a @rest directive in a file called article.graphql:

type Article {
  id: ID!
  title: String!
  description: String
  cover_image: String
  username: String!
  github_username: String!
      type Query {
      myArticles(username: String!): [Article]
        @rest(
          endpoint: "https://dev.to/api/articles?username=$username"
          configuration: "dev_config"
          setters: [
            { field: "username", path: "user.username" }
            { field: "github_username", path: "user.github_username" }
          ]
        )
    }
}

Let's pull out the @rest directive to take a closer look:

@rest(
  endpoint: "https://dev.to/api/articles?username=$username"
  configuration: "dev_config"
  setters: [
    { field: "username", path: "user.username" }
    { field: "github_username", path: "user.github_username" }
  ]
)

endpoint, configuration, and setters are all parameters on the @rest directive. That is, they give StepZen the information it need to connect to the REST API.

  • endpoint sets the endpoint of the API
  • configuration references the configuration file by its name value
  • setters gives the names of the fields that will be used and their values from their paths

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.