In this tutorial, you’ll learn how to use the Maximo REST API and the Maximo NodeJS SDK to build a web application that allows any user to access Maximo asset data. The user authenticates using the Maximo NodeJS SDK authentication, and then the user can perform asset queries, read asset details, and create an asset.

If you prefer, you can watch a video demo of building this app.

This tutorial includes a complete Node.js web application that calls the Maximo REST APIs using Maximo Core Development Instance Docker Container. The Node.js web app uses the Express Framework

Before you begin

In this tutorial, we will use a local deployment architecture.

Maximo development architecture

However, there are differences when you move your application into a production architecture.

Maximo production architecture

Complete these prerequisite steps:

  1. Set up your local development environment
  2. Optional: Set up your production environment
  3. Familiarize yourself with IBM Maximo
  4. Obtain a trial license or paid license of Maximo to use the Maximo APIs used in this tutorial.

Set up your local development environment

You need to install the following software:

  • IBM® Maximo® Asset Management V7.6. You also need a licensed, running server to develop with Maximo Asset Manager. IBM Business Partners can get a license using the IBM Software Access Catalog. IBM Business Partners can also request access to a Docker container with Maximo for development time only. Contact Hari Narasimhamurthy mailto from IBM.

  • Git. You’ll use Git for source code management and versioning.

  • Node.js. You’ll need a Javascript Server runtime environment to run the app locally.

  • Postman. You’ll use this API development environment to test REST APIs.

Set up a production environment in IBM Cloud

This tutorial does not provide instructions for setting up a production environment, but you will need to complete these steps:

  • IBM Maximo Asset Management. See the available options, including a free trial, on the IBM Maximo product page.

  • An IBM Cloud account. To deploy your Node.js app to IBM Cloud, you will need a Cloud Foundry Node.js runtime.

  • IBM Cloud CLI. You’d use these commands to deploy your Node.js app to the production environment in IBM Cloud.

Familiarize yourself with IBM Maximo

To learn more about the Maximo REST APIs, watch these video tutorials:

Also, you’ll need to review and consult these API reference documents:

Finally, you’ll want to explore the documentation and information from the community:

Steps

To develop the Node.js web app that provides access to Maximo asset data, complete these steps:

  1. Set up and start a Maximo Docker container

  2. Run the Node.js web app

  3. Review the code to learn more about the Maximo REST APIs and Maximo Node.js SDK

  4. Test the web app to try to query assets, read asset details, and create an asset

Set up and start a Maximo Docker container

After requesting and receiving directions on how to retrieve your Maximo Docker Image for development time use (and the token), complete these steps:

  1. Install the Docker engine. These Maximo containers are tested to run Linux, Windows 10, and Mac.

  2. Download the Maximo Docker Image. Use the following commands to login and download the docker images. Substitute with the token value that you were given.

    docker login -u token -p <token value> registry.ng.bluemix.net
    docker pull registry.ng.bluemix.net/maximodev/bpdevws:7610
    docker pull registry.ng.bluemix.net/maximodev/bpdevdb2:7610
    
  3. After your request to access the Docker Container is fufilled, you are given a file docker-compose.yml. Save the attached docker-compose.yml file into a new folder. Change directories to the directory where you saved the docker-compose.yml file.

  4. Use the docker-compose command to run the container using the docker-compose.yml file to start both Maximo and Docker.

    docker-compose -f docker-compose.yml up`
    

    screen shot of command line showing docker-compose command

  5. Verify that both Maximo and Docker are running. When the Maximo instance is running, as marked by repeated “Correlation started” log messages on the command prompt, Maximo can be accessed in a browser with this URL “http://localhost:9080/maximo” where <localhost> can be replaced by a resolvable hostname or a reachable ip address.

After launching the url http://localhost:9080/maximo in a browser, you can log in using wilson as the userid and wilson as the password.

Run the web app

  1. Clone this Git repository which has the completed Node.js app:

    git clone git@github.ibm.com:carlos-ferreira/maximo-nodejs-getstarted.git

  2. Install the dependencies listed in the package.json file to run the app locally.

    cd maximo-nodejs-getstarted
    npm install
    
  3. Install the Maximo REST API Node.js module:

    npm install --save ibm-maximo-api

  4. Add the cookie-parser module to reuse the authentication in the browser for calling APIs. Issue one of these commands:

    • npm install cookie-parser -g

    • sudo npm install cookie-parser

  5. Install the express-session module:

    sudo npm install express-session

  6. Run the app.

    npm start

    Or if you want your file system code changes to be automatically reloaded by Node.js use this command.

    nodemon server.js

  7. View your app at the following URL, where <localhost> can be replaced by a resolvable hostname or a reachable ip address:

    http://localhost:3000

Review the code to learn more about the APIs

To understand the Maximo REST APIs and the Maximo NodeJS SDK that are used in this app, let’s review the methods in the code in the server.js file. These methods show the corresponding URLs that are used and the methods that are invoked for authentication, querying assets, getting asset details, and creating an asset. These examples are for a Maximo environment that uses native Maximo authentication (as opposed to app server-based authentication, such as LDAP).

Authentication

Add authentication to your web app to authenticate the API using the user’s credentials in the browser.

app.get('/authenticate', function(req, res)
{
      var maximo = new Maximo(options);
      maximo.authenticate()
            .then(function(setcookie)
            {
              jsondata = setcookie;
              req.session.authcookie = jsondata; // Set the cookie in the session so we can use it for future requests
              res.json(jsondata);
            })
            .fail(function (error)
            {
                  console.log('****** Error Code = '+error);
            });
});

Load the Maximo library

Enable the app to call the Maxmio REST API.

var Maximo = require('ibm-maximo-api');

Query Assets in Maximo

Enables the app to query for assets using an app REST API URL of http://localhost:3000/api/assets. The method uses the Maximo NodeJS SDK to authenticate and query for assets in the Maximo database.

app.get("/api/assets", function (request, response) {
  maximo.resourceobject("MXASSET")
      .fetch()
      .then(function(resourceset)
          {
    jsondata = resourceset.thisResourceSet();
    response.json(jsondata);
    uri = jsondata[0]["href"];
          })
      .fail(function (error)
      {
            console.log('****** Error Code = '+error);
      });
});
Query Asset Details using REST API JSON

Here is example of the Maximo REST API JSON response for getting asset attribute details. You can see the structure using this URL:

http://localhost:9080/maximo/oslc/os/mxasset?_lid=wilson&_lpwd=wilson&lean=1&oslc.pageSize=10&&oslc.select=*&lean=1

{
    "member": [{
        "calnum": "COMPANY1",
        "ytdcost": 934.13,
        "installdate": "1998-08-27T00:00:00+00:00",
        "moved": false,
        "pluscismte": false,
        "pluscisinhousecal": false,
        "totalcost": 2113.87,
        "_rowstamp": "373940",
        "totunchargedcost": 0.0,
        "children": false,
        "tloampartition": false,
        "siteid": "BEDFORD",
        "unchargedcost": 0.0,
        "href": "http:\/\/localhost\/maximo\/oslc\/os\/mxasset\/_MTMxNTAvQkVERk9SRA--",
        "removefromactivesp": false,
        "assetspec_collectionref": "http:\/\/localhost\/maximo\/oslc\/os\/mxasset\/_MTMxNTAvQkVERk9SRA--\/assetspecclass",
        "mainthierchy": false,
        "status_description": "Not Ready",
        "returnedtovendor": false,
        "changepmstatus": false,
        "changedate": "1999-03-11T15:32:11+00:00",
        "replacecost": 6200.0,
        "priority": 3,
        "orgid": "EAGLENA",
        "pluscsolution": false,
        "removefromactiveroutes": false,
        "rolltoallchildren": false,
        "itemsetid": "SET1",
        "assetopskd_collectionref": "http:\/\/localhost\/maximo\/oslc\/os\/mxasset\/_MTMxNTAvQkVERk9SRA--\/assetopskd",
        "status": "NOT READY",
        "assetmeter_collectionref": "http:\/\/localhost\/maximo\/oslc\/os\/mxasset\/_MTMxNTAvQkVERk9SRA--\/int_assetmeter",
        "islinear": false,
        "iscalibration": false,
        "serialnum": "32R5G",
        "description": "Top Breaker System",
        "assetusercust_collectionref": "http:\/\/localhost\/maximo\/oslc\/os\/mxasset\/_MTMxNTAvQkVERk9SRA--\/assetusercust",
        "manufacturer": "WES",
        "totdowntime": 0.0,
        "_imagelibref": "http:\/\/localhost\/maximo\/oslc\/images\/50",
        "pluscpmextdate": false,
        "vendor": "WES",
        "assetnum": "13150",
        "plusciscontam": false,
        "warrantyexpdate": "2003-08-31T00:00:00+00:00",
        "disabled": false,
        "changeby": "MAXIMO",
        "assettag": "13443",
        "invcost": 0.0,
        "newsite": "BEDFORD",
        "purchaseprice": 5500.0,
        "statusdate": "2001-05-10T10:18:21+00:00",
        "isrunning": true,
        "budgetcost": 800.0,
        "failurecode": "PKG",
        "assetid": 8,
        "assetmntskd_collectionref": "http:\/\/localhost\/maximo\/oslc\/os\/mxasset\/_MTMxNTAvQkVERk9SRA--\/assetmntskd",
        "location": "BPM3100",
        "autowogen": false
    }]
}
Query Asset Details using server.js method

To get asset details on an asset you choose from the query above using HREF. For ‘maxauth’ the values in the header should be base64-encoded, not plain text.

app.get("/api/asset_detail", function (request, response) {
    console.log("request JSON body -------")
    console.log(request.body);
    console.log("request href -------")
    var  asset_href = request.query.href;
    console.log(asset_href);
    var result = /[^/]*$/.exec(asset_href)[0];
    console.log("Result " + result)

    Request.get({
        "headers": { "content-type": "application/json",
                      "properties": "*" ,
                      "maxauth" : Buffer.from("wilson:wilson").toString('base64') },
        "url": "http://localhost:9080/maximo/oslc/os/mxasset/_MTMxNTAvQkVERk9SRA--"
    }, (error, res, body) => {
        if(error) {
            console.dir(error);
            response.json(error);
            return
        }
        if (res) {
            console.log("JSON res ");
            console.log(res.body);
            // doc = JSON.parse(res);
            response.json(res)
            return
        }
        if (body) {
            console.log("JSON body ");
            console.log(JSON.parse(body));
            //var doc =  response.json( JSON.parse(res.body)    );
            response.json(body)
            return
        }
    });

Create an asset endpoint

Here’s how you create an asset endpoint that you add to the server.js file.

app.post("/api/asset_create", function (request, response) {
    Request.post({
        "headers": { "content-type": "application/json",
                      "properties": "*" ,
                      "maxauth" : Buffer.from("wilson:wilson").toString('base64') },
        "url": "http://localhost:9080/maximo/oslc/os/mxasset?lean=1",
        "body": JSON.stringify({
                                "assetnum": "TEST210",
                                "status": "NOT READY",
                                "description":"Test Asset 210",
                                "siteid": "BEDFORD"
                                })
    }, (error, res, body) => {
        if(error) {
            console.dir(error);
            response.json(error);
            return
        }
        if (res) {
            console.log("JSON res ");
            console.log(JSON.parse(res.body));
            // doc = JSON.parse(res);
            response.json(res)
            return
        }
        if (body) {
            console.log("JSON body ");
            console.log(JSON.parse(body));
            //var doc =  response.json( JSON.parse(res.body)    );
            response.json(body)
            return
        }
    });
    //response.send(res.body)
});`
REST API Create Asset Error JSON Format
{ Error:
   { errorattrname: 'assetnum',
     extendedError: { moreInfo: [Object] },
     errorobjpath: 'asset',
     correlationid: null,
     reasonCode: 'BMXAA4129E',
     message:
      'BMXAA4129E - The record for Site=BEDFORD, Asset=1234 already exists. This validation error is thrown when an attempt is made to insert a new record with a unique key value that already exists in the database. Ensure that the key value for the given record is unique.',
     statusCode: '400'
   }
  }
REST API Create Asset Success Response JSON
{ ytdcost: 0,
  moved: false,
  pluscismte: false,
  pluscisinhousecal: false,
  totalcost: 0,
  _rowstamp: '1678851',
  totunchargedcost: 0,
  children: false,
  tloampartition: false,
  siteid: 'BEDFORD',
  unchargedcost: 0,
  href: 'http://localhost/maximo/oslc/os/mxasset/_MTIzL0JFREZPUkQ-',
  removefromactivesp: false,
  assetspec_collectionref:
   'http://localhost/maximo/oslc/os/mxasset/_MTIzL0JFREZPUkQ-/assetspecclass',
  mainthierchy: false,
  status_description: 'Not Ready',
  returnedtovendor: false,
  changepmstatus: false,
  changedate: '2019-03-19T10:04:18+00:00',
  replacecost: 0,
  orgid: 'EAGLENA',
  pluscsolution: false,
  removefromactiveroutes: false,
  rolltoallchildren: false,
  itemsetid: 'SET1',
  assetopskd_collectionref:
   'http://localhost/maximo/oslc/os/mxasset/_MTIzL0JFREZPUkQ-/assetopskd',
  status: 'NOT READY',
  assetmeter_collectionref:
   'http://localhost/maximo/oslc/os/mxasset/_MTIzL0JFREZPUkQ-/int_assetmeter',
  islinear: false,
  iscalibration: false,
  description: 'Test Asset',
  assetusercust_collectionref:
   'http://localhost/maximo/oslc/os/mxasset/_MTIzL0JFREZPUkQ-/assetusercust',
  totdowntime: 0,
  pluscpmextdate: false,
  assetnum: '123',
  plusciscontam: false,
  disabled: false,
  changeby: 'WILSON',
  expectedlife: 0,
  invcost: 0,
  newsite: 'BEDFORD',
  purchaseprice: 0,
  statusdate: '2019-03-19T10:04:18+00:00',
  isrunning: true,
  budgetcost: 0,
  assetid: 2173,
  assetmntskd_collectionref:
   'http://localhost/maximo/oslc/os/mxasset/_MTIzL0JFREZPUkQ-/assetmntskd',
  location: 'SHIPPING',
  autowogen: false }

Test the web app

To test the Maximo Getting Started Node.js web application, you first need to ensure that your Maximo REST APIs are working.

  1. Test that your Maximo environment — either your local Docker Container (you can use this URL http://localhost:9080/maximo/oslc to check it) or the Maximo SaaS Environment (you can use this URL https://trial-classic.maximosaas.ibm.com/maximoui/oslc to check it) — is available by opening a browser and accessing the JSON REST APIs that the app will use. Or, you can use Postman to test the REST JSON APIS. View the JSON REST interfaces available.

  2. Test that the query REST API that the Getting Started Node.js web app uses is working.

The URL to query for Maximo public assets with page size of 10 records and using user id and password of wilson as url query parameters. Using user id and password as URL query parameters is not recommended for production applications. This is used as an example of how to query a Maximo test system quickly to see the JSON structure.

http://localhost:9080/maximo/oslc/os/mxasset?_lid=wilson&_lpwd=wilson&lean=1&oslc.pageSize=10

Or, you can use pageSize=5 for 5 records:

http://localhost:9080/maximo/oslc/os/mxasset?_lid=wilson&_lpwd=wilson&lean=1&oslcpageSize=5

  1. To better understand what Get and Post parameters can be used to modify Maximo REST JSON query results, append ?lean=1 to see just the JSON in the browser.

Summary and Next Steps

Congratulations on learning how to setup your Maximo development enviroment and run a simple getting started Node JS application that uses Maximo REST API’s for creating assets. With this knowlege you can now try and creat other types of business object in Maximo like a Work Order or like working with the child objects of an Asset.

To learn more about these objects review the child to Asset in MXASSET: ASSETUSERCUST, ASSETOPSKD, ASSETMETER, ASSETMNTSKD, ASSETSPEC URL parameter to select all columns using this REST API:

http://host:port/maximo/oslc/os/mxasset?lean=1&oslc.select=*

You can explore other samples in the Maximo Developer Github site.