The @graphql
directive connects your GraphQL API with other GraphQL APIs, including those in the StepZen GraphQL Studio.
The following sections describe how to connect to a GraphQL API:
- Connect to Public APIs
- Connect to Authenticated APIs
- What else can I do with the
@graphql
Directive?
Connect to Public APIs
Follow the steps below to connect to public APIs:
- Ensure you have a StepZen account.
In this example, see how to connect to the public Rick and Morty GraphQL API using the
@graphql
directive. Later you will see how to connect to an API that requires authorization. - Perform the steps in the following subsections:
Create the Project Structure
Execute the following commands to create a project called rick-and-morty
with a single directory called schema
for the types:
mkdir -p rick-and-morty/schema cd rick-and-morty
Create an index.graphql File
The index.graphql
file tells StepZen how to assemble the various type definition files into a complete GraphQL schema.
touch index.graphql
This example only has a single file for now called characters.graphql
:
schema @sdl( files: [ "schema/characters.graphql" ] ) { query: Query }
Create a characters.graphql File
Create a file called characters.graphql
for the Character
object:
touch schema/characters.graphql
The Character
object has three fields:
Field | Type | Description |
---|---|---|
id | ID | Identifier |
name | String | Character's name |
image | String | URL to a .jpeg image file of the character |
type Character { id: ID name: String image: String }
To match the Rick and Morty API schema, return a results
array containing the Character
objects and call the type Characters
:
type Characters { results: [Character] }
The Query
type has a characters
query that returns the Characters
, as specified in the previous types. The @graphql
directive takes the endpoint
of the GraphQL API, which in this case is https://rickandmortyapi.com/graphql
, with the URL placed in between quotation marks:
type Query { characters: Characters @graphql( endpoint: "https://rickandmortyapi.com/graphql" ) }
Run CHARACTERS_QUERY Test Query
Run the following query called CHARACTERS_QUERY
to test the new endpoint. This executes the characters
query and returns an array of Character
objects with their id
, name
, and image
:
query CHARACTERS_QUERY { characters { results { id name image } } }
This returns a data
object containing the id
, name
, and image
of the characters
contained within a results
array.
{ "data": { "characters": { "results": [ { "id": "1", "image": "https://rickandmortyapi.com/api/character/avatar/1.jpeg", "name": "Rick Sanchez" }, { "id": "2", "image": "https://rickandmortyapi.com/api/character/avatar/2.jpeg", "name": "Morty Smith" } ] } } }
Connect to Authenticated APIs
Now let's try a slightly more complex example. The Rick and Morty API is public, meaning that it does not require an API token to access. What if you wanted to use a headless CMS with the @graphql
directive?
If you want to follow along with your own example, you can see how to authenticate with the Storyblok GraphQL API at the following link.
Create a config.yaml file
Much like the @rest
directive, pass your query a configuration
contained in a config.yaml
file:
touch config.yaml
The config.yaml
file contains a token provided by Storyblok that requires the following:
- A
name
calledstoryblok_config
. - A
token
provided by Storyblok. Substitutexxxx
in the example below with the value:
configurationset: - configuration: name: storyblok_config token: xxxx
Create a storyblok.graphql file
The storyblok.graphql
file has the content types and queries:
touch schema/storyblok.graphql
Define the following:
- A
PostItem
type with aname
of typeString
. - A
PostItems
type with an array nameditems
containingPostItem
objects.
type PostItem { name: String } type PostItems { items: [PostItem] }
The Query
type has a postItems
query that returns the PostItems
as specified in previous types. The @graphql
directive takes:
- The
endpoint
of the GraphQL API (https://gapi.storyblok.com/v1/api
). - The
configuration
namedstoryblok_config
. - The
headers
, which is an array of objects each containing thename
andvalue
of a header:
type Query { postItems: PostItems @graphql( endpoint: "https://gapi.storyblok.com/v1/api" headers: [ { name:"Token" value:"$token" } ] configuration: "storyblok_config" ) }
Add schema/storyblok.graphql
to your index.graphql
file inside the files
array:
schema @sdl( files: [ "schema/characters.graphql" "schema/storyblok.graphql" ] ) { query: Query }
Run POSTS_QUERY Test Query
Run the following query called POSTS_QUERY
to test the new endpoint and execute the PostItems
query:
query POSTS_QUERY { PostItems { items { name } } }
This returns a data
object containing the name
of the PostItems
contained within an items
array:
{ "data": { "PostItems": { "items": [ { "name": "my-super-awesome-post" } ] } } }
What else can I do with the @graphql Directive?
The @graphql
directive provides a variety of extra functionality not explored in this simple example.
Mutations
So far you have only seen how to run queries. But you can also use the @graphql
directive with Mutations as well.
You can find examples for how to use Mutations in the GraphQL Mutation Basics section.
Fragments
Let's say you have a relatively complicated page in your app that looks at two characters side by side, along with their friends. For more complicated queries, GraphQL includes reusable units called fragments.
Fragments let you construct sets of fields to include in your queries. This is useful for queries where you need to repeat the fields. The GraphQL docs include the following example:
{ leftComparison: hero(episode: EMPIRE) { ...comparisonFields } rightComparison: hero(episode: JEDI) { ...comparisonFields } } fragment comparisonFields on Character { name appearsIn friends { name } }
This results in the following output:
{ "data": { "leftComparison": { "name": "Luke Skywalker", "appearsIn": [ "NEWHOPE", "EMPIRE", "JEDI" ], "friends": [ { "name": "Han Solo" }, { "name": "Leia Organa" }, { "name": "C-3PO" }, { "name": "R2-D2" } ] }, "rightComparison": { "name": "R2-D2", "appearsIn": [ "NEWHOPE", "EMPIRE", "JEDI" ], "friends": [ { "name": "Luke Skywalker" }, { "name": "Han Solo" }, { "name": "Leia Organa" } ] } } }
Prefixes
As your project grows, you may connect to multiple APIs which result in name collisions for the types and queries. For example, if you have multiple characters
queries, you may want the characters from the Rick and Morty API and not the Star Wars API.
In this example, append the prefix value rick_
to the types and queries. Instead of Character
, write rick_Character
, and so on:
type rick_Character { id: ID name: String image: String } type rick_Characters { results: [rick_Character] }
Append a prefix
by including an object containing a value
with that prefix:
type Query { rick_characters: rick_Characters @graphql( endpoint: "https://rickandmortyapi.com/graphql" prefix: { value: "rick_", includeRootOperations: true } ) }