Schema usage examples

Referencing schemas in action.json

Every action must reference at least one schema. You can use a shared schema field for both request and response, or define requestSchema and responseSchema separately.

  • schema — Used when the request and response share the same schema, or as a fallback when no specific schemas are defined.
  • requestSchema — A schema specific to the request.
  • responseSchema — A schema specific to the response.
1{
2 "name": "getIP",
3 "protocol": "REST",
4 "method": "GET",
5 "entitypath": "{base_path}/{version}/addresses/{pathv1}",
6 "schema": "schema.json",
7 "requestSchema": "requestSchema.json",
8 "responseSchema": "responseSchema.json",
9 "timeout": 3000,
10 "sendEmpty": true,
11 "datatype": "PLAIN",
12 "headers": {},
13 "responseObjects": [
14 {
15 "type": "default",
16 "key": "",
17 "mockFile": ""
18 }
19 ]
20}

Organizing schema files in subdirectories

You can move schema files into a subdirectory within the entity folder. Update the paths in action.json to match.

1{
2 "requestSchema": "schemas/requestSchema.json",
3 "responseSchema": "schemas/responseSchema.json"
4}

No translation

Adapter Builder often generates a simple schema with translation disabled. This is easier to understand and requires less configuration. With translate set to false, all data from the external system is passed toItential Platform unchanged, and all data fromItential Platform is sent to the external system unchanged — no field name mapping occurs.

1{
2 "$id": "deviceSchema.json",
3 "type": "object",
4 "schema": "http://json-schema.org/draft-07/schema#",
5 "translate": false,
6 "dynamicfields": true,
7 "properties": {
8 "ph_request_type": {
9 "type": "string",
10 "description": "type of request (internal to adapter)",
11 "default": "getDevice",
12 "enum": ["getDevice", "createDevice"],
13 "external_name": "ph_request_type"
14 }
15 },
16 "definitions": {}
17}

Token schemas

Token requests are a common case where separate request and response schemas are useful. The request typically requires specific fields (such as username and password) that do not appear in the response. Using separate schemas lets you enforce required fields on the request without affecting response validation.

This example translates usernameuser_name and passwordpasswd on the request, and maps access_tokentoken on the response.

Because the response schema does not set dynamicfields, it defaults to false. This means only the fields explicitly defined in the response schema — in this case, token — are returned toItential Platform. All other fields in the response are dropped.

Request token schema

1{
2 "$id": "reqTokenSchema.json",
3 "type": "object",
4 "schema": "http://json-schema.org/draft-07/schema#",
5 "translate": true,
6 "dynamicfields": true,
7 "properties": {
8 "ph_request_type": {
9 "type": "string",
10 "description": "type of request (internal to adapter)",
11 "default": "getToken",
12 "enum": ["getToken", "healthcheck"],
13 "external_name": "ph_request_type"
14 },
15 "username": {
16 "type": "string",
17 "description": "username to log in with",
18 "external_name": "user_name"
19 },
20 "password": {
21 "type": "string",
22 "description": "password to log in with",
23 "external_name": "passwd"
24 }
25 },
26 "required": ["username", "password"],
27 "definitions": {}
28}

Response token schema

1{
2 "$id": "respTokenSchema.json",
3 "type": "object",
4 "$schema": "http://json-schema.org/draft-07/schema#",
5 "translate": true,
6 "properties": {
7 "ph_request_type": {
8 "type": "string",
9 "description": "type of request (internal to adapter)",
10 "default": "getToken",
11 "enum": ["getToken"],
12 "external_name": "ph_request_type"
13 },
14 "token": {
15 "type": "string",
16 "description": "the token returned from the system",
17 "external_name": "access_token"
18 }
19 },
20 "definitions": {}
21}

Dynamic fields and translation

You can define a schema that translates specific fields while passing all other fields through as-is. This is useful when you want to validate or rename certain fields but do not want to enumerate the full data structure.

Setting dynamicfields to true tells the adapter library to include any field not explicitly defined in the schema and return it unchanged. When external_name differs from the property name, the adapter translates that field in both directions — Itential Platform receives the property name, and the external system receives the external_name.

In the example below:

  • componentId inItential Platform maps to objectId in the external system.
  • deviceId uses the same name in both systems.
  • Any other fields in the data are passed through without modification.
1{
2 "$id": "sevone_alert",
3 "type": "object",
4 "schema": "http://json-schema.org/draft-07/schema#",
5 "translate": true,
6 "dynamicfields": true,
7 "properties": {
8 "ph_request_type": {
9 "external_name": "ph_request_type"
10 },
11 "deviceId": {
12 "type": "integer",
13 "description": "the id of the device this alert originated on",
14 "external_name": "deviceId"
15 },
16 "componentId": {
17 "type": "integer",
18 "description": "the id of the component this alert originated on",
19 "external_name": "objectId"
20 }
21 },
22 "definitions": {}
23}

Conditionally required fields

Calls to external systems can be costly. When required information is missing, it is more efficient for the adapter to return a validation error immediately rather than forwarding an incomplete request to the external system.

The adapter runs Ajv validation against the schema before making a call. If validation fails, the adapter returns an error without contacting the external system.

Require a field on a specific action

Use if/then with allOf to make a field required only for certain actions. This example requires origin only when ph_request_type is createAlert.

1{
2 "$id": "sevone_alert",
3 "type": "object",
4 "$schema": "http://json-schema.org/draft-07/schema#",
5 "properties": {
6 "ph_request_type": {
7 "type": "string",
8 "default": "getAlerts",
9 "enum": [
10 "getAlerts", "getAlertsFiltered", "getAlertsForDevice",
11 "getAlertsForMapConnection", "getAlertsForMapNode",
12 "createAlert", "updateAlert", "assignAlert", "ignoreAlert",
13 "clearAlert", "deleteAlert"
14 ],
15 "external_name": "ph_request_type"
16 },
17 "id": {
18 "type": "integer",
19 "description": "id of the alert",
20 "minimum": 0,
21 "maximum": 999999999999,
22 "external_name": "sys_id"
23 },
24 "origin": {
25 "type": "string",
26 "description": "where this alert originated",
27 "external_name": "origin"
28 }
29 },
30 "allOf": [
31 {
32 "if": { "properties": { "ph_request_type": { "enum": ["createAlert"] } } },
33 "then": { "required": ["origin"] }
34 }
35 ],
36 "definitions": {}
37}

Require one of several fields

You can also require at least one field from a set using oneOf. This example requires either componentId or deviceId for createAlert. If both are missing, Ajv validation fails and the adapter returns an error without making the request.

1{
2 "$id": "sevone_alert",
3 "properties": {
4 "ph_request_type": {
5 "enum": ["createAlert"],
6 "external_name": "ph_request_type"
7 },
8 "deviceId": {
9 "type": "integer",
10 "description": "the id of the device this alert originated on",
11 "external_name": "deviceId"
12 },
13 "componentId": {
14 "type": "integer",
15 "description": "the id of the component this alert originated on",
16 "external_name": "objectId"
17 }
18 },
19 "allOf": [
20 {
21 "if": { "properties": { "ph_request_type": { "enum": ["createAlert"] } } },
22 "then": {
23 "oneOf": [
24 { "required": ["deviceId"] },
25 { "required": ["componentId"] }
26 ]
27 }
28 }
29 ],
30 "definitions": {}
31}

Parse field value

Some external systems return data where a field contains a stringified JSON value — a JSON object or array that has been serialized into a string. Setting parse to true on a field tells the adapter to parse that string back into structured JSON before returning it toItential Platform.

1{
2 "$id": "reqTokenSchema.json",
3 "properties": {
4 "Data": {
5 "type": "object",
6 "properties": {
7 "Data": {
8 "type": "string",
9 "parse": true,
10 "external_name": "Data"
11 }
12 },
13 "external_name": "Data"
14 }
15 },
16 "definitions": {}
17}

Before and after

Without parse, the inner Data field is returned as a raw string:

1{
2 "ResponseType": "SUCCESS",
3 "Data": {
4 "Message": "",
5 "MessageType": "Success",
6 "returnStatus": false,
7 "RecordCount": 0,
8 "Data": "[{\"siteid\":\"XXXXX\",\"ng_rtr_pair_nm\":\"XXXXXXX\",\"ngmadrtr_id1\":\"XXXXXX\",\"ngmadrtr_id2\":\"XXXXXX\",\"ng_rtr_port\":\"2/1/5\",\"eth_term_mso\":\"XXXXX\"}]"
9 }
10}

With parse: true, the adapter parses the string and returns structured JSON:

1{
2 "ResponseType": "SUCCESS",
3 "Data": {
4 "Message": "",
5 "MessageType": "Success",
6 "returnStatus": false,
7 "RecordCount": 0,
8 "Data": [
9 {
10 "siteid": "XXXXX",
11 "ng_rtr_pair_nm": "XXXXXXX",
12 "ngmadrtr_id1": "XXXXXX",
13 "ngmadrtr_id2": "XXXXXX",
14 "ng_rtr_port": "2/1/5",
15 "eth_term_mso": "XXXXX"
16 }
17 ]
18 }
19}

Encrypt a field value

Adding an encrypt object to a field causes the adapter to encrypt that field’s value before sending it to the external system, and decrypt it when receiving the response.

Currently only AES encryption is supported. You must provide both the encryption type and the key used to encrypt and decrypt.

If you want to encrypt on the request but not decrypt on the response, use separate request and response schemas and only include the encrypt object in the request schema.

1{
2 "$id": "reqTokenSchema.json",
3 "properties": {
4 "Data": {
5 "type": "object",
6 "properties": {
7 "Data": {
8 "type": "string",
9 "encrypt": {
10 "type": "AES",
11 "key": "thisismykey"
12 },
13 "external_name": "Data"
14 }
15 },
16 "external_name": "Data"
17 }
18 },
19 "definitions": {}
20}

Before and after

Without encryption:

1{
2 "Data": {
3 "returnStatus": false,
4 "RecordCount": 0,
5 "Data": "something random"
6 }
7}

With encryption:

1{
2 "Data": {
3 "returnStatus": false,
4 "RecordCount": 0,
5 "Data": "IcNev7McG3/8MOt8QaULRzkNjDdzUKwhf6vEqPZkhog="
6 }
7}