Skip to main contentIBM Maximo REST API Guide

Selecting

Overview

When designing the the REST API framework, the following functionality was considered:

  • Being able to filter and sort Maximo business objects by using a higher-level query language that internally maps to the native SQL for the corresponding relation DB that is used by the Maximo deployment.
  • Being able to select the list of attributes that you want the API to fetch.
  • Being able to fetch data from related objects leveraging existing Maximo relationships without additional configuration.
  • Being able to page data.

With these basic requirements in mind, we can now talk about some of the query parameters that are used for facilitating these. Query API is always based on a collection URI for any resources that are API enabled. All collection URIs support a known set of URI query parameters that operates on the collection. The following most common query parameters are listed:

Selecting - oslc.select

This query parameter specifies the set of attributes to fetch from the object structures as well as the related objects.

Filtering - oslc.where

This query parameter specifies the WHERE clause for filtering the result set of a query.

Sorting - oslc.orderBy

This query parameter specifies how the results of a query are ordered.

Paging - oslc.pageSize

This query parameter specifies the resources for each page of a query.

Querying data - Mbo and relationship

Selecting - oslc.select

A sample select clause might be help understand it better. Below is a simple select clause from the MXAPIASSET object structure. oslc.select=assetnum,location,description,status

GET /oslc/os/mxapiasset?oslc.pageSize=10&lean=1

This results in the following JSON response:

{
"member": [
{
"href": "http:\/\/localhost\/maximo\/oslc\/os\/mxapiasset\/_QTYwMDIvRkxFRVQ-"
},
{
"href": "http:\/\/localhost\/maximo\/oslc\/os\/mxapiasset\/_TDEyNTEwL0xBUkVETw--"
},
{

This results in fetching the 10 members (max) of the MXAPIASSET resource, which is based on the ASSET MBO, and each member pointing to an asset record with a href that contains the link to get the details for that MXAPIASSET. Any collection resource in this REST API follows the same basic structure.

Note that the result is boxed under the member JSON array. Other than the member property there is another property called responseInfo that contains the meta information about the query. The meta information includes the current URI that is used to get the result (href) and the URL for the next page (nextPage), if there is a next page. The meta information also includes the URL for the previous page (previousPage), if there is a previous page. The current page number (pagenum) and total database count (totalCount) of the rows that meet the query filter criterion as well as the total number of pages (totalPages) that are available for this query are also included.

The totalCount and totalPages are not displayed by default. You can enable totalCount and totalPages by including the query parameter collectioncount=1 to the request. If you want to see only the total count of records that match the query and not the records, you use the request query parameter count=1. This results in the following JSON response:

{
"totalCount": 10
}

If you set the mxe.oslc.collectioncount system property to 1, the totalCount and totalPages parameters are included by default as part of the responseInfo. However, we recommend not to set that property to 1 because there will be cases where you may not need those values and will unnecessarily incur the cost of getting those values (which needs an additional SQL call to get total count). It is preferred to just request them using the query parameter collectioncount as needed.

Just getting the links to the member resources may not be very exciting or useful. Rather than traversing individual URIs for details, the oslc.select clause is used to get more details inlined in this JSON response.

GET /oslc/os/mxapiasset?oslc.pageSize=2&oslc.select=assetnum,location,description,status&lean=1

This results in the following JSON response:

{
"member": [
{
"assetmeter_collectionref": "http:\/\/localhost\/maximo\/oslc\/os\/mxapiasset\/_QTYwMDIvRkxFRVQ-\/int_assetmeter",
"status_description": "Not Ready",
"ahrrplan_collectionref": "http:\/\/localhost\/maximo\/oslc\/os\/mxapiasset\/_QTYwMDIvRkxFRVQ-\/ahrrplan",
"description": "Highway Tractor, Class 8 Truck, Cummins M11 , Spic",
"moddowntimehist_collectionref": "http:\/\/localhost\/maximo\/oslc\/os\/mxapiasset\/_QTYwMDIvRkxFRVQ-\/moddowntimehist",
"downtimereport_collectionref": "http:\/\/localhost\/maximo\/oslc\/os\/mxapiasset\/_QTYwMDIvRkxFRVQ-\/downtimereport",

This results in a JSON that contains the four attributes as requested for each of the members. Note that by default the API response skips the null value attributes. For example, if the location is null for any of the member assets in the selection, that attribute will not appear in the member JSON and helps reduce the response payload size. To force the response to add null value attributes, use the query parameter _dropnulls=0.

Note that along with the status you will also have the status_description property, which contains the synonymdomain description for that corresponding status value that is based on the users profile language. The API framework detects a domain bound attribute (from the Maximo metadata repository) and uses the domain cache to fetch the description for that status.

The _rowstamp property is present for every object in the object structure for a given resource record and is used for handling dirty updates.

The xxxx_collectionref properties includes the links to child objects as defined in the MXAPIASSET object structure. The prefix xxxx is the name of the child object. The GET <collectionref link> shows the collection of the child objects. We can traverse through that collection resource just like any other collection ie we can page through them (using oslc.pageSize) or filter them (using oslc.where) or get partial views (using oslc.select) etc.

To get data from the assetmeter object where assetmeter is a child object as defined in the object structure MXAPIASSET, you can use the following select clause:

GET /oslc/os/mxapiasset?oslc.pageSize=2&oslc.select=assetnum,status,description,location,assetmeter{*}&lean=1

The member JSON looks like:

{
"member": [
{
"assetmeter_collectionref": "http:\/\/localhost\/maximo\/oslc\/os\/mxapiasset\/_QTYwMDIvRkxFRVQ-\/int_assetmeter",
"status_description": "Not Ready",
"description": "Highway Tractor, Class 8 Truck, Cummins M11 , Spic",
"assetmeter": [
{
"rolldownsource_description": "Accept Asset rolldown.",

To get the child object details, the notation - <child object name>{comma separated attribute names} or * to get all properties is used. So assetmeter{*} is going to fetch all properties for the assetmeter. This notation is applicable for multiple levels. For example, you can define obj1{prop1,prop2,obj2{prop21,prop22}} - where obj2 is defined as a child object of obj1.

While this notation works for child objects, you often need to get more data from related objects, such as locations or work orders, which are not defined in the object structure. The following notation is an example of calling more data from related objects:

GET /oslc/os/mxapiasset?oslc.pageSize=2&oslc.select=assetnum,status,description,location,location.description,location.status&lean=1

This results in a member json like:

{
"member": [
{
"status_description": "Not Ready",
"description": "Highway Tractor, Class 8 Truck, Cummins M11 , Spic",
"_rowstamp": "36654",
"assetnum": "A6002",
"$alias_this_attr$location": "DALTERM",
"location": {

Aliasing of attributes

You might have noticed the property “$alias_this_attr$location”. What is that?

The name clash of the attribute named location with the relation named location - both at the asset object level. In XML, this clash is resolved by using namespaces. With JSON, you can rename the property with an alias. Aliasing refers to the process of renaming a MBO attribute in the JSON domain to avoid naming conflicts. Where there is a naming conflict, the JSON response marks the renamed attribute with the prefix $alias_this_attr$. To alias an attribute, you use the -- operator in the select clause. The following renames the location attribute to mylocation in the JSON domain:

oslc.select=assetnum,location--mylocation,location.status

Note that the -- operator works only on attributes and not on object names or relation names. Therefore, if an attribute name clashes with an object name or a relation name, the attribute name needs to be aliased.

The response json looks like following:

{
"member": [
{
"assetnum": "A6002",
"location": {
"status_description": "Operating",
"status": "OPERATING"
},
"href": "http:\/\/localhost\/maximo\/oslc\/os\/mxapiasset\/_QTYwMDIvRkxFRVQ-",

Dynamic Select Clause

1:1 relationship

Asset to location is a 1:1 relationship where the dot notation attaches the JSON object for the location with the member JSON for MXAPIASSET at the asset header object. Note that the API framework detects a conflict of names - attribute location and the relation named location. Note that the dot notation format is <relation name>[.<relation name>]*.<attribute name>. Effectively, these relations can be nested too. The API response groups attributes at each relation level to form the JSON object. For example:

oslc.select=rel1.a1,rel1.a2,rel1.rel11.a11,rel1.rel11.a12,rel1.rel21.a21

Will result in a json like

{
"rel1": {
"a1": "...",
"a2": "...",
"rel11": {
"a11": "...",
"a12": "..."
},
"rel21": {

1:many relationship

Dot notations produce JSON objects. However, for related data that is 1:*, a variation is required. For example, for an Asset:Workorder relationship, an asset can have many open work orders. If you want to get details about all open work orders for the set of Assets, you can use the following select clause:

GET oslc/os/mxapiasset?_lid=wilson&_lpwd=wilson&oslc.pageSize=2&oslc.select=assetnum,rel.openwo{wonum,description}&oslc.where=openwo.wonum="*"

This rel notation has the format - rel.<relation name> and results in a JSON array property named relation name. The following example shows the sample output format:

{
"member": [
{
"openwo": [
{
"description": "11400 PM work",
"wonum": "43013"
},
{

This rel notation can also be nested. The nesting occurs as part of it’s attribute set, for example:

oslc.select=rel.rel1{attr1,attr2,rel.rel2{attr21,attr22},rel.rel3{*}, rel4.attr4}

Here the rel2, rel3 are samples of nesting the rel notation. The rel4.attr4 shows that you can embed a dot notation within a rel notation but not the other way round. The rel3 also demonstrates that you can use * to get all attributes for that target object. To determine whether * implies all persistent attributes or all persistent and non-persistent attributes combined, use the following guidelines:

  • If the target object is a persistent object, the * notation includes all persistent attributes for that object. You need to explicitly request the non-persistent attributes to include them. For example, - rel.openwo{*,displaywonum} where displaywonum is a non-persistent attribute in the target object.
  • If the target object is a non-persistent object, the * notation will include all non-persistent attributes for that object.

Note that these dot notation attributes and the rel attributes can be used at any level of the object structure. For example, we count use it in assetmeters like below

oslc.select=assetnum,status,assetmeter{*,rel.rel1{attr1,attr2},rel2.attr3}

Traversing to related MboSets is achieved by using the relation name as part of the GET URI call. The following example shows how to move from an asset to a work order using the relationship name.

GET /oslc/os/mxapiasset/{rest id}/openwo?oslc.select=*

The openwo relationship name is used to traverse to the work order collection from a given asset. The resulting JSON is a serialized response that is based on the work order MBO, which by default does not contain any non-persistent attributes. You request non-persistent attributes explicitly in the oslc.select clause.

GET /oslc/os/mxapiasset/{rest id}/openwo?oslc.select=*,npattr1,npattr2

If you prefer getting the response as a object structure collection resource, you can use the following clause:

GET /oslc/os/mxapiasset/{rest id}/openwo.mxapiwodetail?oslc.select=*

The object structure name is added at the end of the relation name with a dot separator. With this request, you get all work order records returned as mxwodetail records. The following example is a variation of the API:

GET /oslc/os/mxapiasset/{rest id}/openwo?oslc.select=*&responseos=mxapiwodetail

In both cases, (that is MBO and object structure), you can use all the collection API query parameters like oslc.select and oslc.where and use paging etc to filter, sort, and view the collection as required. Note that this is recursive and you can go as deep nested as needed by using the relation name and the rest ID pair. For example:

GET /oslc/os/mxapiasset/{rest id}/openwo/{rest id}/jobplan/?oslc.select=*

These rest IDs are derived from the URIs that come back from the server. The client code does not need to generate these IDs but uses the URIs and append the relation name token to it to traverse down from the selected record. We have seen in previous sections how related MboSets can be inlined (inside the parent Mbo/set data) using the rel notation. This is different in the sense that we are not inlining the related MboSet, rather we are treating it just like another independent collection resource.

Querying data - Related data

So far we have been discussing how to fetch the MBO and related MBO attributes for the object structure. We are now going to cover the other forms to related data and how to request them explicitly or implicitly.

Images

In Maximo Asset Management, an image repository (imglib table) stores the image avatars for the managed resources, such as assets, items, person. The API framework maintains a cache of the image references. If the system detects an image reference while fetching the resource details, the URI for the image document is added to the resulting JSON (_imagelibref). The Maximo image repository stores the images in the Maximo database or in an external repository provided that the repository exposes a simple URI based mechanism to load the images. To facilitate that, the IMGLIB table has two attributes - imguri and endpointname. The endpointname attribute points to the integration endpoint, which is the http(s) endpoint, and the imguri attribute refers to the URL of the image that is used by the http endpoint to fetch the image. It is possible to use a custom endpoint to handle more complex URLs. Bulk loading of images can be done by using SQL command line tools. Associating images to any Maximo MBOs can be done by using REST APIs. The following sample REST API associates an asset with an image.

POST /oslc/os/mxapiasset/{id}?action=system:addimage
custom-encoding: base64
x-method-override:PATCH
Slug: <maps to image name in imglib> Content-type: <maps to mime type in imglib>
<HTTP body contains the base64 encoded image bytes>

Or

POST /oslc/os/mxapiasset/{id}?action=system:addimage
x-method-override:PATCH
Slug: <maps to image name in imglib>
Content-type: <maps to mime type in imglib>
Body:
{
"imguri":<uri for the externally sourced image>,
"endpointname":"..."

The following API deletes the associated image:

POST /oslc/os/mxapiasset/{id}?action=system:deleteimage
x-method-override:PATCH

Domain internal values

Maximo REST API supports fetching the synonymdomain internal value corresponding to the external value which will be in the payload by default as part of the mbo attribute value. Most use cases need the internal values for some client side logic as the external values are customer specific and the internal values are base provided. To get the internal values use the query parameter internalvalues with the value set to 1. The internal value would be set using the <attribute name>_maxvalue property. An example is shown below

GET /oslc/os/mxapiasset?oslc.select=assetnum,status&internalvalues=1

This results in following JSON response:

{
"members": [
{
"status": "...",
"status_maxvalue": "..."
}
]
}

Database Aggregation functions

Maximo REST API supports using database aggregation (max,min,avg,sum,count, and exists) functions on related MboSets. For example, to apply these functions on the open work orders for an asset, all the aggregation functions are used in the following API:

GET /oslc/os/mxapiasset/{rest id}?oslc.select=assetnum,openwo.actlabhrs._dbavg,openwo.actlabhrs._dbsum,openwo.actlabhrs._dbmax,openwo.actlabhrs._dbmin,openwo._dbcount&oslc.where=openwo.wonum="*"

The format for the sum,avg,max, and min functions is <relation name>.<target attrname>._<operation>. Note that the supported operations are dbsum (for sum), dbavg (for avg), dbmax (for max) and dbmin (for min). The format is always a dot (.) separated by a three token format that includes a relationship name token that is followed by an attribute name and the underscore prefixed (_) operation to perform on that related attribute.

The count function (operation dbcount) has a two token format that includes the relation name as the first token followed by the operation name (_dbcount) and evaluates the count on that related MboSet. The JSON response looks like:

{
"openwo": {
"_dbcount": 17,
"actlabhrs": {
"_dbsum": 2.5,
"_dbmax": 2.5,
"_dbavg": 0.14705882352941177,
"_dbmin": 0.0
}

Bookmarks

Maximo bookmarks can be leveraged with the rest APIs.

Formula properties

You can select calculated values without creating non-persistent attributes by using the integration between the REST APIs and the object formula feature.

For example, you create a object formula called MYREPLACECOST for asset object by using the Object Formula action in the Database Configuration application. The formula is purchaseprice/NVL(priority,1). You can then select that formula property that is associated with the asset object by using the following API select clause:

GET /oslc/os/mxapiasset?oslc.select=assetnum,status,exp.myreplacecost

The response is as if myreplacecost was an attribute of the asset MBO.

{
"member": [
{
"assetnum": "A6002",
"myreplacecost": 39000.0
},
{
"assetnum": "L12510",
"myreplacecost": 1450.0

A similar approach applies to an individual resource:

GET /oslc/os/mxpaiasset/{rest id}?oslc.select=assetnum,status,exp.myreplacecost

{
"assetnum": "L12510",
"href": "oslc\/os\/mxapiasset\/_TDEyNTEwL0xBUkVETw--",
"myreplacecost": 1450.0
}

Note that this can be considered as a great alternative to defining non-persistent attributes just for the sake of holding calculated values. This acts like a dynamic attribute that does not need db config or admin mode.