How to use Union Types in Queries In GraphQL
Step 1: Define the Schema
- To define the GraphQL schema, Create a file and save it with .graphql extension.
- For example we can name the file as schema.graphql.
Javascript
const typeDefs = ` type Book { title: String! isbn: String! } type Author { name: String! books: [Book!]! } union SearchResult = Book | Author type Query { search(query: String!): [SearchResult] } `; module.exports = { typeDefs, }; |
Step 2: Implement Resolvers
Let’s set up the server, save the file as server.js and we will implement resolvers. Resolver functions are responsible for resolving the queries that are defined in the schema. Here, we will create a “search” resolver that will be responsible for resolving the “search” query, and we will return a static data based on the provided query string. We will also create a “SearchResult” resolver that will determine the type of the search result, which will be either “Book” or “Author”.
Then, we will create an executable schema using the “makeExecutableSchema” function that will combine our schema and resolvers, and create an executable GraphQL schema.
At last, we will create and initialise our App using express, and start the app.
Javascript
const express = require( 'express' ); const { graphqlHTTP } = require( 'express-graphql' ); const { makeExecutableSchema } = require( 'graphql-tools' ); const { typeDefs } = require( './schema.graphql' ); // Define the resolver const resolvers = { Query: { search: (_, { query }) => { if (query.toLowerCase().includes( 'graphql' )) { return [ { __typename: 'Book' , title: 'GraphQL in Action' , isbn: '1234567890' }, { __typename: 'Author' , name: 'John Doe' , books: [] }, ]; } else { return []; } }, }, SearchResult: { __resolveType: (obj) => { if (obj.title && obj.isbn) { return 'Book' ; } else if (obj.name && obj.books) { return 'Author' ; } return null ; }, }, }; // Create the executable schema const schema = makeExecutableSchema({ typeDefs, resolvers }); // Create the express app const app = express(); // Enable CORS for all routes app.use((req, res, next) => { res.header( 'Access-Control-Allow-Origin' , '*' ); res.header( 'Access-Control-Allow-Headers' , 'Content-Type' ); res.header( 'Access-Control-Allow-Methods' , 'OPTIONS,POST' ); next(); }); // Set up the GraphQL endpoint app.use( '/graphql' , graphqlHTTP({ schema, graphiql: true , // Enable GraphiQL for testing in the browser }) ); // Start the server const PORT = process.env.PORT || 3000; app.listen(PORT, () => { console.log(`Server running on http: //localhost:${PORT}/graphql`); }); |
Step 3: Start the server
To start the server run the below command in the terminal.
node server.js
Output:
Server running on http://localhost:3000/graphql
Step 4: Test the Query in GraphiQL Interface
To test the query, execute the below query in the GraphiQL interface.
query {
search(query: "GraphQL") {
__typename
... on Book {
title
isbn
}
... on Author {
name
books {
title
isbn
}
}
}
}
In the above query, we first define a search query that takes in a parameter with value, “GraphQL”, and since it can return data with the type of either Book, or Author, so we define 2 cases, first if the type is Book, we select only the title and the isbn field from the response, and if the type is Author, we select only title and books of type title, and isbn.
Output:
The output of the above query will look like below
Union Types in GraphQL Schema
GraphQL is an open-source Query Language for APIs that allows us to query only the data we require, unlike the REST framework which returns the entire data as is configured in its API. With GraphQL, we can maintain a Schema that defines what data we can query from the server, and we can define a proper contractual schema like this between the client and the server. In this article, we will learn about the Union Types in GraphQL Schema, and implement our resolver for it in Node.JS.