Jon G Lind
ServiceNow Employee
ServiceNow Employee

The Practical Guide to What is GraphQL and How to Create APIs within ServiceNow and test them.

 

Who is this for?

This Tutorial is for someone who (like myself a few weeks ago) is not quite sure what GraphQL is our how it works or why I would use it in the first place.  I was interested in this technology, so I chose my favorite technique of learning hands-on within the context of ServiceNow.

We will explore the basics of GraphQL by implementing an actual API to retrieve Incidents for a University's Students using the ServiceNow platform.  To test it we will setup a third-party client and I will show you how to configure it to get it running.  

 

Why use GraphQL if I already know how to REST?

GraphQL answers a couple of issues when building a new API—it is standardized enough that once you get used to it picking up a new API is simple. It provides a standard definition format (Schema) for easier reuse and discoverability, it leads to less hunting through documents or samples to figure out what you need to send with an API request (it's all part of the Schema) and it defines the types that you can expect to get back (you guess it--in the Schema).

If you’re interested in GraphQL more generally, the official intro to GraphQL is a great place to start. 

By the time you complete this demo you’ll have mastered pretty much everything there is to know about building GraphQL APIs in ServiceNow!

 

What we will do today in Part 1:

1. Add a client to your instance test our API by installing the GraphiQL Client from Github.

2. Setup the Application Scope
3. Configure a new Graph API and start with Hello World (in Part 2 we will interact with Users and Incidents)
4. Create our first GraphQL query and submit it

 

Add GraphQL Explorer Client to your Instance

You will need a GraphQL Client to inspect and query your API, so we will add an open source one which we will call "GraphQL Explorer".

 

NOTE: Before going any further add the GraphiQL Client from Github to your instance by pulling it from Github in Studio. 

 

1. Open the Github Repo at https://github.com/ServiceNowNextExperience/graphiql/ and select "Fork" in the top right corner of the screen.

2. Use Studio and your newly forked URL (it will be something like github.com/mygithubname/graphiql) to "Import from Source Control".  (If you are not familiar with the process here are instructions on how to Import an Application from Source Control).

3. Once you're done refresh your browser and you should be able to navigate to "System Web Services > GraphQL > GraphQL Explorer".

 

Setup your Application

Today we will be creating a GraphQL API with a query to return "Hello World".

Note: You will not be using Studio to edit your API, but it is a shortcut to create a new application scope for the purposes of this tutorial.

1. Create a new Application Scope by going to System Applications > Studio and creating a new project named "GraphQL Tutorial".

Note: I like to verify the “Scope” field as well, in this case I made it “x_snc_graph_tutor”—this will actually become part of your API interface later so make it tidy.

2. When prompted you may select the Incident table but otherwise make no more changes in the Studio configuration and complete application setup.

 

Setup your GraphQL API Record

Like most things in ServiceNow it starts with a record!

1. Go to System Web Services > GraphQL APIs and create a new GraphQL API called “University” with a Schema Namespace of "university" (we will explain the use case in Part 2 of this tutorial).
2. Disable “Requires ACL Authorization”.

 

What is this weird JSON-looking stuff in the Schema field?

GraphQL works by combining the definition of the data schema with the definition of the query. That is, the schema of the query, the data input and the data returned is all explicitly defined in advance, unlike REST in which may return any data from any query at the developer’s whim.

 

This definition will be the published interface for our API and is also used by ServiceNow to give you some guardrails and help you in implementation.

Boilerplate Schema
schema {
  query: Query
  mutation: Mutation
}

type Query {
#implement here...
}

type Mutation {
#implement here...
}

Setup a simple Query in your Schema

We need to edit the default Schema value to allow us to make queries.

 

The two types of operations that ServiceNow supports are Query and Mutation, which are already prototyped by default and pretty much do what they sound like. Query defines how you find and retrieve data while Mutation defines how you create, edit or delete data.

 

We will start with the classic Hello World to show how quickly you can get to results, and how you can control the format of the results by returning JSON if you wish (more on returning GlideRecords in the next post).

 

1. Add a query to the Query type called “getHelloWorld” that takes an optional string parameter called "name" and returns the type HelloWorld.

 

You can't have empty type definitions so for now let's remove the mutation types and references.

HelloWorld Schema (02)
schema {
  query: Query
}

type Query {
  # NOTE: The ! means it's mandatory. Query must return a HelloWorld object
  getHelloWorld(name: String): HelloWorld!
}

type HelloWorld {
  # NOTE: The ! means that "message" cannot be missing or blank 
  message: String!
}

 

The first schema line says "there is one operation type, Query" (we'll add "Mutation" back in later) and then defines what is available in those types--so far just a single query called "getHelloWorld" and it returns a "HelloWorld" document.  Types are types and the exact same techniques will be used repeatedly as we build out our API.

 

NOTE: The "!" means "mandatory".  This means that the getHelloWorld query must return a HelloWorld object and the message property must be populated.

 

2. Add a Resolver that will process getHelloWorld requests.

Go to the related list "GraphQL Scripted Resolvers" and select "New".

Name it "Get Hello World" and use the following code:

HelloWorld Resolver (03)
(function process( /*ResolverEnvironment*/ env) {
  var message = "Hello World";
    var name = env.getArguments().name;

    if(name){
      message += ' (and ' + name + ')';
    }
    
    return {
      "message": message
    };
})(env);

 

3. Add a Resolver Mapping so that the processor knows which script to call for these request types.

Go the "GraphQL Resolver Mappings" related list and select "New".

 

The system is aware of the schema so you will see "Query:getHelloWorld" in the Path dropdown.  Choose that and select the Get Hello World resolver you created previously.

 

That's it!  Next we'll unit test our API.

 

How to run this thing

Enable Introspection

Introspection is the feature of GraphQL that allows your client to discover the schema and queries you have published and provides auto-complete in your client.  It can be fairly intensive to refresh the schema, so this is meant for development environments only.

 

1. Go to "System Web Services > GraphQL > Properties"

2. Enable introspective queries (the LAST item in the list of properties).

3. If you enable introspection for "GlideRecord Schema" it will download the schema of every table and field in your system.  Needless to say, that takes a while.

 

Create a GraphQL query 

The last step is to form the query, which conveniently is structured the same as the data itself. Since the schema is published by the server via introspection your client will use this to help you build your queries using autocomplete!

 

1. Navigate to "GraphQL > GraphQL Explorer" (if you missed it earlier, you can get the GraphiQL Client from Github).

2. Check the small “spinner” button in the bottom left of the main panel.  It will spin when you start the client each time and download the schema of all GraphQL APIs on the server.  

 

Build the query

1. Start by typing “query {” in the main panel (this causes auto-complete to reference the schema).
2. You are immediately prompted to select the Application you wish to use. In this case we are going to select our application’s namespace which you can find in the form for the GraphQL API record you created earlier. In my case it’s “xSncGraphTutor”.

03-query-namespaces.jpg

Query Namespaces (03)

 

3. Next we’ll type “{“ to bring up our API namespace, in this case choosing “university” (the Schema Namespace on the GraphQL API form).
4. We specify which query we wish to call with “getHelloWorld”.
5. Finally we need to let the API know that we wish to see the "message" value in the result, so select "message".

NOTE: While building your query in Insomnia if the auto-complete list goes away you can use ctrl-space to bring up the list of available options.

 

SUPER EXTRA NOTE: Depending on what instance you created your API in you may need to change the application namespace node in your query for this to work.  For example on a PDI it may be something like "x530453Gqlt".  Don't forget to change that for all queries going forward.

 

Your query should look like this now:

query {
  xSncGraphTutor { # Change to your Application Namespace
    university {
      getHelloWorld {
        message
      }
    }
  }

HelloWorld Query (04)

 

Let's see this in action!

That’s it—the suspense is killing me! Time to see all of this work in action. Click the “Send” button and wait for the results (it may take a moment the first time that you run it).

04-query-hello-world.jpg

HelloWorld Query Results (04)

 

Optional Parameters  

The schema designates an optional "name" parameter, so let's add that to our query using (name: "Moose and Squirrel"), like this:

 

query {
  xSncGraphTutor {
    university {
      getHelloWorld(name: "Moose and Squirrel") {
        message
      }
    }
  }
}

HelloWorld Query with Parameter (05)

 

That will return a message of "Hello World (and Moose and Squirrel)"

 

(If something goes wrong)

Sometimes the query doesn't officially fail but you see a bogus value like this: "message": "GraphQLObjectType{name='xSncGraphTutor_university_Query', description='null', fieldDefinitionsByName=[getIncidentsForStudent, getIncidents, getIncident, getStudent, getHelloWorld], interfaces=[]}"

 

Pro Tip: Whenever you have a problem always be sure to check your "GraphQL Resolver Mappings" related list.  

 

Why this rules!

Sure, it's pretty simple, but there are some powerful things happening here. 

Note that the results and the query are identical past the first nodes, including specifying that you wish to include "message" in the results.  This is fundamental to the idea that with GraphQL that everything is specified up front.  No surprises and no excess data sent or returned other than what you need! And thanks to the auto-complete features the tools even help you figure out what you can request and what you can expect to be returned.

 

Congratulations on your first GraphQL API and unit test! 

Tune in for Part 2: Querying Data with your GraphQL API Tutorial when we will start doing real work by creating an API to query Incidents, return more complex documents including lists, and show how to re-use Resolvers.

Source for this series is available at https://github.com/ServiceNowNextExperience/graphql-tutorial



 

Comments
George_
Tera Contributor

Thank you for sharing this tutorial, we really appreciate the effort!

Version history
Last update:
‎03-31-2023 08:18 AM
Updated by:
Contributors