Gadgets RPC

From VZ Developer Wiki
Jump to: navigation, search

The RPC protocol supports the same data and operations as the RESTful API in a form that is more natural for the JSON data format.

The RPC protocol shares the following with the RESTful protocol:

  • The JSON/XML format of the OpenSocial data types such as Person, Activity, Group, AppData are identical.
  • HTTP status codes are used to represent common error cases where applicable.
  • [OAuth-Core-1.0] is supported for authentication and authorization in addition to other authorization schemes a container may choose to support. A single OAuth token can be used for a batch of operations or each operation can specify its own OAuth token.
  • Concurrency control is optional.

The RPC protocol differs from the RESTful protocol in the following ways:

  • Conforms to the [JSON-RPC] specification
  • All structural elements in the protocol are represented using the JSON or XML notation.
  • Batch support is required.
  • HTTP is used primarily as a transport and not to indicate the semantics of the request.

Endpoints

Our possible endpoints are:

URL Addressing

Access to RPC services is possible using a URL addressing scheme to invoke a single RPC via HTTP GET. This encoding can also be used to support RPC execution via form posts including file-uploads as parameters to RPCs. The the following canonical transformation between the RPC structure and its URL encoding are used:

  • The RPC method is defined by the 'method' query parameter
  • The RPC id is defined by the 'id' query parameter
  • All other query parameters are assumed to belong to the RPC params element and are encoded from JSON using <field path dot notation>=<scalar value> | <comma separated array of scalars>. When a field represents an array of non-scalars then elements of the array are identified by enclosing the index in parenthesis. Strings which match [0-9]+ MUST be single-quoted, Strings which match [A-Za-z_]+ MUST be unquoted, all other strings retain their original quoting.

The following provides some examples of mapping JSON objects to URL Parameters:

JSON Object	URL Parameter
{ "field" : "value" }	field=value
{ "field" : [1,2,3,4,5]}	field=1,2,3,4,5
{ "field" : "12" }	field='12'
{ "field" : [identifier,anotheridentifier]}	field=identifier,anotheridentifier
{ "field" : ["value","another value"]}	field=value,"another value"
{ "field" : ['value','another value']}	field=value,'another value'
{ "field" : { "nested" : "value" }}	field.nested=value
{ "field" : [{ "nested1" : "value1" }, { "nested2" : "value2" }]}	field(0).nested1=value1&field(1).nested2=value2

For example, given the following RPC-Request-Payload:

{ "method" : "people.get", "id" : "myfriends", "params": {"userId" : "@me", "groupId" : "@friends" } }

The corresponding URL is:

http://api.example.org/rpc?method=people.get&id=myfriends&params.userId=@me&params.groupId=@friends

RPC Request

An RPC request uses the following format:

RPC-Request = "POST /" RPC-Base-URL " HTTP/1.1"
              "HOST" <any valid HTTP host>
              "Authorization: " Auth-Token 
              "Content-Type: " Content-Type 
              RPC-Request-Payload

For example, here is a RPC request to retrieve information about a user:

POST /rpc HTTP/1.1
Host: api.example.org
Authorization: hh5s93j4hdidpola
Content-Type: application/json
{
  "method" : "people.get",
  "id" : "myself"
  "params" : {
    "userId" : "@me",
    "groupId" : "@self"
  }
}

RPC Base URL

The RPC Base URL is defined in the XRDS file.

RPC Request Payload

RPC requests MAY batch multiple procedure calls into a single HTTP request. Therefore, the payload of an RPC request can container a JSON array of procedure calls, or a single procedure call:

RPC-Request-Payload = RPC-Batch-Payload / RPC-Single-Payload
RPC-Batch-Payload = "[" #RPC-Single-Payload "]"
RPC-Single-Payload = "{"
                        <"> "method" <"> ":" <"> RPC-Method <"> ","
                        <"> "id" <"> ":" <"> Request-ID <"> ","
                        [ <"> "params" <"> ":" RPC-Request-Parameters ]
                      "}"

Note that the "json-rpc" property defined in JSON-RPC [JSON-RPC] is not passed in the request but requests MUST be interpreted as if "json-rpc" : "2.0" was supplied.

If a method call has no parameters, or only default values are required, the "params" field can be omitted completely.

Here is an example of a RPC request with a batch of procedure calls in the payload:

POST /rpc HTTP/1.1
Host: api.example.org
Authorization: hh5s93j4hdidpola
Content-Type: application/json
[
  {
    "method" : "people.get",
    "id" : "myself",
    "params" : {
      "userId" : "@me",
      "groupId" : "@self"
    }
  },
  {
    "method" : "people.get",
    "id" : "myfriends",
    "params" : {
      "userId" : "@me",
      "groupId" : "@friends"
    }
  }
]

Note that multiple authorization tokens MAY be used in a single batch request. The following example contains an authorization token as an HTTP header in the request, which is overridden by an authorization token provided in the 'auth' property in the second request object of the batch. In this example, assume that Alice doesn't have access to Bob's profile, so her authorization token is not sufficient to access his information. The client making the request has an authorization token for Bob's profile, so the client can include this token to retrieve his information as well.

POST /rpc HTTP/1.1
Host: api.example.org
Authorization: <1st Auth token>
Content-Type: application/json
[
  {
    "method" : "people.get",
    "id" : "profileOfAlice"
    "params: {
      "userId" : "09737549474",
    }
  },
  {
    "method" : "people.get",
    "id" : "profileOfBob",
    "params: {
      "userId" : "34906734059",
      "auth" : "<2nd Auth token>"
    }
  }
]

RPC Method

The value of the "method" field in an OpenSocial RPC request uses a format of "<service-name>.<operation>". <service-name> is a string [A-Za-z0-9_]+ that identifies one of the services listed in [Services] and <operation> is a string [A-Za-z0-9_]+ that identifies an operation supported by that service.

RPC-Method   = <"> Service-Name "." Method-Name <">
Service-Name = String
Method-Name  = String

All OpenSocial services expose a "get" operation. Operations with the names get, create, update and delete map to the HTTP equivalent operations in the RESTful protocol of GET, PUT, POST & DELETE.

Available methods can be determined by calling the system.listMethods method.

RPC Request Parameters

Parameters can be passed to RPC methods in the request payload as a JSON object as described in [RFC4627]

Appropriate values for RPC request parameters can be determined by calling the system.methodSignatures method.

Here is an example of an RPC request payload with procedure-specific parameters (userId, groupId) and standard OpenSocial parameters:

{
  "method" : "people.get",
  "id" : "myself"
  "params" : {
    "userId" : "@me",
    "groupId" : "@self",
    "fields" : "name, gender",
    "format" : "json"
  }
}

This specification defines a function ENCODE-RPC-PARAMETER which is an alias for the JSON encoding process. This function takes a key and value as arguments, where the key must be a string, and the value must have a valid JSON encoding.

ENCODE-RPC-PARAMETER(k,v) = "{" <"> k <"> ":" JSON-ENCODE(v) "}")

RPC Response

An RPC response uses the following format:

HTTP/1.x 207 Multi-Status
"Content-Type: " Content-Type 
RPC-Response-Payload

RPC-Response-Payload

RPC responses MAY contain results from multiple procedure calls, if the corresponding HTTP request contained a RPC-Batch-Payload. The batch response elements MUST be returned in the same order as the corresponding batch request elements and the "id" property of the corresponding request in the batch request is carried over to the response. If processing of the entire batch fails, as opposed to a single request within the batch, then the returned value is a single RPC-Error object with the appropriate error message and code.

The response payload for a single procedure call contains an 'id' property to correlate the response with a request. On success, the payload contains a 'result' property. On failure, the payload contains an 'error' property. Each service method defines the object that is included as the Return-Object.

RPC-Response-Payload = RPC-Batch-Payload / RPC-Single-Payload
RPC-Batch-Payload = RPC-Error / ("[" #RPC-Single-Payload"]")
RPC-Single-Payload = "{"
                       <"> "id" <"> ":" <"> Request-ID <"> ","
                       ( (<"> "result" <"> ":" <Return-Object>) / (<"> "error" <"> ":" RPC-Error) )
                     "}"

The following examples illustrate how success and failure are represented in responses to batch requests.

Batch successful, all procedure calls successful:

[
  { 
    "id" : "myself", 
    "result" : { ... }
  },
  { 
    "id" : "myfriends", 
    "result" : { ... }
  }           
]

Batch successful, some procedure calls successful while some fail:

[
  { 
    "id" : "myself", 
    "result" : { ... }
  },
  { 
    "id" : "myfriends", 
    "error" : { ... }
  }
]

Batch successful, all procedure calls fail:

[
  { 
    "id" : "myself", 
    "error" : { ... }
  },
  { 
    "id" : "myfriends", 
    "error" : { ... }
  }
]

Batch fails:

{
  "error" : { ... }
}

RPC Error

An error object contains a 'code' property to indicate the actual error that occurred and MAY contain a 'message' property describing the error. Additional information may be returned in the 'data' property, as defined by the procedure.

RPC-Error = "{"
              [ <"> "message" <"> ":" <"> string <"> "," ]
              [ <"> "data" <"> ":" <any JSON object> "," ]
              <"> "code" <"> ":" integer ","
            "}"

A common set of error codes are used to represent failure modes that apply generally to operations and so are reserved for use by this specification.

-32700 (Parse error)
Invalid JSON. An error occurred on the server while parsing the JSON text.
-32600 (Invalid Request)
The received JSON not a valid JSON-RPC or batch of JSON-RPCs.
-32601 (Method not found)
The requested remote-procedure does not exist / is not available.
-32602 (Invalid params)
Invalid method parameters.
-32603 (Internal server error)
Internal server error.
-32099..-32000
Reserved for implementation-defined server-errors.
401 (Unauthorized)
Access token does not grant access to the resource,
404 (Not Found)
The requested resource was not found.
409 (Conflict)
The requested update conflicts with a prior change.
0-1000
Reserved for future use by this specification.

Here is an example of an unsuccessful RPC response payload:

{
  "id" : "myself"
  "error" : {
    "code" : 401
    "message" : "The authorization token does not provide access to the requested resource."
  }
}