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}
wheredisplaywonum
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
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:addimagecustom-encoding: base64x-method-override:PATCHSlug: <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:addimagex-method-override:PATCHSlug: <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:deleteimagex-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.