NOTE: The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC2119.
collection+protobuf
follows the
collection+json
specification but uses
Protocol Buffers
to provide a structure for a language-neutral, extensible, hypermedia
RESTful service that avoids the ambiguity of a schema-less format
such as JSON.
Unless specified, this specification follows the collection+json
specification and protocol exactly.
- Avoid ambiguity by using structured protobuf messages
- Provide a universal interface to enable automatic clients
- Maintain the same H Factor as
collection+json
- Maintain structural compatibility with
collection+json
by avoiding to redefine anycollection+json
fields. This will aid automatic conversion.
collection+protobuf
tries to maintain structural compatibility with
collection+json
but favors complex strongly typed data for the
payload.
collection+protobuf
uses a pb
field to prevent conflicts with
services that want to provide a simpler collection+json
data
field.
Services that want to maintain compatibility with collection+json
are free use repeated DataField
messages in Template.data
and
Item.data
messages.
This data
field is assumed ignored by services accepting
collection+protobuf
request bodies. Services that use content
negotiation to allow collection+json
request bodies, MUST follow
the collection+json
specification and use the template.data
and
item.data
fields when using JSON.
If your service does convert a collection+protobuf
message to JSON
don't call the resource application/vnd.collection+json
unless it
meets their
spec.
We strongly encourage that messages converted to JSON adhere to the
collection+json
spec. The world does not need one more ad-hoc
format.
Like collection+json
, collection+protobuf
supports the use of
semantic profiles to link to the .proto
file that the resource is
defined in:
application/vnd.collection+protobuf;profile=http://example.com/polling.proto#polling.QuestionCollection
The profile information gives automatic clients enough information to validate and decode a resource from an HTTP response.
A Resource message wraps a collection message. The resource message type is used to aid extensibility if additional fields need to be bundled with the collection.
message (Subject)Resource {
optional Collection collection;
}
A collection+protobuf
Collection message should be shaped like
this:
message (Subject)Collection {
optional string version; // SHOULD
optional string href; // SHOULD
repeated Link links; // MAY
repeated (Subject)Item items; // MAY
repeated Query queries; // MAY
optional (Subject)Template template; // MAY
optional Error error; // MAY
}
Obviously, for brevity, message declarations can omit any optional or repeated fields that are not used by resource. A client MUST support missing fields.
The Collection.template
field is a message that can be used to add
or edit members of the collection.
The template message is shaped like:
message (Subject)Template {
optional (Subject)TemplatePB pb;
}
To match collection+json
The template should be wrapped in
a the subject's Collection message:
template {
pb {
full_name: "J. Doe"
email: "joeexample.org"
blog: "http://examples.org/blogs/jdoe"
avatar: "http://examples.org/images/jdoe"
}
}
A collection+protobuf
services MUST follow protocol established
by collection+json
§ 2.1 read/write
The Collection.items
repeated message is shaped like an Item message
described below.
An Item message is shaped like this:
message (Subject)Item {
optional string href;
optional (Subject) pb;
repeated Link links;
}
The Item.pb
field will be of the type of the subject of the
collection.
The error message is used to express that an error that occurred processing the request.
message Error {
optional string title = 1;
optional string code = 2;
optional string message = 3;
}
The link message is used by Collection messages and Item messages to get all hyper on.
Link relations are thoughtfully described at http://amundsen.com/media-types/linkrelations/
The render field MUST be "link" or "image".
message Link {
required string rel = 1;
required string href = 2;
optional string name = 3;
optional string render = 4 [default="link"];
optional string prompt = 5;
}
NOTE: It is up for debate if we should use an enum for the render field; I chose a string to make conversion to JSON easier.
A Query message for describing how to make queries
The name/value pairs of the data
messages can be combined with the
href
field to make GET requests.
message Query {
required string href = 1;
required string rel = 2;
optional string name = 3;
optional string prompt = 4;
repeated DataField data = 5;
}
The DataField message is used by the Query message to describe a query template
message DataField {
required string name = 1;
optional string value = 2;
optional string prompt = 3;
}
The DataField message MAY be used with Template.data
and Item.data
to maintain compatibility with collection+json
without sacrifice of
explicit typing.
The Template.data
and Item.data
field MUST be ignored by
collection+protobuf
services.
In the examples/
directory is a friends.proto
that demonstrates
conversion of the collection+json
example into
collection+protobuf
In the examples/friends/
are text protobuf messages and binary
protobuf messages for the converted examples.
To make .proto file creation easier there is a script called
bin/new_collection.sh
that will generate a skeleton .proto file
$ ./bin/new_collection.sh Car
import "collection.proto";
message CarResource {
optional CarCollection collection = 1;
}
message CarCollection {
optional string version = 1;
optional string href = 2;
repeated collection.Link links = 3;
repeated CarItem items = 4;
repeated collection.Query queries = 5;
optional CarTemplate template = 6;
optional collection.Error error = 7;
}
message CarTemplate {
optional CarTemplatePB pb = 1;
}
message CarTemplatePB {
}
message CarItem {
optional string href = 1;
optional Car pb = 2;
repeated collection.Link links = 3;
}
message Car {
}