πŸ“˜

Enterprise Feature

Schemas allow the Platform to perform validation and filtering of other resources. For example, ensuring that an Application User can only view certain properties on a Thng. Schemas themselves are valid JSON Schema objects. See the Schema Types section below for some example schema resources.

Applying schemas to requests into the Platform is achieved by associating it with a role policy. See the Role Policies section for more information.

πŸ“˜

Notes

  • Schema resources are shared across an entire account, and so are applied to resources that match them in all projects.

  • In order to use the readOnly keyword, the jsonSchema must specify the https://evrythng.com/jsonSchema# namespace as its $schema property (see the examples below).


API Status
Beta:
/schemas
/schemas/:schemaId

SchemaDocument Data Model

.id (string, read-only)
    The ID of this resource.

.createdAt (integer, read-only)
    Timestamp when the resource was created.

.updatedAt (integer, read-only)
    Timestamp when the resource was updated.

.name (string)
    Friendly name of this resource.

.resourceType (string, one of 'thngs', 'thng_properties', 'thng_property_key', 'thng_actions')
    The type of resource this schema applies to.

.jsonSchema (object)
    The JSON Schema description of the objects this schema will 
    validate.

.product (string,null)
    The product ID filter applied to Thngs compared to this 
    schema. If `null`, the product ID filter is not applied.
{
  "type": "object",
  "description": "An object describing a schema.",
  "properties": {
    "id": {
      "type": "string",
      "description": "The ID of this resource.",
      "pattern": "^[abcdefghkmnpqrstwxyABCDEFGHKMNPQRSTUVWXY0123456789]{24}$",
      "readOnly": true
    },
    "createdAt": {
      "type": "integer",
      "description": "Timestamp when the resource was created.",
      "readOnly": true,
      "minimum": 0
    },
    "updatedAt": {
      "type": "integer",
      "description": "Timestamp when the resource was updated.",
      "readOnly": true,
      "minimum": 0
    },
    "name": {
      "type": "string",
      "description": "Friendly name of this resource."
    },
    "resourceType": {
      "type": "string",
      "description": "The type of resource this schema applies to.",
      "enum": [ "thngs", "thng_properties", "thng_property_key", "thng_actions" ]
    },
    "jsonSchema": {
      "type": "object",
      "description": "The JSON Schema description of the objects this schema will validate."
    },
    "product": {
      "description": "The product ID filter applied to Thngs compared to this schema. If `null`, the product ID filter is not applied.",
      "type": [ "string", "null" ]
    }
  }
}
{
  "id": "U3p3dbY4q9tVhswRwFy2Frfn",
  "createdAt": 1505309050669,
  "updatedAt": 1505309905737,
  "name": "Thng Properties Schema",
  "resourceType": "thng_properties",
  "jsonSchema": {
    "$schema": "http://evrythng.com/jsonSchema#",
    "type": "array",
    "items": {
      "type": "object",
      "properties": {
        "key": {
          "type": "string",
          "enum": [
            "temperature_celsius"
          ]
        },
        "value": {
          "type": "number"
        },
        "createdAt": {
          "type": "integer"
        },
        "timestamp": {
          "type": "integer"
        }
      }
    }
  },
  "product": "U3EtU2k3BD8wQpwwR6EMXgKb"
}

Schema Types

Below are some example schemas for each supported resourceType in the Platform for which a schema resource can be applied.


Thngs Schema

The thngs schema resource limits access and visibility of a Thng's properties by name when a new Thng is being created with properties using the /thngs endpoint.

When a schema is being used to filter a POST, PUT, or GET request to Thng properties, the inclusion of any given property depends on its inclusion in the schema, and whether or not it is writable. This is summarized in the table below.

Property in Schema?

POST

GET

PUT

Yes

Writable

Included in response

N/A

Yes, readOnly

Not writable

Included in response

N/A

No

Not writable

Filtered out of response

N/A

The SchemaDocument below is an example of the Thngs schema type.

{
  "name": "Thng Schema",
  "resourceType": "thngs",
  "product": "UGD9FeTcqGsYh6aawhKxApnt",
  "jsonSchema": {
    "$schema": "https://evrythng.com/jsonSchema#",
    "type": "object",
    "properties": {
      "properties": {
        "type": "object",
        "properties": {
          "temperature_celsius": {
            "type": "integer",
            "description": "The temperature of the device in celsius.",
            "minimum": -273
          },
          "wind_speed_mph": {
            "type": "integer",
            "description" : "The current wind speed in miles per hour",
            "minimum": 0
          }
        }
      }
    }
  }
}

Thng Properties Schema

Whereas a Thngs schema validates and filters Thng properties when a Thng is created with properties, a Thng properties schema is applied when a Thng's properties are created/updated with the /thngs/:thngId/properties endpoint. This is due the the fact that from this endpoint, the list of properties takes on a different format.

Like the other schema types, it is applied according to the product ID rules.

The SchemaDocument below is an example of the Thng properties schema type.

{
  "name": "Thng Properties Schema",
  "resourceType": "thng_properties",
  "product": "U3EtU2k3BD8wQpwwR6EMXgKb",
  "jsonSchema": {
    "$schema": "https://evrythng.com/jsonSchema#",
    "type": "array",
    "items": {
      "type": "object",
      "properties": {
        "key": {
          "type": "string",
          "enum": [ "temperature_celsius" ]
        },
        "value": { "type": "number" },
        "createdAt": { "type": "integer" },
        "timestamp": { "type": "integer" }
      }
    }
  }
}

Read-only in Thng Properties Schemas

In order to apply a readOnly rule in a Thng properties schema, it is required to use the JSON Schema oneOf keyword. This allows the developer to specify multiple possible enums for the key property being validated in each case readOnly is required.

An example is shown below, and has been collapsed for brevity.

{
  "name": "Thng Properties Schema With ReadOnly",
  "resourceType": "thng_properties",
  "product": "U3EtU2k3BD8wQpwwR6EMXgKb",
  "jsonSchema": {
    "$schema": "https://evrythng.com/jsonSchema#",
    "type": "array",
    "items": {
      "type": "object",
      "oneOf": [{
        "properties": {
          "key": {
            "type": "string",
            "enum": [ "temperature_celsius" ]
          },
          "value": { 
            "type": "number",
            "readOnly": true
          },
          "createdAt": { "type": "integer" },
          "timestamp": { "type": "integer" }
        }
      }, {
        "properties": {
          "key": {
            "type": "string",
            "enum": [ "wind_speed_mph" ]
          },
          "value": { "type": "number" },
          "createdAt": { "type": "integer" },
          "timestamp": { "type": "integer" }
        }
      }]
    }
  }
}

Thng Property Key Schema

Similar to the Thng properties schema type, the Thng property key schema allows validation of the value updates to a particular key on the thngs/:thngId/properties/:key endpoint. As a result, the format of this type of schema is also quite similar.

πŸ“˜

Note

Although the data returned by /thngs/:thngId/properties/:key does not include the key property, it must be included here for this type of schema to correctly apply to a particular key.

An example allowing only a particular range of integer values allowed is shown below:

{
  "name": "Thng Property Key Schema",
  "resourceType": "thng_property_key",
  "product": "U3EtU2k3BD8wQpwwR6EMXgKb",
  "jsonSchema": {
    "$schema": "https://evrythng.com/jsonSchema#",
    "type": "array",
    "items": {
      "type": "object",
      "properties": {
        "key": {
          "type": "string",
          "enum": [ "temperature_celsius" ]
        },
        "createdAt": { "type": "integer" },
        "timestamp": { "type": "integer" },
        "value": {
          "type": "number",
          "minimum": -273,
          "maximum": 100
        }
      }
    }
  }
}

Read-only in Thng Properties Schemas

In order to apply a readOnly rule in a Thng property key schema, remember to include the correct $schema namespace value as detailed at the top of this page.


Thng Actions Schema

The Thng actions schema type allows read/write filtering by the action's type property. It is applied to newly created actions on a particular Thng via the /thngs/:thngId/actions/:type endpoint.

Like the other schema types, it is applied according to the product ID rules, where the product ID in question is that of the Thng the action is created on.

The following example allows only actions of the _Activated type to be created and read by any Application User associated with it through a role policy:

{
  "name": "Actions Schema",
  "resourceType": "thng_actions",
  "product": "U3EtU2k3BD8wQpwwR6EMXgKb",
  "jsonSchema": {
    "$schema": "https://evrythng.com/jsonSchema#",
    "type": "object",
      "properties": {
        "type": {
          "type": "string",
          "enum": [ "_Activated" ]
        }
      }
    }
  }
}

Read-only in Action Schemas

The readOnly behavior and requirements for action schemas is the same as for Thng properties schemas.


Use of Product IDs

When a resource that may include the product property is involved in schema validation, the behavior depends largely on the particular product ID included in the resource itself, according to the following rule:

The authenticating Application User's role must have a policy associating them with a schema that matches the product of the concerned resource, otherwise the request will be forbidden.

The same is true if no product is specified in the payload resource - only schemas associated with the Application User's role that similarly have no product specified will be applied.

The decision making process for a given request is shown below:

550550

Create a Schema

Create a new schema resource and include the JSON Schema model it will use to validate read/write requests to Platform resources.

POST /schemas
Content-Type: application/json
Authorization: $OPERATOR_API_KEY

SchemaDocument
curl -H "Content-Type: application/json" \
  -H "Authorization: $OPERATOR_API_KEY" \
  -X POST 'https://api.evrythng.com/schemas' \
  -d '{
    "name": "Temperature Schema",
    "resourceType": "thngs",
    "jsonSchema": {
        "$schema": "https://evrythng.com/jsonSchema#",
      "type": "object",
      "properties": {
        "properties": {
          "type": "object",
          "properties": {
            "temperature_celsius": {
              "type": "integer",
              "description": "The temperature of the device in celsius.",
              "minimum": -273
            }
          }
        }
      }
    },
    "product": "U3EtU2k3BD8wQpwwR6EMXgKb"
  }'
const schema = {
  name: 'Temperature Schema',
  resourceType: 'thngs',
  jsonSchema: {
    schema: 'https://evrythng.com/jsonSchema#',
    type: 'object',
    properties: {
      properties: {
        type: 'object',
        properties: {
          temperature_celsius: {
            type: 'integer',
            description: 'The temperature of the device in celsius.',
            minimum: -273
          }
        }
      }
    }
  },
  product: 'U3EtU2k3BD8wQpwwR6EMXgKb'
};

operator.schema().create(schema).then(console.log);
HTTP/1.1 201 Created
Content-Type: application/json
Location: https://api.evrythng.com/schemas/UmVykKBSBXPaQpRwaECrCfWa

{
  "id": "UmVykKBSBXPaQpRwaECrCfWa",
  "createdAt": 1497533249389,
  "updatedAt": 1497533249389,
  "name": "Test Schema",
  "resourceType": "thngs",
  "jsonSchema": {
    "$schema": "https://evrythng.com/jsonSchema#",
    "type": "object",
    "properties": {
      "properties": {
        "type": "object",
        "properties": {
          "temperature_celsius": {
            "type": "integer",
            "description": "The temperature of the device in celsius.",
            "minimum": -273
          }
        }
      }
    }
  },
  "product": "U3EtU2k3BD8wQpwwR6EMXgKb"
}

Read all Schemas

Read all schemas in an account. The result may be paginated if there are more than 30 items.

GET /schemas
Authorization: $OPERATOR_API_KEY
curl -H "Authorization: $OPERATOR_API_KEY" \
  -X GET 'https://api.evrythng.com/schemas'
operator.schema().read().then(console.log);
HTTP/1.1 200 OK
Content-Type: application/json

[
  {
    "id": "U3pQqs3MqQQBE8wwREADKtmn",
    "createdAt": 1505742492262,
    "updatedAt": 1505742492262,
    "name": "Temperature Schema",
    "resourceType": "thngs",
    "jsonSchema": {
      "$schema": "https://evrythng.com/jsonSchema#",
      "type": "object",
      "properties": {
        "properties": {
          "type": "object",
          "properties": {
            "temperature_celsius": {
              "type": "integer",
              "description": "The temperature of the device in celsius.",
              "minimum": -273
            }
          }
        }
      }
    },
    "product": "UmVE9h7dVXPwQpwaRgfXKGnq"
  }
]

Read a Schema

GET /schemas/:schemaId
Authorization: $OPERATOR_API_KEY
curl -H "Authorization: $OPERATOR_API_KEY" \
  -X GET 'https://api.evrythng.com/schemas/UmVTmk3NVXsatpaRaEfrCCfe'
const schemaId = 'UmVTmk3NVXsatpaRaEfrCCfe';

operator.schema(schemaId).read().then(console.log);
HTTP/1.1 200 OK
Content-Type: application/json

{
  "id": "U3pQqs3MqQQBE8wwREADKtmn",
  "createdAt": 1505742492262,
  "updatedAt": 1505742492262,
  "name": "Temperature Schema",
  "resourceType": "thngs",
  "jsonSchema": {
    "$schema": "https://evrythng.com/jsonSchema#",
    "type": "object",
    "properties": {
      "properties": {
        "type": "object",
        "properties": {
          "temperature_celsius": {
            "type": "integer",
            "description": "The temperature of the device in celsius.",
            "minimum": -273
          }
        }
      }
    }
  },
  "product": "UmVE9h7dVXPwQpwaRgfXKGnq"
}

Update a Schema

PUT /schemas/:schemaId
Content-Type: application/json
Authorization: $OPERATOR_API_KEY

SchemaDocument (subset)
curl -H "Content-Type: application/json" \
  -H "Authorization: $OPERATOR_API_KEY" \
  -X PUT 'https://api.evrythng.com/schemas/U3pQqs3MqQQBE8wwREADKtmn' \
  -d '{
    "name": "Updated Schema"
  }'
const schemaId = 'UmVTmk3NVXsatpaRaEfrCCfe';

const update = {
  name: 'Updated Schema'
};

operator.schema(schemaId).update(update).then(console.log);
HTTP/1.1 200 OK
Content-Type: application/json

{
  "id": "U3pQqs3MqQQBE8wwREADKtmn",
  "createdAt": 1505742492262,
  "updatedAt": 1505742492262,
  "name": "Updated Schema",
  "resourceType": "thngs",
  "jsonSchema": {
    "$schema": "https://evrythng.com/jsonSchema#",
    "type": "object",
    "properties": {
      "properties": {
        "type": "object",
        "properties": {
          "temperature_celsius": {
            "type": "integer",
            "description": "The temperature of the device in celsius.",
            "minimum": -273
          }
        }
      }
    }
  },
  "product": "UmVE9h7dVXPwQpwaRgfXKGnq"
}

Delete a Schema

DELETE /schemas/:schemaId
Authorization: $OPERATOR_API_KEY
curl -H "Authorization: $OPERATOR_API_KEY" \
  -X DELETE 'https://api.evrythng.com/schemas/U3pQqs3MqQQBE8wwREADKtmn'
const schemaId = 'U3pQqs3MqQQBE8wwREADKtmn';

operator.schema(schemaId).delete().then(() => console.log('Deleted'));
HTTP/1.1 204 No Content