Connecting a GraphQL backend
Use an existing GraphQL API as a data source for your project. The
@graphql directive connects your GraphQL API with other GraphQL APIs.
Connect to public APIs
This example connects to the public Rick and Morty GraphQL API using the
@graphql directive. To connect to the public API, complete the following tasks:
- Create the project structure .
Run the following commands to create a project called
rick-and-mortywith a single directory calledschemafor the types:mkdir -p rick-and-morty/schema cd rick-and-morty - Create an
index.graphqlfile.The
index.graphqlfile describes how to assemble the various type definition files into a complete GraphQL schema.touch index.graphqlThis example only has a single file for now called
characters.graphql:schema @sdl( files: [ "schema/characters.graphql" ] ) { query: Query } - Create a
characters.graphqlfile.Create a file called
characters.graphqlfor theCharacterobject:touch schema/characters.graphqlThe
Characterobject has three fields, as shown in Table 1:Table 1. Fields in the CharacterobjectField Type Description idID Identifier nameString Character's name imageString URL to a .jpegimage file of the charactertype Character { id: ID name: String image: String }To match the Rick and Morty API schema, return a
resultsarray containing theCharacterobjects; call the typeCharacters:type Characters { results: [Character] }The
Querytype has acharactersquery that returns theCharacters, as specified in the previous types. The@graphqldirective takes theendpointof the GraphQL API, which in this case ishttps://rickandmortyapi.com/graphql, with the URL enclosed in quotation marks:type Query { characters: Characters @graphql( endpoint: "https://rickandmortyapi.com/graphql" ) } - Run the
CHARACTERS_QUERYtest query.Run the following query called
CHARACTERS_QUERYto test the new endpoint. This query executes thecharactersquery and returns an array ofCharacterobjects with theirid,name, andimage:query CHARACTERS_QUERY { characters { results { id name image } } }The query returns a
dataobject containing theid,name, andimageof thecharacterscontained within aresultsarray.{ "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?
Complete the following steps to connect an authenticated API:
- Create a
config.yamlfile.Much like the
@restdirective, pass your query aconfigurationcontained in aconfig.yamlfile:touch config.yamlThe
config.yamlfile contains a token provided by Storyblok that requires the following values:- A
namecalledstoryblok_config. - A
tokenprovided by Storyblok. Replacexxxxin the example below with the actual token's value:
configurationset: - configuration: name: storyblok_config token: xxxx - A
- Create a
storyblok.graphqlfile.The
storyblok.graphqlfile has the content types and queries:touch schema/storyblok.graphqlDefine the following types:
- A
PostItemtype with anameof typeString - A
PostItemstype with an array nameditemscontainingPostItemobjects
type PostItem { name: String } type PostItems { items: [PostItem] }The
Querytype has apostItemsquery that returns thePostItemsas specified in previous types. The@graphqldirective takes:- The
endpointof the GraphQL API (https://gapi.storyblok.com/v1/api). - The
configurationnamedstoryblok_config. - The
headers, which is an array of objects each containing thenameandvalueof 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.graphqlto yourindex.graphqlfile inside thefilesarray:schema @sdl( files: [ "schema/characters.graphql" "schema/storyblok.graphql" ] ) { query: Query } - A
- Run
POSTS_QUERYTest Query.Run the following query called
POSTS_QUERYto test the new endpoint and execute thePostItemsquery:query POSTS_QUERY { PostItems { items { name } } }This returns a
dataobject containing thenameof thePostItemscontained within anitemsarray:{ "data": { "PostItems": { "items": [ { "name": "my-super-awesome-post" } ] } } }
If you want to follow along with your own example, you can see how to authenticate with the Storyblok GraphQL API at the Storyblok website.
What else can you do with the @graphql directive?
The @graphql directive provides a variety of extra functionality that was not
explored in this simple example. The following sections describe what else you can do with the
@graphql directive:
- Mutations
- So far you have only seen how to run queries. But you can also use the
@graphqldirective with mutations that changee the data in the backend data source.You can find examples for how to use mutations in the GraphQL mutations topic.
- 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 might connect to multiple APIs, which can result in name collisions
for the types and queries. For example, if you have multiple
charactersqueries, you might want the characters from the Rick and Morty API instead of the Star Wars API.In this example, add the prefix value
rick_to the types and queries. Instead ofCharacter, writerick_Character, and so on:type rick_Character { id: ID name: String image: String } type rick_Characters { results: [rick_Character] }Add a
prefixby including an object containing avaluewith that prefix:type Query { rick_characters: rick_Characters @graphql( endpoint: "https://rickandmortyapi.com/graphql" prefix: { value: "rick_", includeRootOperations: true } ) }