How to use the Daybed API¶
Daybed is a REST interface you can use to create model definitions, edit them and publish data that complies to these models.
Let’s say you want to have a Daybed-managed todo list. Follow the steps and you will have a grasp of how Daybed works.
To simplify API calls, you can use httpie which performs HTTP requests easily.
All examples in this section are using httpie against a local Daybed server running on port 8000.
Daybed uses Hawk, so to run the following example, you’ll need to install the requests-hawk module.
Listing supported fields¶
Daybed supports several field types to build your model definition. All details are given in the dedicated documentation section.
You can also get a list of these fields and their parameters programmatically, on the /fields endpoint:
http GET http://localhost:8000/v1/fields --verbose --json
Authentication¶
You need to be authenticated to be able to run most of the commands. In order to get authenticated, the first thing to do is to get some credentials from Daybed.
In order to get yours, you need to send a POST
request:
http POST http://localhost:8000/v1/tokens
HTTP/1.1 201 Created
Content-Length: 273
Content-Type: application/json; charset=UTF-8
Date: Thu, 24 Jul 2014 16:25:49 GMT
Server: waitress
{
"credentials": {
"algorithm": "sha256",
"id": "e0394574578356252e2033b829b90291e2ff1f33ccbcbcec777485f3a5a10bca",
"key": "416aa1287121218feeb9b751a9614959a1c95fd09aba5959bab7c484dcd1b198"
},
"token": "ad37fc395b7ba83eb496849f6db022fbb316fa11081491b5f00dfae5b0b1cd22"
}
In your next requests, you can either :
- use the
token
, and rely on a Hawk library to wrap everything (recommended); - use the
credentials
pair of id and key, and build the HawkAuthorization
header yourself (or probably via ``hawk.js``).
If you want to get always the same token for a given user, you can access the endpoint using Basic Auth Authorization scheme:
http POST localhost:8000/v1/tokens --auth admin:password -v
POST /v1/tokens HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate, compress
Authorization: Basic YWRtaW46cGFzc3dvcmQ=
Content-Length: 0
Host: localhost:8000
User-Agent: HTTPie/0.8.0
HTTP/1.1 201 Created
Content-Length: 266
Content-Type: application/json; charset=UTF-8
Date: Fri, 07 Nov 2014 15:09:01 GMT
Server: waitress
{
"credentials": {
"algorithm": "sha256",
"id": "371ef18f8a054e5c9fb0961cc5b81006080e9ad22078d30b3727c7c32843579f",
"key": "87e72a8e5dcaf8b4be00b8729462814da3d438ce2fd8b6efee335db722d8369d"
},
"token": "9f19de0237c9bd59f803de1785f7aea4e3499b6929df3428e1b415fed81f797a"
}
In that case you will get a 201 Created on the creation time and then a 200 each time you ask for the same token.
Model management¶
PUT and POST /v1/models
You can create models without being authenticated, since model creation is allowed to everyone by default.
When you are authenticated, all the objects you create will be associated to your credentials id.
First, you put a definition under the name “todo” using a PUT request on /models:
http PUT http://localhost:8000/v1/models/todo
Use the token
as the auth
value, as expected by the requests-hawk
library.
echo '{"definition":
{
"title": "todo",
"description": "A list of my stuff to do",
"fields": [
{
"name": "item",
"type": "string",
"label": "The item"
},
{
"name": "status",
"type": "enum",
"choices": [
"done",
"todo"
],
"label": "is it done or not"
}
]
}
}' > definition
http PUT http://localhost:8000/v1/models/todo @definition \
--verbose \
--auth-type=hawk \
--auth='ad37fc395b7ba83eb496849f6db022fbb316fa11081491b5f00dfae5b0b1cd22:'
And you receive the model id back
HTTP/1.1 200 OK
Content-Length: 14
Content-Type: application/json; charset=UTF-8
Date: Thu, 24 Jul 2014 18:35:10 GMT
Server: waitress
{
"id": "todo"
}
Since the token was used, the new model was associated to your id, and you are the only one to get read and write permissions. Of course, the model permissions can be changed later.
Note
In case you don’t want to define a name yourself for your model, you can do the exact same request, replacing the PUT http method by a POST. A random name will be generated.
The definition properties are:
- title: The model title
- description: The model description
- fields: The model fields’ list. See fields documentation
- extra: An optional property to store custom data to your model.
GET /models
Returns the list of models where you have the permission to read the definition:
http GET http://localhost:8000/v1/models --verbose \
--auth-type=hawk \
--auth='ad37fc395b7ba83eb496849f6db022fbb316fa11081491b5f00dfae5b0b1cd22:'
GET /v1/models HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Authorization: Hawk mac="3NXv...=", hash="B0we...=", id="36...0", ts="1407166852", nonce="tQlJHv"
Host: localhost:8000
User-Agent: HTTPie/0.8.0
HTTP/1.1 200 OK
Content-Length: 202
Content-Type: application/json; charset=UTF-8
Date: Mon, 04 Aug 2014 15:40:52 GMT
Server: waitress
{
"models": [
{
"description": "A list of my stuff to do.",
"id": "todo",
"title": "Todo"
}
]
}
GET /v1/models/{modelname}
You can now get your models back:
http GET http://localhost:8000/v1/models/todo \
--verbose \
--auth-type=hawk \
--auth='ad37fc395b7ba83eb496849f6db022fbb316fa11081491b5f00dfae5b0b1cd22:'
GET /v1/models/todo HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Authorization: Hawk mac="CEhSQuh8tqGY8RbdrnMvGyIRJBDmdxJeu2/HIRB0pbQ=", hash="B0weSUXsMcb5UhL41FZbrUJCAotzSI3HawE1NPLRUz8=", id="e03945
74578356252e2033b829b90291e2ff1f33ccbcbcec777485f3a5a10bca", ts="1406228025", nonce="4sEpMQ"
Host: localhost:8000
User-Agent: HTTPie/0.8.0
HTTP/1.1 200 OK
Content-Length: 1330
Content-Type: application/json; charset=UTF-8
Date: Thu, 24 Jul 2014 18:53:45 GMT
Server: waitress
{
"permissions": {
"e0394574578356252e2033b829b90291e2ff1f33ccbcbcec777485f3a5a10bca": [
'create_record',
'delete_all_records',
'delete_model',
'delete_own_records',
'read_permissions',
'read_all_records',
'read_definition',
'read_own_records',
'update_permissions',
'update_all_records',
'update_definition',
'update_own_records',
]
},
"definition": [
{
"description": "A list of my stuff to do",
"fields": [
{
"label": "The item",
"name": "item",
"type": "string"
},
{
"choices": [
"done",
"todo"
],
"label": "is it done or not",
"name": "status",
"type": "enum"
}
],
"title": "todo"
}
],
"records": []
}
Note
You will get a 401 - Unauthorized
response if you don’t have the
permission to read the model definition.
Pushing records¶
POST /v1/models/{modelname}/records
PUT /v1/models/{modelname}/records/{id}
Now that you’ve defined the schema, you may want to push some real record there:
http POST http://localhost:8000/v1/models/todo/records item="work on daybed" status="done" \
--verbose \
--auth-type=hawk \
--auth='ad37fc395b7ba83eb496849f6db022fbb316fa11081491b5f00dfae5b0b1cd22:'
POST /v1/models/todo/records HTTP/1.1
Accept: application/json
Accept-Encoding: gzip, deflate
Authorization: Hawk mac="4Sly1HVkkKsRk43dHOLw/e/AmWeoDEe9ZbVu9cugzg0=", hash="KE3ivKqZxHPTg1yzUAJHOu/PYiYWvEoh3SZxzYshikw=", id="e03945
74578356252e2033b829b90291e2ff1f33ccbcbcec777485f3a5a10bca", ts="1406228375", nonce="T2NP4V"
Content-Length: 44
Content-Type: application/json; charset=utf-8
Host: localhost:8000
User-Agent: HTTPie/0.8.0
{
"item": "work on daybed",
"status": "done"
}
HTTP/1.1 201 Created
Content-Length: 42
Content-Type: application/json; charset=UTF-8
Date: Thu, 24 Jul 2014 18:59:35 GMT
Location: http://localhost:8000/v1/models/todo/records/ebc9f07c8faa4969a76f46b8c514fac6
Server: waitress
{
"id": "ebc9f07c8faa4969a76f46b8c514fac6"
}
The server sends us back the id of the newly created record.
Note
You can also only validate the data your are sending, by setting the
Validate-Only
header, which will prevent storing it as a record.
GET /v1/models/{modelname}/records
Using the GET method, you can get back all the records you have created:
http GET http://localhost:8000/v1/models/todo/records \
--json \
--verbose \
--auth-type=hawk \
--auth='ad37fc395b7ba83eb496849f6db022fbb316fa11081491b5f00dfae5b0b1cd22:'
GET /v1/models/todo/records HTTP/1.1 [5/4051]
Accept: application/json
Accept-Encoding: gzip, deflate
Authorization: Hawk mac="OQ9PYGfLhE7L0TPHFpYteHI0j3PBnKgEjyYjMQXMsaM=", hash="NVuBm+XMyya3Tq4EhpZ0cQWjVUyIA8sKnySkKDOIM4M=", id="e0394574578356252e2033b829b90291e2ff1f33ccbcbcec777485f3a5a10bca", ts="1406232484", nonce="_m0VvY"
Content-Type: application/json; charset=utf-8
Host: localhost:8000
User-Agent: HTTPie/0.8.0
HTTP/1.1 200 OK
Content-Length: 151
Content-Type: application/json; charset=UTF-8
Date: Thu, 24 Jul 2014 20:08:04 GMT
Server: waitress
{
"records": [
{
"item": "work on daybed",
"status": "done"
},
]
}
Get back a definition¶
GET /v1/models/{modelname}/definition
http GET http://localhost:8000/v1/models/todo/definition \
--verbose \
--auth-type=hawk \
--auth='504fd8148d7cdca10baa3c5208b63dc9e13cad1387222550950810a7bdd72d2c:'
GET /v1/models/todo/definition HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Authorization: Hawk mac="k9edIqpoz7cSUJQTroXgM4vgDoZb2Z2KO2u40QCbtYk=", hash="B0weSUXsMcb5UhL41FZbrUJCAotzSI3HawE1NPLRUz8=", id="220a1c4212d8f005f0f56191c5a91f8fe266282d38b042e6b35cad8034f22871", ts="1406645426", nonce="meNBWv"
Host: localhost:8000
User-Agent: HTTPie/0.8.0
HTTP/1.1 200 OK
Content-Length: 224
Content-Type: application/json; charset=UTF-8
Date: Tue, 29 Jul 2014 14:50:26 GMT
Server: waitress
{
"description": "A list of my stuff to do",
"fields": [
{
"label": "The item",
"name": "item",
"type": "string"
},
{
"choices": [
"done",
"todo"
],
"label": "is it done or not",
"name": "status",
"type": "enum"
}
],
"title": "todo"
}
Get back the model permissions¶
GET /v1/models/{modelname}/permissions
http GET http://localhost:8000/v1/models/todo/permissions \
--verbose \
--auth-type=hawk \
--auth='504fd8148d7cdca10baa3c5208b63dc9e13cad1387222550950810a7bdd72d2c:'
GET /v1/models/todo/permissions HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Authorization: Hawk mac="G8PntYqGA0DiP4EC0qvvr70tmCZrsVBdTTTBq9ZeKYg=", hash="B0weSUXsMcb5UhL41FZbrUJCAotzSI3HawE1NPLRUz8=", id="220a1c4212d8f005f0f56191c5a91f8fe266282d38b042e6b35cad8034f22871", ts="1406645480", nonce="4D0z9n"
Host: localhost:8000
User-Agent: HTTPie/0.8.0
HTTP/1.1 200 OK
Content-Length: 293
Content-Type: application/json; charset=UTF-8
Date: Tue, 29 Jul 2014 14:51:20 GMT
Server: waitress
{
"220a1c4212d8f005f0f56191c5a91f8fe266282d38b042e6b35cad8034f22871": [
"create_record",
"delete_all_records",
"delete_model",
"delete_own_records",
"read_all_records",
"read_definition",
"read_own_records",
"read_permissions",
"update_all_records",
"update_definition",
"update_own_records"
"update_permissions",
]
}
Change model permissions¶
As described in the dedicated section about permissions, you can add or remove permissions from models.
For example, you may want to give the permission to read everyone’s records to anonymous users (i.e. Everyone).
Using a PATCH
request, existing permissions configuration is not overwritten
completely :
PATCH /v1/models/{modelname}/permissions
echo '{"Everyone": ["+read_all_records"]}' | http PATCH http://localhost:8000/v1/models/todo/permissions \
--json \
--verbose \
--auth-type=hawk \
--auth='504fd8148d7cdca10baa3c5208b63dc9e13cad1387222550950810a7bdd72d2c:'
PATCH /v1/models/todo/permissions HTTP/1.1
Accept: application/json
Accept-Encoding: gzip, deflate
Authorization: Hawk mac="CWT9du2YxOoTb2i5d15bBTA4XiSYY/99ybh6g7welLM=", hash="Nt8m2h1nc5lVUItOobOliVj6hul0FYXmwpEmkjyp+WU=", id="220a1c4212d8f005f0f56191c5a91f8fe266282d38b042e6b35cad8034f22871", ts="1406645940", nonce="2il3kl"
Content-Length: 34
Content-Type: application/json; charset=utf-8
Host: localhost:8000
User-Agent: HTTPie/0.8.0
{
"Everyone": [
"+read_all_records"
]
}
HTTP/1.1 200 OK
Content-Length: 333
Content-Type: application/json; charset=UTF-8
Date: Tue, 29 Jul 2014 14:59:00 GMT
Server: waitress
{
"220a1c4212d8f005f0f56191c5a91f8fe266282d38b042e6b35cad8034f22871": [
"create_record",
"delete_all_records",
"delete_model",
"delete_own_records",
"read_all_records",
"read_definition",
"read_own_records",
"read_permissions",
"update_all_records",
"update_definition",
"update_own_records"
"update_permissions",
],
"system.Everyone": [
"read_all_records"
]
}
If you add an unknown permission or modify the permissions of an unknown id, you will get an error.
Reset permissions¶
Using a PUT
request, existing permissions will be completely erased and
replaced by the new ones.
Using the ALL
shortcut, you can grant all available permissions.
PUT /v1/models/{modelname}/permissions
echo '{"Everyone": ["read_definition"], "Authenticated": ["ALL"]}' | http PUT http://localhost:8000/v1/models/todo/permissions \
--json \
--verbose \
--auth-type=hawk \
--auth='504fd8148d7cdca10baa3c5208b63dc9e13cad1387222550950810a7bdd72d2c:'
PATCH /v1/models/todo/permissions HTTP/1.1
Accept: application/json
Accept-Encoding: gzip, deflate
Authorization: Hawk mac="CWT9du2YxOoTb2i5d15bBTA4XiSYY/99ybh6g7welLM=", hash="Nt8m2h1nc5lVUItOobOliVj6hul0FYXmwpEmkjyp+WU=", id="220a1c4212d8f005f0f56191c5a91f8fe266282d38b042e6b35cad8034f22871", ts="1406645940", nonce="2il3kl"
Content-Length: 34
Content-Type: application/json; charset=utf-8
Host: localhost:8000
User-Agent: HTTPie/0.8.0
{
"Everyone": [
"read_definition"
],
"Authenticated": [
"ALL"
]
}
HTTP/1.1 200 OK
Content-Length: 333
Content-Type: application/json; charset=UTF-8
Date: Tue, 29 Jul 2014 14:59:00 GMT
Server: waitress
{
"system.Authenticated": [
"create_record",
"delete_all_records",
"delete_model",
"delete_own_records",
"read_all_records",
"read_definition",
"read_own_records",
"read_permissions",
"update_all_records",
"update_definition",
"update_own_records"
"update_permissions",
],
"system.Everyone": [
"read_definition"
]
}
Note
It can be useful if you need to remove permissions associated to an unknown id for example.