This video is available to students only

Using the GraphQL Schema Language

The GraphQL schema language is a human-readable syntax to help create GraphQL schemas. In this lesson, we'll use the GraphQL schema language to re-create the schema we have in a more readable and simpler format.

Using the GraphQL Schema Language

📝 This lesson's quiz can be found - here.
🗒️ Solutions for this lesson's quiz can be found - here.
📃 Grab a cheatsheet that summarizes creating a simple GraphQL API with the ApolloServer constructor - here.

The GraphQL schema language (sometimes known as the Schema Definition Language) uses a simple syntax to define and create a GraphQL schema and is language agnostic. Most graphql server libraries provide us with the capability of creating a schema with the GraphQL schema language. The GraphQL JavaScript library also allows us to create a schema with the GraphQL schema language, but we'll achieve this with the apollo-server-express package.

Apollo Server conventionally allows us to define a GraphQL schema by setting up two different values.

  • typeDefs - string that represents the GraphQL schema.
  • resolvers - map of functions that implement the schema.

We'll create these in separate files located within a src/graphql folder. We'll also create an index.ts file in the src/grapqhl folder to gather the typeDefs and resolvers map and export them explicitly from the graphql/ folder.

server/
  src/
    graphql/
      index.ts
      resolvers.ts
      typeDefs.ts
    // ...

typeDefs

Listing

We'll begin by creating our schema definition with the GraphQL schema language in the src/graphql/typeDefs.ts file. To do so, we'll import and use the gql template literal tag from apollo-server-express.

server/src/graphql/typeDefs.ts
import { gql } from "apollo-server-express";

The gql tag will allow us to write GraphQL in our code by having strings be parsed as a GraphQL Abstract Syntax Tree. Let's see this in action before we discuss how the gql tag works. We'll export and create a const variable named typeDefs that has the gql tag wrapped around a template literal string.

import { gql } from "apollo-server-express";

export const typeDefs = gql``;

We'll first define the Listing object type as we've done in the previous lesson but in this instance use the syntax of the GraphQL schema language. We can define a new object type by using the type keyword.

import { gql } from "apollo-server-express";

export const typeDefs = gql`
    type Listing {}
`;

We can declare the fields of our Listing object type and use the built-in scalar types to reference the types of each field - ID for the id type, String for the string types, and Int for the integer types.

import { gql } from "apollo-server-express";

export const typeDefs = gql`
  type Listing {
    id: ID
    title: String
    image: String
    address: String
    price: Int
    numOfGuests: Int
    numOfBeds: Int
    numOfBaths: Int
    rating: Float
  }
`;

Recall how we've wanted each of the fields within the Listing type to never be null? In the last lesson, we achieved this by wrapping the types with the GraphQLNonNull wrapper. With the GraphQL schema language, we can simply place an ! after a type definition to declare that the type should always be defined.

import { gql } from "apollo-server-express";

export const typeDefs = gql`
  type Listing {
    id: ID!
    title: String!
    image: String!
    address: String!
    price: Int!
    numOfGuests: Int!
    numOfBeds: Int!
    numOfBaths: Int!
    rating: Int!
  }
`;

Query

With our Listing type defined, we can go ahead and declare the shape of the root Query and Mutation types.

We intend on having a single listings field be in our Query object that's responsible in returning a list of Listing objects. With the GraphQL schema language, we can simply wrap the type with [] brackets to denote a GraphQL List.

import { gql } from "apollo-server-express";

export const typeDefs = gql`
  type Listing {
    id: ID!
    title: String!
    image: String!
    address: String!
    price: Int!
    numOfGuests: Int!
    numOfBeds: Int!
    numOfBaths: Int!
    rating: Int!
  }

  type Query {
    listings: [Listing]
  }
`;

For our listings query field, we want to ensure the value returned is not null and contains a list of not null values. We'll place the ! marks accordingly to denote this.

import { gql } from "apollo-server-express";

export const typeDefs = gql`
  type Listing {
    id: ID!
    title: String!
    image: String!
    address: String!
    price: Int!
    numOfGuests: Int!
    numOfBeds: Int!
    numOfBaths: Int!
    rating: Int!
  }

  type Query {
    listings: [Listing!]!
  }
`;

Mutation

Finally, we'll declare the shape of the Mutation object type that contains a deleteListing field that is to return a required Listing type.

import { gql } from "apollo-server-express";

export const typeDefs = gql`
  type Listing {
    id: ID!
    title: String!
    image: String!
    address: String!
    price: Int!
    numOfGuests: Int!
    numOfBeds: Int!
    numOfBaths: Int!
    rating: Int!
  }

  type Query {
    listings: [Listing!]!
  }

  type Mutation {
    deleteListing: Listing!
  }
`;

The deleteListing field is unique since it's the only field that accepts an argument. We'll specify the id argument it expects and declare that is of type ID!. Our typeDefs string in its complete state will look like the following:

server/src/graphql/typeDefs.ts
import { gql } from "apollo-server-express";
Please select a discussion on the left.