Inbound REST Integrations with Service Now

I'm new to Service Now. I just started developing on the NOW platform a little shy of 3 months ago. For those of you that are not familiar with Service Now, it's a highly organized and complex cloud computing platform mainly used by huge companies for IT Service Management, it's so big, it's literally does everything you could every want in a Hosted Software as as Service Platform. Or is it a Service as a Service Platform. Either way, it's massive and can manage your entire IT infrastructure with ease.

Do you want to start Developing applications in Service Now? No problem.

You can request and use a Developer instance to learn the platform. They are 100% free. But they also come with some caveats you should be aware of. Like your instance going to sleep and getting wiped if you forget to keep online and awake. This will require some effort on your part. I have attempted to circumvent this by using Headless Browser Automation with Selenium; but somehow Service Now can detect that a browser is being controlled by a software program. Even when mimicking the behavior of a real life user.

In a recent SNOW build for a customer, I was able to quickly and easily create, code, test and deploy an Inbound RESTful API Integration with CMDB.

Let's walk through the steps.

The Data Model

Start by launching the Studio app from your DEV instance. In Studio, the Application Menu will load. Select Create Application. Then Create from Scratch.

I am naming my application NetAuto.

Switch to the Application when prompted. The first item to build will be a table to hold our Device Status Checks. Every time a device responds to a request, it will post that status check back into a SNOW table.

Fields for this table are quite simple.

  • Timestamp
  • Device ID
  • Health Status (choice, OK, NOT OK)

I am also adding new table columns to Locations (cmn_location) and Communication Devices (cmdbci_comm)

  • StoreID
  • DeviceID
  • DeviceAuthUser
  • DeviceAuthPass
  • Device Endpoint
  • Device Comm Port
  • Device URL Prefix

table columns

You will have to populate some data in your instance to use the API. Next >>

The REST API

Start the Inbound integration by clicking Create Application File, scrolling to Inbound Integrations and choosing Scripted REST API

service now scripted rest api

And the completed REST API with no Resources yet defined.

Make sure you select Protected for your Protection Policy. This encrypts the Scripts and protects your IP.

The API Resources

Starting endpoints. We need to get a list of stores, then a list of network devices in each store that require monitoring, then we need to get the device detail, and maybe an endpoint for all devices.

  • /api/x_devinstancescope/netauto/netapi/stores
  • /api/x_devinstancescope/netauto/netapi/store/{storeId}
  • /api/x_devinstancescope/netauto/netapi/store/{storeId}/devices
  • /api/x_devinstancescope/netauto/netapi/devices

Build the Resources (Endpoints) out like so...

This is the second API Resource - GetStoreDetail

Our GetStoreDetail Resource script file simply and efficiently passes the request object and the response object to our Script Include class method - getStore.

NETAPI().getStore(request, response)  

Now, I am not going to build out each of these routes in full, but the example should be enough to extrapolate the additional endpoints in your own project. Now let's take a look at the Script Include.

The Script Include

Create the Script Include by selecting Create Application File in Studio and choosing Server Development, Script Include.

restapi-script-include

Next, we can begin coding our script.

var NETAPI = Class.create();  
NETAPI.prototype = {  
    initialize: function() {
        this.util = new NETUtil();
        this.tableName = this.util.getTableNames("stores");
        this.msgPrefix = this.util.getLogPrefix();
    },

    getStores: function(request, response) {
        try {
            var gr = new GlideRecordSecure(this.tableName);
            gr.addNotNullQuery("x_devinstance_location_id");
            gr.addQuery("x_devinstance_active", "true");
            gr.orderBy("x_devinstance_location_name");

            var storeArray = [];

            while (gr.next()) {
                storeArray.push({
                    "name": gr.name + "",
                    "location_id": gr.x_devinstance_location_id + "",
                    "status": gr.x_devinstance_active + "",
                    "city": gr.city + "",
                    "state": gr.state + "",
                    "zip_code": gr.zip_code,
                });
            }

            // set the response
            response.setStatus(200);
            response.setContentType("application/json");

            // log activity
            gs.log(this.msgPrefix + " REST API fetched " + storeArray.length + " stores from the database");

            // return response
            return response.setBody(storeArray);
        }
        catch (ex) {
            var msg = ex.message;
            gs.log(this.msgPrefix + " ERROR :: " + msg);
        }
    },

    type: 'NETAPI'
};

First thing to note here is I am using a utility to class to define the messaging prefix for my loggers as well as defining the table space scoped names.

Next, we instantiate a method getStore and pass the request and response objects to the function. The Store ID is parsed from the Resource path parameters (i.e pathParams) and used as a query parameter in our Glide Record object.

If we have a valid Store ID, the query looks up the store in the CMDB and returns the data as JSON.

The REST API Explorer

The Studio app comes complete with its own REST API Explorer UI that allows you to make REST calls against the API you are developing. Use the Glide System Log to log the events as you are testing for quick and dirty debugging. It's not quite up to par with Swagger UI but it is super helpful for testing.

rest-api-explorer

Using Postman to Test the API

Postman is my API testing suite of choice, but you can use whatever you prefer. Make some calls and test your API.

postman-image

Integrating into an Automation Project in Python and Celery

The next step for this project is to integrate our Celery automation with the new REST API and begin making calls to each of the endpoints.

Next week, I will add another post covering the Python and Celery components required to consume the API.

Conclusions

Service Now is a Beast. Can you see how quickly a project like this comes together with the Power and Flexibility of the NOW Platform.

I'm totally amazed. Before a few months ago, I had never even heard of Service Now. Today, I am building high-performance network automation applications with Service Now backend REST APIs.

Automate all the things.

Craig Derington

Secular Humanist, Libertarian, Open Source Software Advocate building Cloud Apps on RHEL and Ubuntu Server. My toolset includes Python, Celery, Flask, Django, Graph, EdgeDB, MySQL, MongoDB and Git.

comments powered by Disqus