-
Notifications
You must be signed in to change notification settings - Fork 0
Thing Broker API
This document describes the Thing Broker API. It is a RESTful interface that generally uses JSON for transferring data.
The Thing Broker currently provides the following abstractions:
- Applications - application clients that use the thing broker. Used for real time event retrieval.
- Things - represent physical or virtual entities with a globally unique id, name, description, type, and metadata associated with them.
- Events - events sent to or retrieved from a thing containing information (info) fields and content such as photos, audio files.
- Content - content uploaded with an event
Note: applications are currently used only to retrieve real time events. Future: things will support 'state' which will contain the latest value of each event info field
Like twitter users, Things have following/follow relationships; one thing may follow another. When retrieving events from a thing (past or real time), you can retrieve events sent to the thing and all of the things it is following, or just the things sent to the things it is following.
Future: we may also provide a way to only retrieve events sent to the thing, not the things it follows, but we don't have a use case for that yet.
In a typical installation, the thingbroker will be installed on a Tomcat server and use the web application prefix 'thingbroker'. All URLs in this should be prefixed with the following:
http://{host}:{port}/thingbroker
Where host is your host name or IP address, port is the port number (80 or 8080 typically) and /thingbroker is the name of the web application (.war) file. Of course the port can be omitted if 80 is used, and /thingbroker may be omitted if the application is the ROOT.war application.
Create an application resource to uniquely identify your application for the thing broker. This is currently required for real time event retrieval to ensure your application is allocated its own event queue.
To register a new application, POST the application name to the following URL
POST /applications
{
name:"application-name"
}
This will return the application representation with its id as follows:
{
id: "88c67d4e-178e-4c50-98b2-3e2179e32636",
name: "application-name"
}
More than one application can share the same name. The application id returned will be globally unique.
Get all applications registered with the system
GET /applications
[{
id: "88c67d4e-178e-4c50-98b2-3e2179e32636",
name: "application-one"
},
{
id: "88c67d4e-178e-4c50-98b2-3e2179e32636",
name: "application-two"
},
{
id: "88c67d4e-178e-4c50-98b2-3e2179e32636",
name: "application-three"
}]
PUT /application/88c67d4e-178e-4c50-98b2-3e2179e32636
{
name:"updated app name"
}
Returns the updated application:
{
id: "88c67d4e-178e-4c50-98b2-3e2179e32636",
name:"updated app name"
}
Delete the specified application:
DELETE /application/88c67d4e-178e-4c50-98b2-3e2179e32636
A "thing" object is represented by the following JSON:
{
thingId: "88c67d4e-178e-4c50-98b2-3e2179e32636",
name: "Ricardo-Galaxy-Nexus",
description: "Description for a thing",
type: "smartphone",
metadata: null,
followers: [ ],
following: [ ]
}
To register a new thing on the system, POST a JSON thing description to the following URL
/things
Note that more than one thing can share the same name. Only the thingId must be globally unique.
There are no required JSON parameters, a thing may have an empty name and description (not advised), but you MUST provide an empty JSON object; that is, at least "{}" in the content.
thingId: (not required) Specifies an alpha-numeric id.If not provided, the thing broker will generate a unique identifier.
name: (not required) Specifies a thing's name.
description: (not required) Specifies a short description of the thing.
type: (not required) Specifies a user-defined thing type. Example Values: sensor, display, mobile.
To retrieve all things, or search for things, GET from the same URL
/things
You can add query parameters to get things with a given id, name, description, or type
e.g.
GET /things?name=screen-thing
GET /things?thingId=123
GET /things?name=test
GET /things?type=test
GET /things?thingId=123&name=test
Will return all of the things with the name 'screen-thing'.
TODO: support query on meta data
To retrieve a specific thing with a specific ID, use the following URL
/things/{thing-id}
Where the {thing-id} is the thing id GUID returned when creating the thing.
To update a thing, PUT a thing description to the following URL
/things
The JSON object supplied should contain the following
thingId: id of thing to update
name: Updated name
description: Updated description
type: updated type
TODO: currently the thing ID must be specified in the JSON object. It should be in the URL
To delete a thing, and all of its events, use the HTTP delete method on the following URL
/things/{thing-id}
Response: A JSON that represents the thing it was removed.
{
"thingId": "{thing-id}",
"name": "test",
"description": "This is a thing",
"type": "Random thing",
"metadata": null,
"followers": [],
"following": []
}
To follow a thing, we POST a list of thing IDs to the follow URL
POST /things/{thing-id}/follow
["456574657-567-567-3452-3254", "23532452-1732458e-435-345-345", "345-675876-58678-790-678"]
This sets up a following/follower relationship between the {thing-id} and the list of things it is following.
To unfollow a thing, we POST a list of things to unfollow. For example:
POST /things/{thing-id}/unfollow
["456574657-567-567-3452-3254"]
TODO: DELETE on the follow URL, provide the id in the URL to unfollow a single thing
Sending a JSON object to this URL updates the meta data for the thing and returns the updated thing representation.
Gets the JSON representation of the metadata for the thing
TODO: support metadata queries
Thing state is a collection of all of the info fields sent to a thing, when it was last updated and its last value. Not implemented yet
Future: not implemented yet. The use case is when you want to know the current state of a thing, eg. a phone's last known location, sensor values, etc.
Applications send and receive events to and from things and the things they follow. Applications can receive events in real time using HTTP long polling, or retrieve past events.
To send an event to a thing POST to the following URL
POST /things/{thing-id}/events
Request parameters
keep-stored: (Optional) When set to "true" the events will be stored for future reference.
You must provide a JSON object containing a collection of key-value pairs. You can provide as many key-value pairs, like so:
{"video_url": "http://www.youtube.com/watch?v=QH2-TGUlwu4"}
POST /things/123/events?keep-stored=true
Content-type: application/JSON
Body: {"video_url": "http://www.youtube.com/watch?v=Rku5Oyf-hYU"}
Note: If you are adding a file (image or other) on the body, make sure to change the content-type appropriately to: "Content-type: multipart/form-data". In this case, there'll be a reference id to each piece of content in the content field of the event
{
"eventId": "7eb4e2ea-448f-4a5a-a388-0babc8b502c9",
"thingId": "123",
"serverTimestamp": 1349932703681,
"info": "{\"video_url\":\"http://www.youtube.com/watch?v=Rku5Oyf-hYU\"}"
}
To GET events sent to a thing, and/or to the things it is following, issue a GET request to the same URL with appropriate query parameters.
GET /things/{thing-id}/events?{queryParam}={queryValue}
A thing "event" response is a collection of events ordered by timestamp:
[
{
eventId: "b7ba0f87-d54f-4531-af93-d78277b305ee",
thingId: "123",
serverTimestamp: 1349912663503,
content: [
"1abe3a85-7376-4a15-968b-72dca3fef2e6"
]
},
{
eventId: "62e5d0fe-a854-4d72-bbec-6a211f720671",
thingId: "123",
serverTimestamp: 1349911561470,
content: [
"9dafb29b-21c8-4266-a6d6-8fe5ae128470"
]
},
{
eventId: "5c114a70-7fb2-42ae-9685-9738d1008651",
thingId: "123",
serverTimestamp: 1349911236601,
info: "{"website":"www.blueyou.com.br"}"
}
]
To request historical events, specify one or more of the following parameters:
limit: | (not required) Determines how many events will be fetched. |
offset: | (not required) number of events to skip from the start. |
start: | (not required) This parameter must be defined in Unix epoch time (milliseconds). Example Values: 1349937425. Works together with "end", "before" and "after" to specify the absolute start time for an interval. |
end: | (not required) Works together with "start" to specify the absolute end time for an interval. It must be greater than the "start" time. Defined in Unix epoch time (milliseconds). Example Values: 1349937434 |
after: | (not required) Returns events after a time defined the "start" time in milliseconds. For example, to retrieve 20 seconds of events after the time 1349937434, start=1349937434&after=20000 |
before: | (not required) Returns events preceding the "start" time. This is the _relative_ number of milliseconds before the start time (e.g. 60000 is 60 seconds before the specified (absolute) start time). If "start" is not specified, the start time is now. E.g. to get the last 10 seconds of events, before=10000 |
filter: | get events sent to thing and things it is following (all), sent directly to the thing, but not to the things it is following (thing-only), sent to the things it is following, not directly to the thing (following-only). The default is "all". |
To get real time events, only supply a "waitTime" parameter (seconds to wait), "filter" or no parameters at all. The thing broker will not return until waitTime has passed, or an event is received by the thing (or things it is following).
**Note: If you don't provide url parameters it'll be returned a maximum of 25 events stored in Thing Broker TODO: verify above
**Note: only one application can request real time events from a thing direcly. If more than one application requests real time events from the same thing, not all applications will receive all events -- they are drawing from the same queue. To ensure more than one applications receive events from the same thing, create a new thing for the second application, and follow the thing you want to receive events from.
waitTime: time to wait for more events
followingOnly: only retrieve events from things the thing is following
NOTE: may remove waitTime parameter since this needs to be managed by the server. If the load is high, it may want to release long pollers sooner.
GET /things/123?limit=3
[
{
eventId: "62e5d0fe-a854-4d72-bbec-6a211f720671",
thingId: "123",
serverTimestamp: 1349911561470,
data: [
"9dafb29b-21c8-4266-a6d6-8fe5ae128470"
]
},
{
eventId: "5c114a70-7fb2-42ae-9685-9738d1008651",
thingId: "123",
serverTimestamp: 1349911236601,
info: "{"website":"www.blueyou.com.br"}"
},
{
eventId: "8f769677-a6f7-429d-b19b-db0c409e016c",
thingId: "123",
serverTimestamp: 1349906908431,
info: "{"video_url":"http://www.youtube.com/watch?v=Rku5Oyf-hYU"}"
}
]
This method will update a past event identified by eventId. If none event was found, it returns a JSON with an error message.
TODO: needs testing since API change. PUT should be used instead of POST.
/things/{eventId}
serverTimestamp: (required) The serverTimestamp field for the event that is being updated. This is necessary to check if the event being updated won't overlap new changes in the event.
I don't understand why serverTimestamp needs to be changed
none
POST /events/{eventId}?serverTimestamp=18746875687
Note: If you are adding a file (image or other) on the body, make sure to change the content-type appropriately to: "Content-type: multipart/form-data". In this case, there'll be a reference id to each content in the data field of the event
Note: needs testing since API cahnge
The server will respond with a JSON describing the updated event.
None
Note: needs testing since API change. Its not clear why you would specify the event-id and the timestamp. The ID will uniquely identify the event?
This method will add content to the info field of the event identified by eventId. If none event was found, it returns a JSON with an error message If you try to add content with an already existing key, the new content will overlap the one that is already stored.
GET /events/event/{eventId}
serverTimestamp: (required) The serverTimestamp field for the event that is being updated. This is necessary to check if the event being updated won't overlap new changes in the event.
none
PUT /events/event/{eventId}?serverTimestamp=18746875687
The server will respond with a JSON describing the updated event.
This method will retrieve content (data) uploaded with an event by the content ID.
/content/{contentId}
mustAttach: (optional) Indicated if the content must be attached to the response (for downloading purpose) or not. If not specified it is false.
none
GET /content/9dafb29b-21c8-4266-a6d6-8fe5ae128470?mustAttach=false
The server will respond with the file whose ID matches the provided id.
This method will retrieve information about the content (data) uploaded with an event by the content ID.
/content/{contentId}/info
none
GET /content/9dafb29b-21c8-4266-a6d6-8fe5ae128470/info
The server will respond with the content information, the id, name and mime type.
{"contentId":"1655b351-7080-47eb-b571-a3a9cb64d31c","name":"IMG_0031.JPG","mimeType":"image/jpeg"}
Calling a service in thing broker can return a JSON representing a status message indicating an error that occurred. All status messages are composed by a status code and a text message. The status code can be:
OK = 0
THING_NOT_FOUND = 1
THING_ALREADY_REGISTERED = 2
SENT_EVENT_TO_NON_EXISTENT_THING = 3
REQUESTER_NOT_INFORMED = 4
REQUESTER_NOT_REGISTERED = 5
EVENT_NOT_FOUND = 6
EVENT_DATA_NOT_FOUND = 7
INVALID_EVENT_INFO_FIELD = 8
SERVER_TIMESTAMP_NOT_PROVIDED = 9
SERVER_TIMESTAMP_OUTDATED = 10
INTERNAL_ERROR = 500
{
"code": 1,
"message": "Thing not found"
}