Hands-on: How to design, launch, and query a GraphQL API using Apollo Server

In a data graph, a node is an entity (e.g., Person) and an edge is a relationship (e.g., likes).

Figure 1: In a data graph, an entity such as Person is called a node and the relationship between two nodes; for example, likes, is called an edge

Figure 2: The default relationship between nodes in a GraphQL API is, has

Figure 2: The default relationship between nodes in a GraphQL API is, has

Excerpt from typedefs.js describing demo app types in GraphQL Schema Definition Language (SDL).

Listing 1: A an excerpt from the file, typedefs.js that describes some of the demonstration application types declared in GraphQL Schema Definition Language (SDL)

Description of GraphQL interfaces, types, and inputTypes in UML (Unified Modeling Language).

Figure 3: A description of some of the GraphQL interfaces, types and inputTypes represented in UML (Unified Modeling Language)

Listing 2: The Query, Mutation and Subscription types are basic for any GraphQL Schema

Listing 2: The Query, Mutation and Subscription types are basic for any GraphQL Schema

The movies query in the demo app is backed by a corresponding resolver providing its logic.

Figure 4: The demonstration application's movies: [Movie] query is backed by logic provided by an analogous resolver with the same name

Figure 5: Subscribing to onMovieAdded events

Figure 5: Subscribing to onMovieAdded events

 Figure 6: The mutation, addMovie is declared to return the fields, id and title upon success.

Figure 6: The mutation, addMovie is declared to return the fields, id and title upon success.

Figure 7: UI displays API-emitted messages on movie additions post subscription to onMovieAdded

Figure 7: Once a user subscribes to onMovieAdded, the UI will display messages emitted by the API for the subscription when a movie is added to the system.

Figure 8: The onMoviedAdded and onMovieUpdated Subscriptions returns the custom defined Event object

Figure 8: The onMoviedAdded and onMovieUpdated Subscriptions returns the custom defined Event object

Apollo Server's GraphQL Playground uses GraphQL's introspection to automate online API documentation

Figure 9: Apollo Server's GraphQL Playground takes advantage of the introspection feature of GraphQL to automate online documentation for an API.

Custom Event object details data for onMovieAdded and onMovieUpdated Subscriptions listeners.

Figure 10: The custom Event object describes the data sent to listeners of the onMovieAdded and onMovieUpdated Subscriptions

The resolver addMovie adds movie information to the IMBOB data store and publishes information.

Listing 4: The resolver, addMovie adds movie information to the IMBOB data store and also publishes information.

The method publishMovieEvent sends messages to subscribers listening to movie-related subscription

Listing 5: The method, publishMovieEvent does the work of sending a message to subscribers listening to subscriptions related to movie activity

Listing 5: createEvent is a factory method that creates Event objects in a uniform manner.

Listing 5: createEvent is a factory method that creates Event objects in a uniform manner.

Figure 11: The security overview for IMBOB

Figure 11: The security overview for IMBOB

Figure 12: The context field makes request information available for inspection and processing.

Figure 12: The context field makes request information available for inspection and processing.

Authenticate to an API in GraphQL Playground by submitting authorization in the HTTP HEADERS pane.

Figure 13: To authenticate to an API in GraphQL Playground, submit the authorization information in the HTTP HEADERS pane

onConnect subscription field processes authentication info via connectionParams in Apollo Server.

Figure 14: The subscription field, onConnect allows you to inspect and process authentication information that Apollo Server will send to the onConnect handler, by way of parameter, connectionParams

Figure 15: Authenticate subscriptions in GraphQL Playground using the HTTP HEADERS pane.

Figure 15: You provide authentication information in the HTTP HEADERS pane in GraphQL Playground when you register a subscription

Listing 6: The code for submitting authentication information to a GraphQL Subscription Server

Listing 6: The code for submitting authentication information to a GraphQL Subscription Server

IMBOB defines the Input type, CursorPaginationInput, for efficient pagination with large datasets.

Figure 16: IMBOB defines the Input type, CursorPaginationInput to facilitate using pagination with a very large list of data.

Listing 8: Query using CursorPaginationInput for pagination, assigned to paginationSpec parameter.

Listing 8: A query that defined pagination information using the CursorPaginationInput type and assigns that information to the query parameter, paginationSpec.

Query 1

Query 1 Result 1

{
  persons(paginationSpec : {first : 3, sortFieldName : "lastName"}) {
    pageInfo{endCursor} collection { firstName lastName id }
  }
{
  "data" : {
    "persons" : {
      "pageInfo" : {"endCursor" : "7f1e7daf-376b-4a0d-937f-2d2d09c290f6"},
                   "collection" : [
                     {
                       "firstName" : "Ben",
                       "lastName" : "Affleck",
                       "id" : "b026dd59-98e1-46ac-9ade-5d8794265599"
                     },
                     {
                       "firstName" : "Casey",
                       "lastName" : "Affleck",
                       "id" : "68db2026-1d6c-4e27-abdb-43994d517513"
                     },
                     {
                       "firstName" : "Roslyn",
                       "lastName" : "Armstrong",
                       "id" : "7f1e7daf-376b-4a0d-937f-2d2d09c290f6"
                     }
                   ]
    }
  }
}

Query 2

Query 2 Result 2
{
  persons(paginationSpec
          : {
            after : "7f1e7daf-376b-4a0d-937f-2d2d09c290f6",
            first : 3,
            sortFieldName : "lastName"
          }) {
    pageInfo{endCursor} collection { firstName lastName id }
  }
{
  "data" : {
    "persons" : {
      "pageInfo" : {"endCursor" : "9eb66b6f-5871-4b53-8bcb-64e8ac7586b4"},
                   "collection" : [
                     {
                       "firstName" : "Hal",
                       "lastName" : "Ashby",
                       "id" : "b5f0b9da-8ed1-4743-920e-f85d78a62131"
                     },
                     {
                       "firstName" : "Anthony",
                       "lastName" : "Asquith",
                       "id" : "ad382532-4d32-4bbe-b3ea-69213be4703a"
                     },
                     {
                       "firstName" : "Brando",
                       "lastName" : "Bartell",
                       "id" : "9eb66b6f-5871-4b53-8bcb-64e8ac7586b4"
                     }
                   ]
    }
  }
}
Listing 12: JavaScript class RequiresPersonalScope enforces @requiresPersonalScope directive.

Listing 12: The Javascript class RequiresPersonalScope that enforces the rule for the directive @requiresPersonalScope

The IMBOB @requiresPersonalScope directive exposes sensitive info only to authorized users.

Figure 17: The IMBOB @requiresPersonalScope directive exposes sensitive information only to users who have the necessary permissions.

Figure 18: Users without the required permissions do not get to see sensitive information.

Figure 18: Users without the required permissions do not get to see sensitive information.

+

Esta página está disponible en español

Ver en español