-
Notifications
You must be signed in to change notification settings - Fork 0
Rest.li Protocol
URIs are described using URI templates as defined in the IETF Draft Spec
The content types of pegasus data are application/json
and application/pson
. pson
is a compressed version of json.
The URI templates below assume variables with types as follows:
collection : simple string or "complex key"
entity_id : simple string
ids : list
finder : simple string
params : associative array
Resource | URI Template | Example | Method | Semantics |
---|---|---|---|---|
Collection | /{collection} | /statuses | POST | CREATE – creates an entity in the collection |
Collection | /{collection}/{entity_id} | /statuses/1 | GET | READ – returns the referenced entity |
Collection | /{collection}/{entity_id} | /statuses/1 | PUT | UPDATE – updates the referenced entity |
Collection | /{collection}/{entity_id} | /statuses/1 | POST | PARTIAL UPDATE – partially updates the referenced entity |
Collection | /{collection}/{entity_id} | /statuses/1 | DELETE | DELETE – deletes the referenced entity |
Collection | /{collection}?{ids} | /statuses?ids=1&ids=2&ids=3 | GET | BATCH_GET – returns a map containing the referenced entities |
Collection | /{collection} | /statuses | GET | GET_ALL – returns all entities in the collection |
Collection | /{collection}?q={finder} | /statuses?q=search | GET | FINDER – returns a list containing entities satisfying the query |
Collection | /{collection}?q={finder}{¶ms*} | /statuses?q=search&keywords=linkedin | GET | FINDER – returns a list containing entities satisfying the query |
Collection | /{collection}?action={action}{¶ms*} | /statuses?action=purge&reason=spam | POST | ACTION – some operation, rest.li does not specify any standard behavior |
Associations contain entities referenced by compound keys, referred to here as assockeys
The URI templates below assume variables with types as follows:
firstkey : associative array containing a single element
keys : associative array
association : simple string
assockey : simple string conforming to the assockey syntax described below
assockeys : list of strings conforming to the assockey syntax
finder : simple string
params : associative array
Association keys are composed of one or more named assocKey parts. The key is represented over the wire in the form:
{firstkey}{&keys*}
For example, a two part key identifying an edge in a following graph might be:
followerID=1&followeeID=3
in finders, only some keys from the full association key might be required, e.g.:
followerID=1
All string values for association keys are url encoded. E.g. for the association key composed of code=“1=2b” and widget=“xyz widget”, a GET request using the key would be:
GET /resourceName/code=1%32b&widget=xyz%20widget
When association keys are used in a batch operation, each key is url encoded and put in the form:
ids=urlencoded(associationKey1)&ids=urlencoded(associationKey2)...
Here’s the basic form of a batch update request using association keys:
PUT /resourceName?ids=urlencoded(key1=urlencoded(value)&key2=urlencoded(value)&...)&ids=...
{
"entities": {
"key=urlencoded(value)&key2...": { ... },
...
}
}
Note that in the URL the ids are url encoded AND any strings values for the assocKey parts are double url encoded.
For example, for a batch update for the association keys: (code=“1=2b”, name=“xyz widget”) and (code=“567”, name=“rachet”)
The batch update request would be:
PUT /widgets?ids=code%3D1%2532b%26widget%3Dxyz%2520widget&ids=code%3D567%26widget%3Drachet
{
"entities": {
"code=1%32b&widget=xyz%20widget": {...},
"code=567&widget=rachet": {...}
}
}
Resource | URI Template | Example | Method | Semantics |
---|---|---|---|---|
Association | /{association}/{+assockey} | /follows/followerID=1&followeeID=1 | GET | READ – returns the referenced association entity |
Association | /{association}/{+assockey} | /follows/followerID=1&followeeID=1 | PUT | UPDATE – updates the referenced association entity |
Association | /{association}/{+assockey} | /follows/followerID=1&followeeID=1 | DELETE | DELETE – deletes the referenced association entity |
Association | /{association}/{+assockeys*} | /follows/?ids=followerID%3D1%26followeeID%3D1& ids=followerID%3D1%26followeeID%3D3& ids=followerID%3D1%26followeeID%3D2 \\ Note: followerID%3D1%26followeeID%3D1 unescapes to followerID=1&followeeID=1 |
GET | BATCH_GET – returns a map containing the referenced association entities |
Association | /{association} | /follows | GET | GET_ALL – returns all the association entities |
Association | /{association}?q={finder} | /follows?q=search | GET | FINDER – returns a list containing entities satisfying the query |
Association | /{association}?q={finder}{¶ms*} | /follows?q=followers&userID=1 | GET | FINDER – returns a list containing entities satisfying the query |
Association | /{association}/{+assockey} | /follows/followerID=1?q=other | GET | FINDER – returns a list containing the entities satisfying the query |
Association | /{association}/{+assockey}?q={finder}{¶ms*} | /follows/followerID=1?q=other&someParam=value | GET | FINDER – returns a list containing the entities satisfying the query |
Association | /{association}?action={action}{¶ms*} | /follows?action=purge&reason=spam | POST | ACTION – some operation, rest.li does not specify any standard behavior |
The URI templates below assume variables with types as follows:
finder : simple string identifying a finder
Resource | URI Template | Example | Method | Semantics |
---|---|---|---|---|
Collection, Association, ActionSet | {resource}?q={finder} | /accounts?q=keywordSearch | GET | invokes the specified finder |
The URI templates below assume variables with types as follows:
action : simple string
Resource | URI Template | Example | Method | Semantics |
---|---|---|---|---|
Collection, Association, ActionSet | {resource}?action={action} | /accounts?action=register | POST | invokes the specified action |
The URI templates below assume variables with types as follows:
finder_uri : simple string ...
base_uri : simple string generated via one of the uri templates above
start : simple string
count : simple string
fields : list
Feature | Base URI Type | URI Template | Example |
---|---|---|---|
Paging | Finder | {+finder_uri}{&start,count} | /statuses?q=search&start=0&count=10 |
Projection | Get, BatchGet, Finder | {+base_uri}{&fields} | /groups?q=emailDomain&fields=locale,state |
Schema Return | Any | {+base_uri}&metaDesc | |
Links | Any | {+base_uri}&metaLinks |
Status codes should be interpreted according to the HTTP specification [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html]
Common status codes used in rest.li:
- 200 OK
- 201 Created
- 204 No Content
- 400 Bad Request
- 404 Not Found
- 405 Method Not Allowed
- 500 Internal Server Error
Message Type | Header | Semantics | Notes |
---|---|---|---|
Response | X-LinkedIn-Type | indicates the RecordTemplate type of the JSON entity in the message body. | X-LinkedIn-Type values are Java-style class names. |
Response | X-LinkedIn-Sub-Type | indicates the RecordTemplate type of contained JSON entities in the message body, in cases where the body is a map or list. | X-LinkedIn-Sub-Type values are Java-style class names. |
Response | X-LinkedIn-Error-Response | indicates whether the message body contains a JSON-serialized ErrorResponse object | The header value is set to “true” when an error response is returned. The header is omitted otherwise. |
Response | X-LinkedIn-Id | indicates the id assigned by the server to a new entity created in a collection. | set on response messages resulting from a successful POST request to create an entity. The header value is set to the entity id, represented as a string |
Response | Location | indicates the URI of a new entity created in a collection. | Location is set on response messages resulting from a successful POST request to create an entity. The header value is set to a URI referencing the newly created entity |
Response | Content-Type | The Content-Type is always set to “application/json” | |
Request | X-RestLi-Method | Set whenever content is POSTed. Can be “GET_ALL”, “GET”, “BATCH_GET”, “CREATE”, “BATCH_CREATE”, “UPDATE”, “PARTIAL_UPDATE”, “DELETE”, “BATCH_DELETE”, “ACTION”, “FINDER”, “BATCH_PARTIAL_UPDATE” | Is only required for “BATCH_CREATE”, “BATCH_PARTIAL_UPDATE”, all other method types can be inferred by a RestLi server from the URI string and HTTP Method. |
Single entities are sent as the JSON serialized DataMap representing that entity. The "Content-Type: application/json"
header may be included for PUT and POST requests, if omitted, the server will assume the request is content type is "application/json"
.
Create:
POST /widgets
Content-Type: application/json
{"widgetName":"Lever"}
Read:
GET /widgets/1
Update:
PUT /widgets/1
Content-Type: application/json
{"widgetName":"Lever"}
Delete:
DELETE /widgets/1
A DataMap with field
- “elements”: A JSON array of the resources to batch create/update and the objects are the json serialized values of each resource to create.
E.g.
POST /widgets HTTP/1.0
Content-Type: application/json
X-RestLi-Method: BATCH_CREATE
{
"elements": [
{"widgetName":"Ratchet"},
{"widgetName":"Cog"}
]
}
Response:
{
"elements": [
{
"status": 201,
"id": "100"
},
{
"status": 201,
"id": "101"
}
]
}
Responses are associated to the request by array index. E.g. “Trebuchet” was assigned id 100 and Gear was assigned id 101.
Note: Batch create requests must include the HTTP Header:
X-RestLi-Method: BATCH_CREATE
A DataMap with field
- “entities”: A JSON serialized map where the keys are keys of the resources to update and the objects are the json serialized replacement values of each resource to update.
E.g.
PUT /widgets?ids=1&ids=2 HTTP/1.0
Content-Type: application/json
X-RestLi-Method: BATCH_UPDATE
{
"entities": {
"21": {"widgetName":"Trebuchet"},
"22": {"widgetName":"Gear"}
}
}
Response:
{
"errors": {},
"results": {
"21": {
"status": 204
},
"22": {
"status": 204
}
]
}
Partial update is a set of operations on data object, which is also instance of DataMap. Operations are expressed using fields with reserved word names. Every operation relates to the object that contains it i.e. it’s parent. Following sections describe all currently supported operations. See [ENGS:Partial Update] for details.
E.g.
POST /widgets/1 HTTP/1.0
Content-Type: application/json
{
“patch”: {
“$set”: {
“name”: “John”,
“address”: {
“street”: “10th”,
“city”: “Sunnyvale”
}
}
}
}
See Partial Update and Batch Update above for details, here the two are combined.
E.g.
POST /widgets?ids=1&ids=2 HTTP/1.0
Content-Type: application/json
X-RestLi-Method: BATCH_PARTIAL_UPDATE
{
"entities": {
"1": {"patch": { "$set": { "name":"Sam"}}}
"2": {"patch": { "$delete": { "name":"John"}}}
}
}
Action params are provided in the request body which must contain a data map keyed by param names. E.g.
POST /widgets?action=purge HTTP/1.0
Content-Type: application/json
{
"reason": "spam",
"purgedByAdminId": 1
}
The X-RestLi-Method: ACTION
may optionally be included, but is not required because rest.li is able to determine the request is an action based on the “action” query param key.
Single entities are returned as the JSON serialized DataMap representing that entity
Lists of entities are returned in a com.linkedin.rest.CollectionResponse wrapper. They are returned by finders and getAll.
CollectionResponse fields:
- “elements” : JSON serialized list of entity types
- (optional) “paging” : JSON serialized CollectionMetadata object
E.g.
{
"elements: [
{ "id": 1, "message": "Good morning!", "tone": "FRIENDLY" }
// ...
],
"metadata" { // only returned by finders that define a metadata schema as part of the interface
// ...
},
"paging": {
"count": 10,
"links": [
"href": "/greetings?count=10&start=10&q=search",
"rel": "next",
"type": "application/json"
],
"start": 0
}
}
Maps of entities are returned in a com.linkedin.rest.BatchResponse wrapper. BatchResponse is used as the response for BATCH_GET requests.
BatchResponse fields:
- “results” : JSON object containing name/value pairs
- name is the string value of each map key
- value is the JSON serialized entity for each map value
- “errors”: Errors for
GET /fortunes?ids=1&ids=2&ids=unacceptableKey&ids=faultyKey
{
"errors": {
"unacceptableKey": {
"status": 416,
"message": "Not Acceptable"
},
"faultyKey": {
"status": 500,
"exceptionClass": "org.example.SomeServerException",
"stacktrace": "SomeServerException at org.example.SomeClass.someMethod(SomeClass.java:1)\n..."
}
},
"results": {
"1": {...},
"2": {...}
}
}
}
{"type":"record",
"name":"CollectionMetadata",
"namespace":"com.linkedin.common.rest",
"doc":"Metadata and pagination links for this collection",
"fields":[
{
"name":"start",
"type":"int",
"doc":"The start index of this collection"
},{
"name":"count",
"type":"int",
"doc":"The number of elements in this collection segment"
},{
"name":"total",
"type":"int",
"doc":"The total number of elements in the entire collection (not just this segment)",
"default":0
},{
"name":"links",
"type":{
"type":"array",
"items":{
"type":"record",
"name":"Link",
"doc":"A atom:link-inspired link",
"fields":[
{
"name":"rel",
"type":"string",
"doc":"The link relation e.g. 'self' or 'next'"
},{
"name":"href",
"type":"string",
"doc":"The link URI"
},{
"name":"type",
"type":"string",
"doc":"The type (media type) of the resource"
}]
}
},
"doc":"Previous and next links for this collection"
}]}
{
"type":"record",
"name":"ErrorResponse",
"namespace":"com.linkedin.common.rest",
"doc":"A generic ErrorResponse",
"fields":[
{
"name":"status",
"type":"int",
"doc":"The HTTP status code"
},{
"name":"serviceErrorCode",
"type":"int",
"doc":"An service-specific error code (documented in prose)"
},{
"name":"message",
"type":"string",
"doc":"A human-readable explanation of the error"
},{
"name":"exceptionClass",
"type":"string",
"doc":"The FQCN of the exception thrown by the server (included the case of a server fault)"
},{
"name":"stackTrace",
"type":"string",
"doc":"The full (??) stack trace (included the case of a server fault)"
}]
}
Actions may optionally return a response body. If they do, it must contain a data map with a single “value” key, where the value of the key is either a primitive type, e.g.:
{
"value": 1
}
or complex data type, e.g.:
{
"value": {
"firstName": "John",
"lastName": "Smith"
}
}
When DataMaps (any pegasus record type as defined in a .pdsc file) are used as keys, the are represented as a string of the form:
path1=value1&path2=value2&…pathN=valueN
Where a path specifies a location of a data element in a complex data type. For example,
{
"key": {
"x": [
"a1",
"a2"
],
"y": 123,
"key.with.dots": "val"
}
}
Is represented in a URI as:
key.x[0]=a1&key.x[1]=a2&key.y=123&key~2Ewith~2Edots=val
Where the chars ‘.[]’ are “~ encoded” to their ascii values. This encoding is the same as “% encoding” except that the escape char is ‘~’ and the only reserved chars are ‘.[]’.
. → ~2E
[ → ~5B
] → ~5D
~ → ~7E
The Params
of a ComplexResourceKey
are always prefixed with “$params.” when represented in a URI, e.g.:
$params.x=a1
??
- Dynamic Discovery (D2)
- Data Schema and Templates
-
Rest.li
- Server
- Client
- Projections
- Tools
- FAQs