Skip to content

Latest commit

 

History

History
383 lines (282 loc) · 13.9 KB

index.md

File metadata and controls

383 lines (282 loc) · 13.9 KB

Table of Contents

API Description

The SIS API allows you to interact with SIS data using anything that can issue an HTTP request and parse JSON. The API allows clients to do a variety of operations including:

  • CRUD object definitions. SIS refers to these as schemas and map to concepts like DB Tables or object classes.
  • CRUD instances of objects of a schema. These are referred to as entities in SIS.
  • Register for notifications when any SIS object is created, modified, or deleted. In SIS terms, these are called hooks.
  • Retrieve the state of a SIS object at a particular moment in time.
  • Control access to objects and ensure the right users can manage them.
  • Access the API from any website using a browser that supports CORS.

Role based access control

Read access is provided to any client that can access the REST API endpoint. This is by design and is meant to encourage collaboration among all users.

All objects in SIS have a set of owners which govern the access users have in SIS. Please consult the documentation on Role Based Access Control for more information.

HTTP Headers

Response Headers

  • Content-Type - set on all responses to application/json.
  • x-total-count - only on responses that return pages. Indicates the total number of items in the list.

Request Headers

  • Content-Type - set on all PUT and POST requests.
  • Methods that require authentication require one of two headers:
    • Authorization - for retrieving an API token via credentials.
    • x-auth-token - contains the API token

Errors

All errors returned by SIS are JSON objects that look like:

{
    error: "Error message"
    code: <integer code>
}

The code field is currently a placeholder and not very informative.

Additionally, the HTTP status is set appropriately. The following statuses are used:

  • 400 - client issued bad request
  • 401 - unauthorized
  • 404 - resource not found
  • 500 - internal error

SIS Resources

The SIS API allows clients to manage a number of resources:

  • schemas - manage types of entities in SIS
  • entities - manage objects that belong to a schema
  • hooks - manage web hooks that trigger on object events
  • hiera - manage generic JSON data that can be fetched using Hiera HTTP

Additionally, the API provides a means to view commits for resources in SIS via the Commits API

All SIS objects can be referenced by some id that is unique within their type.

SIS Fields

As of the v1.1 API, the following fields reside on the top level object and are SIS internal fields.

  • _id - persistent ID of the object - ObjectId
  • _v - version of the object, primarily used by mongoose - Number
  • _sis - a subdocument with additional metadata and state. It contains:
    • _created_at - a UTC timestamp of when the object was created - Number
    • _created_by - username of entity creator - String
    • _updated_at - a UTC timestamp of when the object was last updated - Number
    • _updated_by - username of last user who updated the entity - String
    • locked - indicates whether the object can be deleted - Boolean
    • immutable - indicates whether the object can be changed - Boolean
    • tags - an indexed array of Strings for arbitrary tagging - [String]
    • owner - a list of groups that can modify or remove the object.

Below is an example object meant to illustrate the internal fields, especially the _sis subdocument.

{
    // SIS fields
    "_id" : "some_id",
    "_v" : 0,
    "_sis" : {
        // immutable SIS metadata fields start with _
        "_created_at" : 1,
        "_updated_at" : 2,
        "_updated_by" : "user2",
        "_created_by" : "user1",
        // all mutable fields below
        "locked" : false,
        "immutable" : true,
        "tags" : ["tag1"],
        "owner" : ["sis_documentation"]
    },

    // entity fields
    "name" : "some_name",
    "number" : 10,
    "bool" : false
    // etc..
}

When using the V1.1 API, to change any SIS metadata send the _sis object in the request body. For instance, to change the tags of of the above object, send the above request body in the PUT request:

{
    "_sis" : {
        "tags" : ["sis_documentation", "another_tag"]
    }
}

In other words, it looks like any other update request.

Additionally, the v1.1 API no longer requires owner to be present on POST requests for non super users. The _sis.owner will be automatically inferred from the roles of the user.

Endpoint API

All SIS resources expose an HTTP base endpoint. The endpoint paths are versioned. For instance, the base endpoint for the version 1 schemas API is /api/v1/schemas. In version 1.1, the base endpoint is /api/v1.1/schemas. The /api/v1/ endpoints are deprecated and will be removed in a future release. Please use /api/v1.1/ for new applications.

The following HTTP methods are common to all endpoints:

  • GET - retrieve a list (page) of resources. See List retrieval options for options.
  • GET / - retrieve a single resource by id.
  • POST - create a new resource, or multiple resources via bulk insert.
  • PUT / - update a resource with the specified id. CAS operations are also supported.
    • Note this operation will fail if _sis.immutable is true for the resource.
    • Upsert is also
  • DELETE - delete multiple resources via bulk delete.
  • DELETE / - delete a single resource with the specified id.
    • Note this operation will fail if _sis.locked is true for the resource.

Endpoints paths and id fields are documented in the resource specific documentation.

List retrieval options

All GET requests that retrieve a list of objects support a variety of options specified via query parameters.

All list responses contain the x-total-count header which contains the total number of resources that match the search filter.

Pagination

All lists retrieved are actually pages. The following query parameters are used in pagination:

  • limit - the maximum number of items to fetch in a single call; defaults to MAX_RESULTS defined in util/types/constants.js, currently 10,000.
  • offset - the number of items to skip before fetching. 0 based.

For instance, GET /api/v1.1/schemas?limit=3&offset=4 retrieves the schemas at positions 3, 4, and 5.

Field selection

Field selection is done by passing a comma separated list of field names in the fields parameter. Dot notation may be used to specify the field of an embedded object.

For instance:

GET /api/v1.1/schemas?fields=name,definition.name returns a list of schemas where the objects only contain the name, _id, and the name field of the definition. If name is not specified in the schema definition, the other two fields are still returned.

Note that _id is always returned.

Sorting

To sort objects by a particular field, pass in the field name via the sort query parameter.

For instance:

  • GET /api/v1.1/schemas?sort=name returns schemas sorted by name in ascending order.
  • GET /api/v1.1/schemas?sort=-name returns schemas sorted by name in descending order.

Search

Search / filtering is done by passing a URL encoded JSON object in the q parameter. The object looks like a MongoDB query document.

For instance:

/api/v1.1/schemas?q={"_sis.owner":"SIS"} returns a list of schemas where "SIS" is an owner.

Joins

Fields in the query objects may also apply to referenced objects as if they were a nested document.

For instance, consider the following schema definitions (only name and definition provided):

{
    "name" : "entity_1",
    "definition" : {
        "some_number" : "Number",
        "some_string" : "String"
    }
}

{
    "name" : "entity_2",
    "definition" : {
        "some_other_number" : "Number",
        "some_other_string" : "String",
        // reference to entity_1 defined above
        "entity_1" : { "type" : "ObjectId", "ref" : "entity_1" }
    }
}

Then the following request returns a list of entity_2 objects that reference an entity_1 object with a some_number field greater than 10:

GET /api/v1.1/entities/entity_2?q={"entity_1.some_number" : { "$gt" : 10 }}

Bulk Operations

All supported bulk operations return the following response with a 200 status.

{
    success : [< objects >],
    errors : [< error objects >]
}

Error objects in the errors array look like the following:

{
    err : [ status_code, error_body ],
    value : < object that caused the error >
}

Objects in the success array have the same format as the single operation variant. Hooks are dispatched for all items in the success array as well.

Bulk Insert

POST endpoints that support bulk insert also accept an array of objects instead of a single one. When a non-empty array is sent, the following response is sent with a 200 response code.

An optional all_or_none URL query parameter can be added to the request and has a boolean value. When true, any errors will prevent any inserts from occurring and the success array will return empty.

As an example, to insert 3 items in the sample schema defined in Schema Objects, issue POST /api/v1.1/entities/sample with the body

[
    {
        "stringField":    "sampleString",
        "numberField" : 20,
        "uniqueNumberField" : 1,
        "requiredField" : "required string",
        "anythingField" : {
            "anything" : "goes",
            "in" : ["this", "field"]
         },
        "_sis" : { "owner" : ["SISG1"] }
    },
    {
        "stringField":    "sampleString2",
        "numberField" : 21,
        "uniqueNumberField" : 2,
        "requiredField" : "required string",
        "anythingField" : {
            "anything" : "goes",
            "in" : ["this", "field"]
         },
        "_sis" : { "owner" : ["SISG1"] }
    },
    {
        "stringField":    "sampleString3",
        "numberField" : 22,
        "uniqueNumberField" : 3,
        "requiredField" : "required string",
        "anythingField" : {
            "anything" : "goes",
            "in" : ["this", "field"]
         },
        "_sis" : { "owner" : ["SISG1"] }
    }
]

Note that SIS will reject all requests where the payload exceeds 1MB

Bulk Delete

Bulk deletion requires a query with the same query format as those supplied in search. Note that the DELETE is issued against the Endpoint base URL.

A query must be present, otherwise a 400 is returned. Any errors that occur to some items do not prevent other objects from being deleted.

For instance, to delete all entities in the sample schema where the numberField is less than 20, issue the following request:

DELETE /api/v1.1/entities/sample?q={"numberField" : {"$lt" : 20}}

CAS Support

CAS updates are supported on single object update calls only (i.e. PUT /api/v1.1/schemas/my_schema or PUT /api/v1.1/entities/my_schema/the_object_id). CAS updates ensure that an update is applied atomically only if the object meets certain criteria.

To issue a CAS update operation, add the cas query parameter with the value being a query object representing the conditions the object must meet.

For instance, consider the following sample object that exists in SIS and can be retrieved via GET /api/v1.1/entities/sample/some_object_id:

{
    "_id" : "some_object_id",
    "_updated_at" : 1404142960187,
    "stringField":    "some string",
    "numberField" : 100,
    "uniqueNumberField" : 1001,
    "requiredField" : "r",
    "anythingField" : { },
    "_sis" : { "owner" : ["SISG1"] }
    // some other SIS fields omitted
}

To update the object and set numberField to 101 only if numberField is 100, issue the following request:

PUT /api/v1.1/entities/sample/some_object_id?cas={"numberField":100} with the following body:

{
    "numberField" : 101
}

Issuing the same call again will result in an error with status 400.

To further enhance the update condition, consider adding the _updated_at field to the condition. The CAS condition then becomes: {"numberField" : 100 , "_updated_at" : 1404142960187}.

Note that it may not be sufficient to use only _updated_at as multiple writes may succeed within a millisecond. The proper fields for the condition are left up to the application.

Upserts

By default, SIS Endpoints support upsert on all PUT requests that take an ID. Upsert operations create or modify an object depending on if an object exists with the specified ID.

The entities API supports upsert only if the schema has id_field set to something other than _id.

The following request upserts a schema with name "upserted_schema":

PUT /api/v1.1/schemas/upserted_schema?upsert=true with the body containing the schema JSON.

Data Sharing and Organization

There are many ways to manage data in SIS and organize it for collaboration and isolation. Please see Organizing Data in SIS.