What you'll learn
  • the two separate GraphQL APIs that are included by default in every Webiny project
  • how to use the GraphQLSchemaPlugin external link in order to extend an existing GraphQL API
Use the webiny watch command to continuously deploy application code changes into the cloud and instantly see them in action. For quick (manual) testing, you can use the built-in API Playground.

Introduction
anchor

When it comes to HTTP API development, Webiny relies on GraphQL external link. In fact, all of the applications that are part of the Webiny Serverless CMS, for example Page Builder external link or Headless CMS external link, are using it in order to enable developers programmatic interaction via a client of their choice, for example a browser.

By default, every Webiny project starts off with two separate GraphQL APIs.

Default GraphQL API
anchor

The default GraphQL API (or just GraphQL API) is the GraphQL API that’s located within the api/code/graphql external link folder. All of the Webiny Serverless CMS applications are built on top of it, and, in the same fashion, the API can be extended by developers, if need be.

The Extend GraphQL API and Extend Admin Area scaffolds, which can help you extend your GraphQL API in no time, use the same concepts and approaches that are explained in this guide.

Headless CMS GraphQL API
anchor

The Headless CMS GraphQL API is a special standalone GraphQL API that is introduced by the Headless CMS application. It’s located in the api/code/headlessCMS external link folder and, like the default GraphQL API, can also be extended by developers.

Learn more about the Headless CMS GraphQL API.

Extending GraphQL API
anchor

In general, when talking about extending an existing GraphQL API, we’re usually referring to one or more of the following:

For example, we might want to add a new, Page Builder-related, duplicatePage mutation, that would be responsible for making copies of provided pages. Or, we might just want to add an extra field to the PbPage external link GraphQL type, so that we can store some additional data for each page.

And although, depending on the application and the change we want to perform, some of the steps in the overall GraphQL extension process may differ, in all cases, we will want to start by registering a new GraphQLSchemaPlugin external link plugin.

The plugin is registered within your GraphQL API’s application code. For example, if we wanted to extend the default GraphQL API, we would create the plugin inside of the api/code/graphql/src/plugins external link folder, and register it in the api/code/graphql/src/index.ts external link entrypoint file. On the other hand, if we wanted to extend the Headless CMS GraphQL API, we would create the plugin inside of the api/code/headlessCMS/src/plugins external link folder, and register it in the api/code/headlessCMS/src/plugins/index.ts external link entrypoint file.

The GraphQLSchemaPlugin external link plugin is part of the @webiny/handler-graphql external link package, which can also be used to create new standalone GraphQL APIs.

The following is an example of a simple GraphQLSchemaPlugin external link plugin that extends the default GraphQL API with a new listBooks query.

api/code/graphql/src/plugins/books.ts
import { GraphQLSchemaPlugin } from "@webiny/handler-graphql/plugins";

// Make sure to import the `Context` interface and pass it to the `GraphQLSchemaPlugin`
// plugin. Apart from making your application code type-safe, it will also make the
// interaction with the `context` object significantly easier.
import { Context } from "~/types";

export default new GraphQLSchemaPlugin<Context>({
  // Extend the `Query` type with the `Book` type and `listBooks` query field,
  // which returns a list of all books previously saved in the database.
  typeDefs: /* GraphQL */ `
    type Book {
      title: String
      description: String
    }
    extend type Query {
      # Returns a list of all users
      listBooks: [Book]
    }
  `,
  // In order for the `listBooks` to work, we also need to create a resolver function.
  resolvers: {
    Query: {
      listBooks: async (_, args, context) => {
        // In a real life application, these would be loaded from the database.
        const books = [
          { title: "First book", description: "This is the first book." },
          { title: "Second book", description: "This is the second book." }
        ];

        // Finally, return the list of books using the `ListResponse` class instance.
        return books;
      }
    }
  }
});
Having the plugin external link registered within the default GraphQL API’s application code (in the mentioned api/code/graphql/src/index.ts external link entrypoint file), we should be able to see and execute the listBooks query, for example via the API Playground:
{
  listBooks {
    title
    description
  }
}

Executing the query should give us the following result:

Executing the new listBooks Query via API PlaygroundExecuting the new listBooks Query via API Playground
(click to enlarge)
To extend your default GraphQL API in no time, make sure to try the Extend Admin Area and Extend GraphQL API scaffolds.

Additional Related Examples
anchor

For more concrete examples, you can also visit the following guides which explain how to extend GraphQL types and operations that belong to different Webiny applications: