API Guide

This document provides a comprehensive overview of the REST API interactions enabled via the yang-express middleware framework built on Express.js.

While much care has been taken to auto-generate the API endpoint routing to conform as closely as possible to RESTCONF, there are many key deviations and currently no plans to adapt the default REST API generator to be RESTCONF compatible.

Instead, the REST API generated by the YANG data models are much more closely aligned to conventional REST APIs developed for use in the web application development community. Also, there's currently no support for XML but instead follows the YANGJSON specifications for representing configuration data in JSON.

Below is the complete snippet from server.coffee demonstrating how to use yang-express middleware framework to fire up a web server instance capable of serving up the YANG model-driven CORD reference implementation.

yang = require('yang-js')

require('yang-express').run {

  port: 5050
  models: [
    yang.require 'cord-core'
    yang.require 'xos-core'
  ]
  data: require '../../sample-data.json'

}

Yes, it's really that simple.

CORD API Reference

The following section presents various CRUD operations that are runtime generated from the cord-core YANG module. These operations are essentially interpreted and served while running depending on the YANG runtime model and the configuration data state at any given point in time. Basically, it's performing adaptive API routing and rendering.

View Subscribers

Valid URIs:

  • GET /cord-core:subscriber
  • GET /cord:subscriber
  • GET /subscriber

Request:

$ curl localhost:5050/cord:subscriber

Response:

{
  "cord-core:subscriber": [
    {
      "id": 1,
      "service-specific-id": 1000,
      "humanReadableName": "cordSubscriber-1",
      "status": "enabled",
      "demo": false,
      "uplink-speed": 1000000000,
      "downlink-speed": 1000000000,
      "kind": "cord-subscriber",
      "related": {}
    },
    {
      "id": 2,
      "service-specific-id": 1001,
      "humanReadableName": "cordSubscriber-2",
      "status": "enabled",
      "demo": false,
      "uplink-speed": 1000000000,
      "downlink-speed": 1000000000,
      "kind": "cord-subscriber",
      "related": {}
    }
  ]
}

View Details for a Subscriber

Valid URIs:

  • GET /cord-core:subscriber/:id
  • GET /cord:subscriber/:id
  • GET /subscriber/:id

Request:

$ curl localhost:5050/cord:subscriber/1

Response:

{
  "cord-core:subscriber": {
    "id": 1,
    "service-specific-id": 1000,
    "humanReadableName": "cordSubscriber-1",
    "status": "enabled",
    "demo": false,
    "uplink-speed": 1000000000,
    "downlink-speed": 1000000000,
    "kind": "cord-subscriber",
    "related": {}
  }
}

Update a Subscriber

Valid URIs:

  • PUT /cord-core:subscriber/:id
  • PUT /cord:subscriber/:id
  • PUT /subscriber/:id

Request:

$ curl -X PUT localhost:5050/cord:subscriber/1 -H 'content-type: application/json' -d '{ "id": 10, "status": "suspended", "services": { "cdn": { "enabled": true } } }'

Response:

{
  "cord-core:subscriber": {
    "id": 10,
    "service-specific-id": 1000,
    "humanReadableName": "cordSubscriber-10",
    "status": "suspended",
    "demo": false,
    "uplink-speed": 1000000000,
    "downlink-speed": 1000000000,
    "kind": "cord-subscriber",
    "related": {},
    "services": {
      "cdn": {
        "enabled": true
      }
    }
  }
}

This operation highlights an interesting scenario related to invisible YANG schema properties. Any configuration tree segment that does not contain any data behave as shadow properties, which basically means they spring to life once valid data gets placed into it but stays invisible otherwise.

DELETE a Subscriber

Valid URIs:

  • DELETE /cord-core:subscriber/:id
  • DELETE /cord:subscriber/:id
  • DELETE /subscriber/:id

Request:

$ curl -X DELETE localhost:5050/cord:subscriber/2

Response:

HTTP 204

Create a new Subscriber

Valid URIs:

  • POST /cord-core:subscriber
  • POST /cord:subscriber
  • POST /subscriber

Request:

$ curl -X POST localhost:5050/cord:subscriber -H 'content-type: application/json' -d '{ "id": 12, "service-specific-id": 2020, "demo": true }'

Response:

{
  "cord-core:subscriber": [
    {
      "id": 12,
      "service-specific-id": 2020,
      "demo": true,
      "humanReadableName": "cordSubscriber-12",
      "status": "enabled",
      "uplink-speed": 1000000000,
      "downlink-speed": 1000000000,
      "kind": "cord-subscriber",
      "related": {}
    }
  ]
}

The POST operation is only available on YANG `list` schema elements as
well as `rpc` and `action` elements. This operation also accepts
**bulk create** request data by supplying a JSON array.

### Additional Endpoints

There are a number of additional operational endpoints dynamically
rendered for the YANG data model. Since YANG is a **hierarchical**
data modeling language, you can have deeply nested structures of
various `containers` and `lists`. The appropriate CRUD operations can
take effect as deep into the endpoint entity hierarchy according to
the YANG schema.

Here's a sample list of various URIs for the Subscriber model:

| GET/POST       | /cord:subscriber |
| GET/PUT/DELETE | /cord:subscriber/:id |
| GET/PUT        | /cord:subscriber/:id/services/cdn |
| GET/POST       | /cord:subscriber/:id/device |
| GET/PUT/DELETE | /cord:subscriber/:id/device/:mac |
| GET/PUT        | /cord:subscriber/:id/device/:mac/features |

### Validations

Whenever POST/PUT requests are transacted, the incoming data is YANG
schema validated to ensure fitness of the data before it gets applied
into the runtime configuration data state.

For example, if you tried to POST /cord:subscriber without the
`mandatory` *id* and *service-specific-id* properties, it will
generate an error and reject the request.

Also, if you tried to PUT using data values that does not conform to
the underlying YANG schema for that data element, it will generate an
error and reject the requst.

Invalid Request:
```bash
$ curl -X PUT localhost:5050/cord:subscriber/10 -H 'content-type: application/json' -d '{ "status": false }'

Error Response:

{
  "error": {
    "message": "[enumeration] type violation for 'false' on enabled,suspended,delinquent,violation"
  }
}

For additional information on comprehensive validation enforcement support, please refer to yang-js YANG compliance status report.