Skip to content

Instantly share code, notes, and snippets.

@ebastien
Last active May 22, 2016 21:38
Show Gist options
  • Save ebastien/6d49802c8d34549e52ba7cc5fcddfdfa to your computer and use it in GitHub Desktop.
Save ebastien/6d49802c8d34549e52ba7cc5fcddfdfa to your computer and use it in GitHub Desktop.
Specification of a JSON media type for describing and interacting with a relational data domain.
// Specification of a JSON media type for describing and interacting
// with a relational data domain.
//
// The resources protocol is compliant with JSON API 1.0
// As described here: http://jsonapi.org/format/1.0/
//
// JSON API types:
// ---------------
// - entry : the API entry point
// - query : a relational query
// - relation : a relation variable (when name is present) or a result set
// - domain : a data type
// - body : a set of tuples sharing the same heading
// - cube : a multi-dimensional aggregation (JSONStat)
// - schema : a relational schema, i.e a collection of relation variables
//
// JSON API relationships by type:
// -------------------------------
// - (POST) entry.queries => query : create a relational query
// - (GET) entry.schemas => [schema] : get the collection of schemas
// - (GET) query.result => relation : get the result set of a query
// - (GET) relation.heading_* => domain : get the domain of an attribute name
// - (GET) relation.body => body : get the body of a relation
// - (GET) relation.cube => cube : get the cube representation of a relation
// - (GET) body.relation => relation : get the relation of a body
// - (GET) cube.relation => relation : get the relation of a cube
// - (GET) schema.relations => [relation] : get the collection of relations for a schema
// - (GET) domain.relations => [relation] : get the collection of relations referencing a domain
//
// JSON API attributes by type:
// ----------------------------
// - query.sql : string, a SQL query
// - query.status : enumeration ( "created" | "running" | "finished" | "error" )
// - relation.sql : string, a SQL query
// - relation.name : string, a SQL identifier
// - relation.description : string, a free text
// - relation.heading : array of strings, names of the attributes for a relation
// - body.tuples : array of arrays of primitive JSON values
// - cube.cube : JSONStat representation of a multi-dimensional aggregation
// - schema.name : string, a SQL identifier
// - schema.description : string, a free text
// - domain.name : string, a data type identifier
// - domain.primitive : string, a SQL data type
//
// Examples:
// ---------
// GET / HTTP/1.1
// Accept: application/vnd.api+json
// HTTP/1.1 200 OK
// Content-Type: application/vnd.api+json
{
"data": {
"type": "entry",
"id": "1",
"relationships": {
"queries": {
"links": {
"related": "http://example.com/queries"
}
},
"schemas": {
"links": {
"related": "http://example.com/schemas"
}
}
},
"links": {
"self": "http://example.com/"
}
}
}
// POST /queries HTTP/1.1
// Content-Type: application/vnd.api+json
// Accept: application/vnd.api+json
{
"data": {
"type": "query",
"attributes": {
"sql": "select sum(pax) as pax, board_city from market.bookings_ond group by board_city"
}
}
}
// HTTP/1.1 201 Created
// Location: http://example.com/queries/42
// Content-Type: application/vnd.api+json
{
"data": {
"type": "query",
"id": "42",
"attributes": {
"sql": "select sum(pax) as pax, board_city from market.bookings_ond group by board_city",
"status": "created"
},
"links": {
"self": "http://example.com/queries/42"
}
}
}
// GET /queries/42 HTTP/1.1
// Accept: application/vnd.api+json
// HTTP/1.1 200 OK
// Content-Type: application/vnd.api+json
{
"data": {
"type": "query",
"id": "42",
"attributes": {
"sql": "select sum(pax) as pax, board_city from market.bookings_ond group by board_city",
"status": "finished"
},
"relationships": {
"result": {
"links": {
"related": "http://example.com/queries/42/result"
}
}
},
"links": {
"self": "http://example.com/queries/42"
}
}
}
// GET /queries/42/result HTTP/1.1
// Accept: application/vnd.api+json
// HTTP/1.1 200 OK
// Content-Type: application/vnd.api+json
{
"data": {
"type": "relation",
"id": "42",
"attributes": {
"sql": "select sum(pax) as pax, board_city from market.bookings_ond group by board_city",
"heading": [ "pax", "board_city" ]
},
"relationships": {
"heading_pax": {
"links": {
"related": "http://example.com/queries/42/result/heading/pax"
},
"data": {
"type": "domain",
"id": "2"
}
},
"heading_board_city": {
"links": {
"related": "http://example.com/queries/42/result/heading/board_city"
},
"data": {
"type": "domain",
"id": "1"
}
},
"body": {
"links": {
"related": "http://example.com/queries/42/result/body"
}
},
"cube": {
"links": {
"related": "http://example.com/queries/42/result/cube"
}
}
},
"links": {
"self": "http://example.com/queries/42/result"
}
},
"included": [{
"type": "domain",
"id": "1",
"attributes": {
"name": "IATA_CITY",
"primitive": "VARCHAR"
},
"links": {
"self": "http://example.com/domains/1"
}
}, {
"type": "domain",
"id": "2",
"attributes": {
"name": "OND_PAX",
"primitive": "INT"
},
"links": {
"self": "http://example.com/domains/2"
}
}]
}
// GET /queries/42/result/body?q_offset=0&q_limit=10 HTTP/1.1
// Accept: application/vnd.api+json
// HTTP/1.1 200 OK
// Content-Type: application/vnd.api+json
{
"meta": {
"offset": 0,
"limit": 10,
"count": 4
},
"data": {
"type": "body",
"id": "42",
"attributes": {
"tuples": [
[ 35, "MAD" ],
[ 56, "NCE" ],
[ 1, "BOS" ],
[ 9, "MUC" ]
]
},
"relationships": {
"relation": {
"links": {
"related": "http://example.com/queries/42/result"
}
}
},
"links": {
"self": "http://example.com/queries/42/result/body"
}
}
}
// GET /queries/42/result/cube HTTP/1.1
// Accept: application/vnd.api+json
// HTTP/1.1 200 OK
// Content-Type: application/vnd.api+json
{
"data": {
"type": "cube",
"id": "42",
"attributes": {
"cube": {
"version": "2.0",
"class": "dataset",
"value": [ 35, 56, 1, 9 ],
"id" : [ "pax", "board_city" ],
"size": [ 1, 4 ],
"role": {
"metric": [ "pax" ]
},
"dimension": {
"pax": {
"category": {
"label": "pax"
}
},
"board_city": {
"category": {
"index": [ "MAD", "NCE", "BOS", "MUC" ]
}
}
}
}
},
"relationships": {
"relation": {
"links": {
"related": "http://example.com/queries/42/result"
}
}
},
"links": {
"self": "http://example.com/queries/42/result/cube"
}
}
}
// GET /schemas HTTP/1.1
// Accept: application/vnd.api+json
// HTTP/1.1 200 OK
// Content-Type: application/vnd.api+json
{
"links": {
"self": "http://example.com/schemas"
},
"data": [{
"type": "schema",
"id": "1",
"attributes": {
"name": "market",
"description": ""
},
"relationships": {
"relations": {
"links": {
"related": "http://example.com/schemas/1/relations"
}
}
},
"links": {
"self": "http://example.com/schemas/1"
}
}]
}
// GET /schemas/1/relations?fields[relation]=name HTTP/1.1
// Accept: application/vnd.api+json
// HTTP/1.1 200 OK
// Content-Type: application/vnd.api+json
{
"links": {
"self": "http://example.com/schemas/1/relations"
},
"data": [{
"type": "relation",
"id": "1",
"attributes": {
"name": "bookings_ond"
},
"links": {
"self": "http://example.com/relations/1"
}
}, {
"type": "relation",
"id": "2",
"attributes": {
"name": "searches_ond"
},
"links": {
"self": "http://example.com/relations/2"
}
}]
}
// GET /relations/1 HTTP/1.1
// Accept: application/vnd.api+json
// HTTP/1.1 200 OK
// Content-Type: application/vnd.api+json
{
"data": {
"type": "relation",
"id": "1",
"attributes": {
"name": "bookings_ond",
"description": "",
"heading": [ "board_city" ]
},
"relationships": {
"heading_board_city": {
"links": {
"related": "http://example.com/relations/1/heading/board_city"
},
"data": {
"type": "domain",
"id": "1",
}
},
"body": {
"links": {
"related": "http://example.com/relations/1/body"
}
}
},
"links": {
"self": "http://example.com/relations/1"
}
},
"included": [{
"type": "domain",
"id": "1",
"attributes": {
"name": "IATA_CITY",
"primitive": "VARCHAR"
},
"links": {
"self": "http://example.com/domains/1"
}
}]
}
// GET /domains/1 HTTP/1.1
// Accept: application/vnd.api+json
// HTTP/1.1 200 OK
// Content-Type: application/vnd.api+json
{
"data": {
"type": "domain",
"id": "1",
"attributes": {
"name": "IATA_CITY",
"primitive": "VARCHAR"
},
"relationships": {
"relations": {
"links": {
"related": "http://example.com/domains/1/relations"
}
}
},
"links": {
"self": "http://example.com/domains/1"
}
}
}
// GET /domains/1/relations?fields[relation]=name HTTP/1.1
// Accept: application/vnd.api+json
// HTTP/1.1 200 OK
// Content-Type: application/vnd.api+json
{
"links": {
"self": "http://example.com/domains/1/relations"
},
"data": [{
"type": "relation",
"id": "1",
"attributes": {
"name": "bookings_ond"
},
"links": {
"self": "http://example.com/relations/1"
}
}]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment