REST/JSON services
Presentation
iTop provides a REST/JSON interface which allows third party applications to remotely interact with iTop for retrieving, creating or updating iTop objects. This interface is based on a set of simple HTTP POST requests. The data passed to and retrieved from iTop are encoded in JSON using the UTF-8 character set.
Such requests can be performed from any programming language capable os issuing HTTP/POSTs and manipulating JSON encoded data. Requests can even be run directly in javascript inside any web page by the mean of cross-site scripting (iTop supports both CORS and JSON-P). An example of such cross-site scripting in javascript is given in the REST JSON Playground.
The URL to POST the requests looks like:
<itop-root>/webservices/rest.php?version=1.0
Such requests expect the following parameters to be passed:
-
auth_user
-
auth_pwd
-
json_data
In fact, the HTTP method can be either POST or GET (this is needed for JSON-P support). POST and HTTPS are recommended for security reasons (to avoid passing the credentials in clear text) and also because GET imposes a limit on the size of the input data.
Let's have a look at all the parameters of this HTTP service:
Argument | Description | Defaut value |
---|---|---|
version | Exact version of the API. It ensures stability for your scripts: the operations available for a given version should never be deprecated nor have a new interface. | - |
auth_user | User login | - |
auth_pwd | User password | - |
json_data | Structure containing all the information required to process your request. In particular, the requested operation is given here. | |
callback | If set, then JSON-P (JSON with padding) is used |
These parameters apply to any type of operation that is requested.
Operation: list_operations
The first operation you should be familiar with is: list_operations. This command returns the list of all possible operations.
The syntax of the json_data input is as simplest as could be:
{ operation: 'list_operations' }
The reply will look like:
{ version: '1.0', operations: [ { verb: 'core/create', description: 'Create an object', extension: 'CoreServices' }, { verb: 'core/update', description: 'Update an object', extension: 'CoreServices' }, { verb: 'core/get', description: 'Search for objects', extension: 'CoreServices' } ], code: 0, message: 'Operations: 3' }
Note that the part:
{ code: 0, message: 'Everything went well' }
…is common to all the services delivered by rest.php, the other information returned depends on the requested operation.
Error codes
The error codes are available in applicationextension.inc.php, as constants of the class RestResult:
Value | Constant | Meaning |
---|---|---|
0 | OK | No issue has been encountered |
1 | UNAUTHORIZED | Missing/wrong credentials or the user does not have enough rights to perform the requested operation |
2 | MISSING_VERSION | The parameter 'version' is missing |
3 | MISSING_JSON | The parameter 'json_data' is missing |
4 | INVALID_JSON | The input structure is not a valid JSON string |
10 | UNSUPPORTED_VERSION | No operation is available for the specified version |
11 | UNKNOWN_OPERATION | The requested operation is not valid for the specified version |
12 | UNSAFE | The requested operation cannot be performed because it can cause data (integrity) loss |
100 | INTERNAL_ERROR | The operation could not be performed, see the message for troubleshooting |
Core services
The core service are generic services. They are the equivalent of the iTop Core PHP APIs: DBObject, DBObjectSearch and DBObjectSet.
Using this services, you can manipulate any kind of data, provided you know enough of the classes and their attributes.
Common input definitions
Key
A key is a mean to identify an object. This type of specification can be used to determine the target object for the operation, and it used to determine the value of a external key (or “foreign key”).
Three forms are allowed:
-
Specify the id of the object (as a number):
... key: 123
-
Specify a search query (OQL):
... key: 'SELECT UserRequest WHERE caller_name LIKE "monnet"'
-
Specify search criteria (all criteria are combined with a AND operator):
... key: { name: 'Monnet', first_name: 'Claude' }
Response
The format for the response of core/… operations is the following:
{ objects: { "objectclass::objectkey": { ... } }, code: 0, message: "Found: 1" }
Where each object is the form:
{ "code": 0, "message": "", "class": "Person", "fields": { "name": "My last name", "status": "Active", "org_id": 123, ..... ..... ..... } }
Operation: core/get
Searches for a list of objects.
Example:
Passing the following json_data
:
{ operation: 'core/get', 'class': 'Person', key: SELECT Person WHERE email LIKE '%.com' output_fields: 'friendlyname, email' }
or, using another form of “key”:
{ operation: 'core/get', 'class': 'Person', key: 1 output_fields: '*' }
Operation: core/create
Creates a new object of the given class
Passing the following json_data
:
{ operation: 'core/create', comment: 'Synchronization from blah...', 'class': 'UserRequest', output_fields: 'id, friendlyname', fields: { org_id: 'SELECT Organization WHERE name = "Demo"', caller_id: { name: 'monet', first_name: 'claude', } title: 'Houston, got a problem!', description: 'The fridge is empty' } }
… will result in a new User Request being created.
Some attributes have a special format:
-
Link sets: only indirect link sets are currently supported, see the example given above
-
Blobs: document contents (e.g. DocumentFile/file) must be in the form
{data: base64-encoded-data, mimetype: …, filename: …}
Operation: core/update
Updates one object
Passing the following json_data
:
{ operation: 'core/update', comment: 'Synchronization from blah...', 'class': 'UserRequest', key: { description: 'The fridge is empty' }, output_fields: 'friendlyname, title, contact_list', fields: { contacts_list: [ { role: 'pizza delivery', contact_id: { finalclass: 'Person', name: 'monet', first_name: 'claude' } } ] } }
… will update the User Request (identified by its description “The fridge is empty”) by setting the contact list to one contact (Claude Monet) and the role 'pizza delivery'.
key
specification matches more than one object the update will fail
with the error: Several items found (xx) for
query…
.Operation: core/apply_stimulus
Updates one object and applies a stimulus to change the state of the object
Passing the following json_data
:
{ operation: 'core/apply_stimulus', comment: 'Synchronization from blah...', 'class': 'UserRequest', key: 15, stimulus: 'ev_assign', output_fields: 'friendlyname, title, status, contact_list', fields: { team_id: 18, agent_id: 57 } }
… will update the User Request (identified by its key “15”) by
setting the agent_id
and team_id
fields
(which are mandatory for the state assigned
) and then
will apply the stimulus ev_assign
that causes the
ticket to transition from the state new
to the state
assigned
.
key
specification matches more than one object the update will fail
with the error: Several items found (xx) for
query…
.Operation: core/delete
Delete a set of objects
Passing the following json_data
:
{ operation: 'core/delete', comment: 'Cleanup for customer Demo', 'class': 'UserRequest', key: { org_id: 2 }, simulate: false }
… will delete User Request of the customer #2.
simulate: true
to
finetune your scriptEach object reported has a deletion status code and a message giving additional information. The status codes are defined in core/restservices.class.inc.php, as constants of the class RestDelete:
Value | Constant | Meaning |
---|---|---|
0 | OK | Object deleted as per the initial request |
1 | ISSUE | General issue (user rights or … ?) |
2 | AUTO_DELETE | Must be deleted to preserve database integrity |
3 | AUTO_DELETE_ISSUE | Must be deleted to preserve database integrity, but that is NOT possible |
4 | REQUEST_EXPLICITELY | Must be deleted to preserve database integrity, but this must be requested explicitely |
5 | AUTO_UPDATE | Must be updated to preserve database integrity |
6 | AUTO_UPDATE_ISSUE | Must be updated to preserve database integrity, but that is NOT possible |
Operation: core/get_related
Searches for related objects.
Given an object or a list of objects, searches for other objects that are impacting or impacted by those objects.
Passing the following json_data
:
{ operation: 'core/get_related', class: 'Server', key: 1, relation: 'impacts', depth: 4 }
… will search for all of the CIs that Server::1 does impact. The search depth is limited to 4 iterations (defaults to 20).
The results will be in the form:
{ objects: { "objectclass::objectkey": { ... } }, relations: { "origin-class::origin-key": [ { key: "destination-class::destination-key" } ] }, code: 0, message: "Scope: 1; Found: Server=4, VirtualMachine=3, Farm=1" }
Example and playground
If you have an iTop already installed (version 2.0.1+), then click here to test the REST API.
Here is the corresponding code: jsfiddle playground
How to add services
It is possible to extend the services by developping a module (or extension) that declares a class (included in your custom module) implementing the interface iRestServiceProvider.
As soon as your module is installed, your custom services will
be available and listed with
operation=list_operations
.