The following is an initial draft version of the Thing Tracker Network specification. It is meant as a starting point for further discussion.
For the current work in progress version please visit the github project.
The json schema shown to the right shows a subset of the structure of a valid tracker document (shown in js-schema format for conciseness). The following table summarises the key aspects.
The tracker | may not be empty. | So as to recognise whether a tracker has been correctly loaded. |
must contain an attribute with the name "id" and type of String. | ||
must be an object | As opposed to an array. | |
must contain an attribute with the name "things" and type of Array | Subsequently referred to as a "things array". | |
may contain an attribute with the name "trackers" and type of Array | Subsequently referred to as a "trackers array". | |
The things array | may contain zero or more elements. | An element is subsequently refererred to as a "thing element". |
The trackers array | may contain zero or more elements. | An element is subsequently refererred to as a "child-tracker element". |
A thing element | must contain an attribute with the name "id" and type of String. | |
must contain an attribute with the name "title" and type of String. | ||
may contain an attribute with the name "URL" and type of String. | ||
may contain an attribute with the name "license" and type of String. | ||
may contain an attribute with the name "tags" and type of Array. | ||
may contain an attribute with the name "thumbnailURL" and type of String. | ||
may contain an attribute with the name "description" and type of String. | ||
A URL attribute | should be a valid Uniform Resource Locator. | |
A tags attribute | may contain zero or more elements of type String. |
schema({ "id" : String, "things" : Array.of( { "id" : String, "title": String, "*url": String, "*author": String, "*license": String, "*tags": Array.of(String), "*thumbnailURL": String, "*description": String } ), "*trackers" : Array.of( { "url": String } ) })
{ "description": "An Example Thing Tracker.", "things":[ { "id":"cdebf011-e999-4dc5-b4c2-c4163f5584a0", "title": "strandbeest", "url": "http://garyhodgson.github.com/strandbeest", "author": "Gary Hodgson" }, { "id":"f8736600-ff82-4a92-a5e9-fdeeeeb259fe", "title": "Mechanical Movement #27", "url": "http://garyhodgson.github.com/githubiverse-tst", "author": "Gary Hodgson", "license": "GPL3", "tags": ["mechanical movement", "fun"], "thumbnailUrl": "https://github.com/garyhodgson/githubiverse-tst/raw/master/img/test-jig.jpg", "description": "An implementation of movement #27 from "501 Mechanical Movements" by Henry T. Brown.\\n\\nThis is still a work in progress." } ], "trackers":[ { "url":"http://reprap.development-tracker.info/thingtracker" } ] }
To the left is an example tracker which would validate against the above schema. It shows two things and one child-tracker.
This example can also be found in raw json, or displayed in the Thing Tracker Viewer.
To address the issue of scalability a tracker may be also be structured in a different way. A small tracker with only a handful of things would be adequately covered by a single Tracker, however even a modest number of Things would cause the size of this object to become unwieldy. The solution is to have the Tracker reference a separate JSON object for each Thing, each located in it's own resource. This is accomplished by means of the "refUrl" attribute.
To aid clients and services it is probably sensible to also provide some minimal metadata in the root tracker object, such as the title of the Thing, so they can retrieve some of the information without having to perform a request for each Thing in turn.
{ "description": "An Example Thing Tracker with referenced Things.", "things":[ { "title": "Mechanical Movement #27", "refUrl": "/thing/f8736600-ff82-4a92-a5e9-fdeeeeb259fe" } ], "trackers":[ { "url":"http://reprap.development-tracker.info/thingtracker" } ] }
{ "id":"f8736600-ff82-4a92-a5e9-fdeeeeb259fe", "title": "Mechanical Movement #27", "url": "http://garyhodgson.github.com/githubiverse-tst", "author": "Gary Hodgson", "license": "GPL3", "tags": ["mechanical movement", "fun"], "thumbnailUrl": "https://github.com/garyhodgson/githubiverse-tst/raw/master/img/test-jig.jpg", "description": "An implementation of movement #27 from "501 Mechanical Movements" by Henry T. Brown.\\n\\nThis is still a work in progress." }
This section discusses how a tracker can notify others about how it processes data, and what others may expect from it.
Would tell how many, if any, levels the tracker navigates into the network when it builds its list of things. For example, a tracker may decide to only take the things described directly in the child tracker, and ignore any further grand-child trackers. Another tracker may wish to index as many things as it can, acting as a search engine, and so may navigate through all trackers it can find.
This section talks about the way trackers could operate.
When a tracker service scans a new tracker it would usually read the list of things and add them to it's own cache of things. It may also scan the list of trackers that the tracker holds and choose whether to delve further into the network. Each service implementer makes the choice whether to do this depending on their own needs. Some may go all the way down through the network in order to build a comprehensive search index, whereas others may only wish to read one or two levels deep. By adding the new tracker to their list they then allow any further service who uses their data to make this decision themselves. In this way the data is truly propagated throughout the network without degradation.
A service which adds the things from a tracker will usually store the things so as to make them available for browsing. An optional service is to make this cache of things also available alongside the tracker. In this way each downstream service could choose to read this list of things instead of having to process the list of trackers itself. Naturally the downstream service must decide whether the thing cache is suitable for its purposes. To this extent there is an aspect of trust involved, i.e. they must trust that the parent service has maintained the thing cache list and that it contains the data it requires.