IMPORTANT: You need to do the steps in sequence in order for the state of the lesson's learning environment to be
consistent. Otherwise, you'll get behaviors that might be confusing.
Educational Objective
The purpose of the scenario is to present the demonstration GraphQL API, IMBOB and to show users how to perform the following queries and mutations against the IMBOB demonstration API.
Also the scenario shows you how to use GraphQL subscriptions and directives.
What To Expect
After taking this scenario you will be able to:
To install the IMBOB API in the Katacoda interactive learning environment
To access an instance of Apollo Server GraphQL Playground bound to the IMBOB API running in the Katacoda interactive learning environment
To use to the interactive schema documentation published GraphQL Playground
To learn about the details of the IMBOB API using GraphQL introspection
To create and implement queries and mutations in GraphQL Query Language against the IMBOB API
To register subscriptions to the IMBOB API and receive messages asynchronously upon execution of certain mutations
To apply a GraphQL directive to a mutation in executed against the IMBOB API
What You Need To Know Before You Start
In order to get full benenfit from taking this scenario it's use to have a working understanding
of the syntax of the GraphQL Query Language.
Also it's good to have an understanding of the basics GraphQL operations of query, mutation and
subscription.
Working with GraphQL and IMBOB
This scenario published as a custom built API, IMBOB. IMBOB is a GraphQL API built using Apollo
Server. IMBOB publishs data that presents some basic movie information. The API is scaled
back to show data for only a few movies.
The reason only a few movies are represented is to provide just enough related data to make
the underlying object graph understandable in terms of organization and assocation.
Please be advised that the IMBOB API does provide mutations that allow users to build out the underlying
object graph. However, if a mishap occurs, all that required to reset the scenario and IMBOB to its initial
state is to refresh this web page.
Source Code
The source code for the IMBOB demonstration GraphQL API used in this scenario can
be found on GitHub here .
Scenario Contents
Step 1 - Setting Up The GraphQL API to Run on Katacoda
Step 2 - Accessing and Authenticating to the API
Step 3 - Executing Sample GraphQL Queries
Step 4 - Registering a Subscription
Step 5 - Firing a Subscription Event using the Mutation, Ping
Step 6 - Working with onMovieAdded to Add Data and Generate Asynchronous Messages
Step 7 - Declaring a Restricted Field Using a Custom Directive
Step 8 - Working with Connections
Congratulations!
You've completed the scenario!
Scenario Rating
You've crossed the finish line!
In this scenario you learned:
How to setup the GraphQL API, IMBOB, to run under Katacoda
How to access and authenticate IMBOB using an authentication token
How to execute simple and paginated queries
How to register to a custom subscription running on IMBOB in order to receive messages
How to execute a mutation that emits a message to a subscription
How to execute mutations against a more complex subscription
How design time directives work
How to work with connections to get data related to an entity in IMBOB
Your environment is currently being packaged as a Docker container and the download will begin shortly. To run the image locally, once Docker has been installed, use the commands
If all is well you should see a response similar to the following
(id and createdAt values will differ by installation.):
{"data":{"ping":{"createdAt":"Sun May 12 2019 15:41:37 GMT+0000 (Coordinated Universal Time)",
"body":"This is a simple message body.",
"name":"PING",
"id":"ac4f1d95-88fc-4953-89b2-00b8096dec00"}}}
Understanding This Step
The purpose of this step was to get the IMBOB API server up and running so that we can experiment with
GraphQL queries, mutations and subscriptions.
In the next step we'll be working the GraphQL Playground web page that ships with Apollo server to do work.
Step 2 - Accessing and Authenticating to the API
This introductory video covers the tasks you'll perform in this step.
IMPORTANT: You need to do the steps in sequence in order for the state of the lesson's learning environment to be
consistent. Otherwise, you'll get behaviors that might be confusing.
In this step we're going to configure the GraphQL Playground with
the authentication password that IMBOB requires for access to the API.
Task 1: Go to the URL shown below to bring the GraphQL Playground up in your browser. Copy the URL in the address the browser's
address bar.
Task 2: Then, once in GraphQL Playground of IMBOB, add the following JSON
{"authorization":"ch3ddarch33s3"}
to the HTTP Headers section in the lower left of GraphQL Playground as shown the following figure:
This will authenticate your session the IMBOB API. Now you can do some work.
Let's move onto the next step where you'll learn how to execute simple and complex queries against the IMBOB API
using the GraphQL Query Language in GraphQL Playground.
Step 3 - Executing Sample GraphQL Queries
This introductory video covers the tasks you'll perform in this step.
IMPORTANT: You need to do the steps in sequence in order for the state of the lesson's learning environment to be
consistent. Otherwise, you'll get behaviors that might be confusing.
If you do not have the GraphQL Playground for the IMBOB API in a brower window, enter the following URL in
your browser's address bar.
The purpose of this step is to have you execute a simple query against the IMBOB API in GraphQL Playground. Also, you'll
execute a more complex query that uses pagination.
Executing a Simple Query
Let's do a simple query of the IMBOB API. In this task we're going to execute the query, movies to get a
list of all movies stored in the API.
One of the key benefits of GraphQL is that you can declare only the fields you want in the JSON that gets
returned from a particular query. In this case, we're going to declare the following fields for the query to return.
title
releaseDate
actors
directors
As you can see in the figure below, the fields, actors and directors represent arrays of actor andperson
objects respectively.
Thus, we need to define in the GraphQL query exactly the fields of interest in each array. For both actors and
directorswe're interested in firstName and lastName.
We define such as query the GraphQL Query Language like so:
{
movies {
title
releaseDate
actors{
firstName
lastName
}
directors{
firstName
lastName
}
}
}
Task 1: Copy the movies query shown above into GraphQL Playground to execute the query. (An example is shown in the
figure below.)
Executing a Query with Pagination
In the real world, most clients using GraphQL will be working with arrays of data that are very big.
The alternative is to get the information you need in chunks, from a particular starting point. This technique is called pagination.
Pagination is not built in not part of the specification. But, most APIs create implementations that their own pagination mechanisms.
The way IMBOB supports pagination is by way of a special object, CursorPaginationInput, which is the type associated'
with the query parameter, paginationSpec. The persons query shown below configures an implicit CursorPaginationInput object
to return the first 5 objects starting at the beginning of the server-sid list of person
objects, and sort according to lastName.
Task 2: Execute the query below by typing or copying it into the query panel of the GraphQL Playground instance you
have running in your browser.
{
persons(paginationSpec:{first:5,
sortFieldName:"lastName",
}){
pageInfo{
endCursor
hasNextPage
}
collection{
firstName
lastName
id
}
}
}
You should see the results like the following. Play attention to the field, pageInfo.
The field, pageInfo shown in the return value above reports the current state of your pagination activity. Effectively
what pageInfo is reporting is endCursor, which is the id of the last person in the returned list. Also, pageInfo
reports that there are more items to be retrieved, ("hasNextPage": true).
Thus, we use this information to configure the paginationSpec: CursorPaginationInput parameter when we re-query
persons for more data. Notice that we set the value of after to ad382532-4d32-4bbe-b3ea-69213be4703a. Effectively
we're telling IMBOB to get the first 5 persons in the last starting after the person with the idad382532-4d32-4bbe-b3ea-69213be4703a
Task 3: Execute the query persons again according the new pagination information by entering or copying the following
GraphQL query into the query panel of GraphQL Playground.
You should get results as shwon below. Notice that this new query returns values starting with the last name of B,
while the previous query returned last name values starting with A. This is pagination in action.
Please be advised that the CursorPaginationInput the define pagination input andPageInfo that define the pagination
state of the current query session are special to IMBOB. Different APIs will have pagination structures that meet their
special requirements.
Now what we have a basic idea how to use the GraphQL Query language, let's move onto the next step where you'll learn
how to register to a GraphQL subscription on IMBOB to create a
websocket connection and then receive messages
asynchronously when a query or mutation associated with a particular subscription is executed.
Step 4 - Registering a Subscription
This introductory video covers the tasks you'll perform in this step.
IMPORTANT: You need to do the steps in sequence in order for the state of the lesson's learning environment to be
consistent. Otherwise, you'll get behaviors that might be confusing.
The purpose of this step is to show you how to register to a GraphQL Subscription that's published by the
IMBOB API. Subscriptions are a special feature of the GraphQL specification. Subscriptions make it so that a user
of an API can “subscribe” to a specific event published by a GraphQL API. Then, once the user’s subscription is
registered with the API, the user will receive messages when that event is fired by a particular action,
usually when a query or mutation is executed upon the API.
Task 1: Go the your browser window that has the GraphQL Playground page we called in earlier steps. Create new tab by
clicking on New Tab and the end of line of tabs in the GraphQL Playground window.
Task 2: Then add the security authorization token by copy and pasting
{"authorization": "ch3ddarch33s3"}
to the HTTP HEADERS section in the lower left of the GraphQL Playground.
Now we're going to register to the onEventAdded subscription as shown in the figure below:
Task 3 : We'll register the event, eventAdded by copying the following
GraphQL subscription declaration into the new tab pane and then click the execute arrow in the GraphQL
Playground UI.
subscription onEventAdded{
onEventAdded{
id
name
body
createdAt
storedAt
}
}
Now that we have the subscription registered, let's move onto the next step where we'll execute a mutation that
fires off a message to that subscription.
Step 5 - Firing a Subscription Event using the Mutation, Ping
This introductory video covers the tasks you'll perform in this step.
IMPORTANT: You need to do the steps in sequence in order for the state of the lesson's learning environment to be
consistent. Otherwise, you'll get behaviors that might be confusing.
Task 1: Open another new tab in GraphQL Playground.
Task 2: Add the security access token by copy and pasting
{"authorization": "ch3ddarch33s3"}
We're going to execute a GraphQL mutation in this pane
that will fire the event, onEventAdded on the server side. This event will be published by the
onEventAdded subscription we registered to in the last step, Step 4.
Task 3: Copy the following GraphQL mutation declaration into the new tab pane and then click the
execute arrow in the GraphQL Playground UI.
mutation{
ping(messageBody: "This is a simple message body."){
createdAt
body
name
id
}
}
You have now executed the mutation, ping. Also, ping is programmed on the server-sice to fire an message to the
onEventAdded subscription.
Task 4: Go back to the onEventAdded tab in the GraphQL Playground UI. You will see in the tab a new
message from IMBOB that relates to them mutation ping.
Step 6 - Working with onMovieAdded to Add Data and Generate Asynchronous Messages
This introductory video covers the tasks you'll perform in this step.
IMPORTANT: You need to do the steps in sequence in order for the state of the lesson's learning environment to be
consistent. Otherwise, you'll get behaviors that might be confusing.
Task 1: Open another new tab in GraphQL Playground.
Task 2: Add the security access token by copy and pasting
{"authorization": "ch3ddarch33s3"}
In this tab well register a new subscription to the API, onMovieAdded.
Add a the subscription onMovieAdded
Task 3: Subscribe to the event, onMovieAdded by copying and pasting the following into the new tab you just created on GraphQL Playground.
subscription onMovieAdded {
onMovieAdded(channelName: MOVIE_CHANNEL) {
id
name
createdAt
storedAt
body
}
}
Adding some movies
Task 4: Open yet another new tab in GraphQL Playground. (I know, this is getting redundant.)
Task 5: Add the security access token by copy and pasting
{"authorization": "ch3ddarch33s3"}
Task 6: Copy the following mutation into the tab you just created in GraphQL Playground:
mutation {
addMovie(movie: {
title: "2001: A Space Odyssey",
releaseDate: "1968-05-12"}) {
id
title
}
}
Task 7: and execute it by clicking the circled arrow in GraphQL Playground
Let's add another movie.
Task 8: Copy the following mutation into the current tab:
mutation {
addMovie(movie: {
title: "Yellow Submarine",
releaseDate: "1968-11-13"}) {
id
title
}
}
Task 9: Now go back to the tab in which you registered the subscription, onMovieAdded. You should see messaging activity.
Task 10: Then, come back and copy this query into the browser window to see the movie list:
{
movies {
title
releaseDate
actors{
firstName
lastName
}
directors{
firstName
lastName
}
}
}
Step 7 - Declaring a Restricted Field Using a Custom Directive
This introductory video covers the tasks you'll perform in this step.
IMPORTANT: You need to do the steps in sequence in order for the state of the lesson's learning environment to be
consistent. Otherwise, you'll get behaviors that might be confusing.
CONTENT TO BE PROVIDED
In this step we're going to examine how to use a custom GraphQL directive, @requiresPersonalScope.
You can think of a directive as way by which a developer can go into existing GraphQL
type definition source code and “mark” it so that a rule is applied to a type or
one of its fields. Of course, a developer must be actually program behavior for the
defined directive somewhere in the API code.
In this case, the developer applied the directive, @requiresPersonalScope to the email field in the
Person type as shown below:
type Person implements Personable{
id: ID
firstName: String
lastName: String
dob: Date
email: String @requiresPersonalScope
}
Applying the directive makes it so that only users who have permission to view person information
can view email addresses. Otherwise, an error message indicating that user does not have permission to the view
the field information will be displayed.
NOTE: Be advised that the code for the rule logic for the directive, can be found in the custom module, directives.js that can
be found here in the GitHub repository for the
demonstration application IMBOB.
First, let take a look at what happens when a user who does NOT have permission to view personal information runs a
query that includes an email field.
Task 1: In a separate browser window, go to GraphQL Playground as this URL:
You should see a result in which the email field is looks like the following:
"email": "You are not authorized to view personal information"
Task 5: Now, let's change the user to one who has permission to read personal information. Change the
authentication header in the HTTP Headers pane to have the following user token.
{"authorization":"s!ssch33s3"}
The user associated with token, s!ssch33s3 does indeed have permission to access personal information.
(Please be advised the the logic behind permissions assignment by token is part of the
internals of the IMBOB demonstration project.
GraphQL security is a more complex topic than what is presented here. The authentication method used is rudimentary and meant for
demonstration purposes only. Authentication in real-world applications is much more involved.)
Task 6: Run the query again. Now you should see the email address in the person query.
Now that we've covered directives, let's move onto the way IMBOB implements connections. Connection are a convention that's
evolved with in the GraphQL community as a way to describe relationships between objects within a GraphQL API.
Step 8 - Working with Connections
This introductory video covers the tasks you'll perform in this step.
IMPORTANT: You need to do the steps in sequence in order for the state of the lesson's learning environment to be
consistent. Otherwise, you'll get behaviors that might be confusing.
Understanding Nodes and Edges
A graph (also known as an object graph or data graph) is
the foundation on which data is organized and represented in GraphQL.
The concept behind a graph is that data exists as distinct entities within a domain, with an entity being
structured according to properties (aka, attributes or fields). In addition, an entity can have none, one or
many relationships to another entity. For example one entity can "know" another entity.
In discrete mathematics, the discipline that gave birth to the concept of
the graph, we call an entity, a node. A relationship between two nodes is called an edge.
IMBOB captures a number of edges that can exist between nodes. For example, one node (aka entity) can have both "knows" and "likes" edges with another node.
Yet, another node might have only a "knows" edge with the same node.
Understanding Connections in GraphQL
Many GraphQL APIs refer to an edge as a connection. Describing an edge as a connection is a convention that's evolved
among the GraphQL community. For example, IMBOB describes a likes relationship as a likesConnection.
The important thing to understand about connections in IMBOB is that data that's returned is an array of PersonConnection
objects. PersonConnectionis made up of two fields, pageInfo and edges
WHERE
pageInfo contains information required for queries to support pagination
edges contains an array of PersonEdge objects. PersonEdge publishes two fields, the cursor that identifies
the given PersonEdge object in and entire list of PersonEdge objects and the Person object which contains the actual
data about th person.
The reason a PersonEdge object is used is because a likeConnection might container hundreds, if not thousands
of edges. Thus, we need to have the likesConnection query support pagination. In order to support pagination
the query needs the cursor information provide by PersonEdge.
The exercise that follows demonstrates how to query IMBOB to get the likesConnection of a particular person, in this case
Nicholas Roeg.
Using Connections
Let's do a search of Persons, looking for NicholasRoeg using the query, searchPerson.
Now, let do the search in a new tab in the GraphQL Playground web page.
Task 2: Open a new tab in GraphQL Playground.
Task 3: Once in GraphQL Playground of IMBOB, add the following authorization JSON to the HTTP Headers
pane on the lower left of the Web Page, as shown in the illustration below.
You can copy the Authorization JSON by clicking on the copy icon and then pasting it into the UI directly. {"authorization":"ch3ddarch33s3"}
Task 4: Copy the following query into the query panel as shown in the illustration below:
Katacoda offerings an Interactive Learning Environment for Developers. This course uses a command line and a pre-configured sandboxed environment for you to use. Below are useful commands when working with the environment.
cd <directory>
Change directory
ls
List directory
echo 'contents' > <file>
Write contents to a file
cat <file>
Output contents of file
Vim
In the case of certain exercises you will be required to edit files or text. The best approach is with Vim. Vim has two different modes, one for entering commands (Command Mode) and the other for entering text (Insert Mode). You need to switch between these two modes based on what you want to do. The basic commands are:
i
In Command Mode
Change into Insert Mode, you can now insert and edit text in the file
esc
In Insert Mode
Change into Command Mode, you can now execute commands
:wq
In Command Mode
Save and Exit
You’ll love Katacoda
Guided Path
Knowing what you need to know is the hardest part. Our guided pathways help build your knowledge around real-world scenarios.
Learn By Doing
The best way to learn its by doing. All our tutorials are interactive with pre-configured live environments ready for you to use.
Stay up-to-date
It's a competitive industry. Your skills need to keep up with the latest approaches. Katacoda keeps your skills up-to-date.
You’ll love Katacoda
Guided Path
Knowing what you need to know is the hardest part. Our guided pathways help build your knowledge around real-world scenarios.
Learn By Doing
The best way to learn its by doing. All our tutorials are interactive with pre-configured live environments ready for you to use.
Stay up-to-date
It's a competitive industry. Your skills need to keep up with the latest approaches. Katacoda keeps your skills up-to-date.
😺
Have some feedback for us? Please tell us what's happening so we can improve Katacoda.