Patch attached here
https://issues.apache.org/jira/browse/SHINDIG-476
On Thu, Jul 24, 2008 at 11:56 PM, Kevin Brown <[EMAIL PROTECTED]> wrote:
> On Thu, Jul 24, 2008 at 7:50 PM, Louis Ryan <[EMAIL PROTECTED]> wrote:
>
>> I agree with Kevin that were down to a hairs breadth of difference between
>> the two if we use
>>
>> resource = {
>> "service" : "people",
>> "userid" : "@me",
>> "groupid" : "@all",
>> "personid" : "example.org:3838923",
>> "fields" : ["nickName"]
>> }
>>
>> instead of URLs as John suggested we might for JSON-RESTful batch so if
>> we can agree to use either Johns revised revision or mine and then make it a
>> MUST and I think we've got a solid API and Ill +1 whichever folks feel more
>> comfortable about.
>>
>
> Does the resource object need to contain the operation as well? It's not
> clear if the "method" field is still preserved here.
>
>
>>
>>
>> On Thu, Jul 24, 2008 at 6:08 PM, Kevin Brown <[EMAIL PROTECTED]> wrote:
>>
>>> There are a lot of words on this thread so I won't add too many more. I
>>> don't think the first proposal from John is very natural looking for an API,
>>> and have a strong preference for semantically meaningful field names and
>>> values (and avoiding parsing). John's second proposal seems much better (and
>>> not much different from Louis'), though I don't actually care about REST
>>> semantics anyway and just want to see something actually working for real on
>>> a production system.
>>>
>>> On Thu, Jul 24, 2008 at 1:42 PM, Louis Ryan <[EMAIL PROTECTED]> wrote:
>>>
>>>> Heres my take on John's proposal and why I still prefer the JSON-RPC
>>>> variant. The example below is taken from John's proposal with an equivalent
>>>> in JSON-RPC form
>>>>
>>>> *RESTful JSON batching:*
>>>> {
>>>> "method" : "PUT",
>>>> "url" :
>>>> "/people/@me/@all/example.org:3838923?fields=nickName<http://example.org:3838923/?fields=nickName>",
>>>>
>>>> "id" : "setContactNickName",
>>>> "body" :
>>>> {
>>>> "nickName" : "Flounder"
>>>> },
>>>> "If-Match" : "A35II835334339"
>>>> }
>>>>
>>>>
>>>> *JSON-RPC*:
>>>> {
>>>> "method" : "people.update"
>>>> "id" : "setContactNickName"
>>>> "params" : {
>>>> "userid" : "@me",
>>>> "groupid" : "@all",
>>>> "fields" : ["nickName"],
>>>> "person" : {
>>>> "nickName" : "Flounder",
>>>> "etag" : "A35II835334339"
>>>> }
>>>> }
>>>> }
>>>>
>>>> 1. The parametrization for the operation to perform is encoded in a URL
>>>> like "/people/@me/@all/example.org:3838923?fields=nickName". The
>>>> format of these URLs can vary arbitrarily among containers and should be
>>>> described in XRDS. This seems like unnessecary complexity for consumers of
>>>> this API to have to deal with. The use of named parameters in the JSON-RPC
>>>> proposal makes the specification considerably more concrete and easier to
>>>> consume in my opinion.
>>>>
>>>> 2. RESTful batch uses ... "method" : "PUT" .. to identify the operation
>>>> to perform. In this case its an update to a person record. 'update' is a
>>>> more natural verb for this operation and the use of PUT is a hangover from
>>>> HTTP. The benefits of using HTTP verbs in RESTful APIs if well-discussed
>>>> and
>>>> not something I would argue with in general, but in the specific case of
>>>> batching most of those infrastructural benefits evaporate so I would prefer
>>>> to use clearer verbs where possible with the potential for supporting more
>>>> verbs than just CrUD.
>>>>
>>>> The above are my primary objections, there are some other less
>>>> significant details that can be resolved once a decision is made one way or
>>>> the other
>>>>
>>>>
>>>>
>>>> On Tue, Jul 22, 2008 at 10:38 PM, John Panzer <[EMAIL PROTECTED]>
>>>> wrote:
>>>>
>>>>> +1 to coming up with a new solution.
>>>>>
>>>>> Here's another alternative to compare to Louis' JSON-RPC proposal:
>>>>> RESTful JSON Batching. In practice I think both proposals are fairly
>>>>> close
>>>>> to each other (but I'd like to get some implementors to verify this).
>>>>> They
>>>>> could be made closer and I think Louis has some ideas in that direction.
>>>>>
>>>>> *Summary of differences from the 0.8 MIME multipart batching:*
>>>>> o Doesn't require MIME, only POSTing a JSON list and reading a
>>>>> resulting JSON list
>>>>> o Doesn't support non-JSON requests or mixed requests (each data format
>>>>> needs a separate proposal; Atom would be a separate proposal with a lot of
>>>>> copy and pasting from this one)
>>>>>
>>>>> *Summary of differences from JSON-RPC proposal:*
>>>>> o RESTful vs. RPC orientation (for this particular operation the
>>>>> differences are not large)
>>>>> o Fewer conceptual differences from doing individual HTTP operations;
>>>>> translation is largely 1:1 through a few generic mechanisms, with a
>>>>> standard
>>>>> way to handle new extensions the "same way" in each
>>>>> o A few non-essential differences that could easily be unified if it
>>>>> seems worthwhile to the community:
>>>>> o Keeps URLs to identify resources; these too could be translated
>>>>> into JSON structures if the added spec complexity is warranted, though I'd
>>>>> like to make it a generic 1:1 translation if possible
>>>>> o Doesn't do signing of request bodies: I'm not convinced this is
>>>>> necessary given the use cases, but if I'm wrong I'll do it the same way as
>>>>> in the JSON-RPC proposal
>>>>> o Makes IDs for individual requests OPTIONAL, under the theory that
>>>>> they're a bit like forcing people to supply line numbers in BASIC.
>>>>>
>>>>> Enjoy!
>>>>> -John
>>>>> Proposal: RESTful Operation Batching (Rough Draft)
>>>>> 1. OverviewThis proposal defines an alternative operation batching
>>>>> mechanism, to replace section 9 of the 0.8 RESTful API
>>>>> specification<http://code.google.com/apis/opensocial/docs/0.8/restfulspec.html>.
>>>>>
>>>>>
>>>>> *Motivation*: Batching of operations can be critical to reducing
>>>>> latency and increasing throughput of network protocols. For many common
>>>>> read-only requests, collections and pagination address this need.
>>>>> However,
>>>>> for mixed requests dealing with varied operation or resource types, it's
>>>>> natural to simply collect the desired operations into a batch operation.
>>>>> This proposal offers a RESTful alternative to "Proposal for an OpenSocial
>>>>> JSON-RPC API" which attempts to address most of the same issues with less
>>>>> change from the existing OpenSocial 0.8 RESTful specification.
>>>>>
>>>>> *Concepts: *Clients create *batch operations* when they want to ask a
>>>>> server to orchestrate a set of individual operations. A batch operation
>>>>> is
>>>>> essentially an ordered list of individual operations. An individual
>>>>> operation corresponds 1:1 to a RESTful operation on a resource as
>>>>> described
>>>>> in other sections. The batch operation is itself a resource which can be
>>>>> represented in JSON. POSTing the batch operation to a server tells the
>>>>> server to process the individual operations in order. The server returns
>>>>> the resulting state of the batch operation resource after the requests are
>>>>> processed, providing the client with results and/or status on each.
>>>>>
>>>>> Note: An XML+Atom variant of this scheme would reflect 1:1 the JSON
>>>>> structure in this document; this proposal leaves the Atom variant for
>>>>> another proposal, but claims, without substantiation, that it would be
>>>>> straightforward once the details of the basic structure are worked out.
>>>>>
>>>>> 2. Examples2.1 Basic write/read exampleThis toy example assumes that a
>>>>> contact record's nickname can be updated in the example.org social
>>>>> network, and that after updating the record, the client wants to retrieve
>>>>> all friends.
>>>>>
>>>>> *Request:*
>>>>>
>>>>> POST /batchOps HTTP/1.1
>>>>> Authorization: OAuth realm="http://example.org/",
>>>>> oauth_consumer_key="dpf43f3p2l4k3l03",
>>>>> oauth_token="nnch734d00sl2jdk",
>>>>> oauth_signature_method="HMAC-SHA1",
>>>>> oauth_signature="tR3%2BTy81lMeYAr%2FFid0kMTYa%2FWM%3D",
>>>>> oauth_timestamp="1191242096",
>>>>> oauth_nonce="kllo9940pd9333jh",
>>>>> oauth_version="1.0"
>>>>> Content-Type: application/json
>>>>>
>>>>> [
>>>>> {
>>>>> "method" : "PUT",
>>>>> "url" : "/people/@me/@all/example.org:3838923?fields=nickName
>>>>> ",
>>>>> "id" : "setContactNickName",
>>>>> "body" :
>>>>> {
>>>>> "nickName" : "Flounder"
>>>>> },
>>>>> "If-Match" : "A35II835334339"
>>>>> },
>>>>> {
>>>>> "method" : "GET",
>>>>> "url" : "/people/@me/@friends"
>>>>> },
>>>>> ]
>>>>> *
>>>>> Notes:*
>>>>>
>>>>> - Each operation consists of an envelope which mirrors the relevant
>>>>> headers of the equivalent HTTP request, and a body:
>>>>> - "method" and "url" denote the HTTP method and (relative) URL for
>>>>> the individual request.
>>>>> - "id" is optional and is used by the client to describe the
>>>>> operation for later matching.
>>>>> - "body" is required for POST and PUT methods and contains the
>>>>> data that would have been in the HTTP body.
>>>>> - Other HTTP headers MAY be provided (e.g., "If-Match") with the
>>>>> same semantics as the HTTP counterparts. Clients and servers MAY
>>>>> ignore any
>>>>> such headers, and MUST ignore any headers they do not understand.
>>>>> Unlike
>>>>> the HTTP protocol, the header names are case sensitive and MUST use
>>>>> the case
>>>>> specified in RFC2616 (HTTP 1.1). Note that they may include
>>>>> characters
>>>>> which are not legal JavaScript identifier characters, and thus may
>>>>> need
>>>>> special syntax to be referenced (*op["WWW-Authenticate"*] vs. *
>>>>> op.WWW-Authenticate*, for example).
>>>>> - The Authorization: header above uses standard, core OAuth to
>>>>> authorize all operations as being executed on behalf of a single user
>>>>> (specified via the oauth_token). Note that the OAuth signature
>>>>> verifies
>>>>> only the Authorization: header and the /batchOps URL; the payload is
>>>>> *not* verified by a signature. If this is a security issue, TLS
>>>>> (https) or other solutions SHOULD be used for message integrity. (See
>>>>> below
>>>>> for an example of a multi-user operation.)
>>>>>
>>>>>
>>>>> *Response:*
>>>>>
>>>>> HTTP/1.x 200 OK
>>>>> Content-Type: application/json
>>>>>
>>>>> [
>>>>> {
>>>>> "code" : 200,
>>>>> "etag" : "B383999",
>>>>> "id" : "setContactNickName"
>>>>> },
>>>>> {
>>>>> "code" : 200,
>>>>> "ETag" : "XYZ3737",
>>>>> "body" : {
>>>>> "totalResults" : 100,
>>>>> "startIndex" : 0,
>>>>> "itemsPerPage" : 10,
>>>>> "entry" : [
>>>>> {..},
>>>>> {..},
>>>>> ]
>>>>> }
>>>>> }
>>>>> ]
>>>>>
>>>>> *Notes:*
>>>>>
>>>>> - The response code for the batch MUST be 200 if the body of the
>>>>> response correctly reflects the final state of the batch operations
>>>>> (every
>>>>> sub-operation may have failed, for example, but the mechanical
>>>>> execution of
>>>>> the batch itself succeeded). If the batch execution itself failed or
>>>>> was
>>>>> interrupted, the server SHOULD respond with a 5xx error code. If the
>>>>> envelope of the batch was syntactically incorrect, e.g., not a JSON
>>>>> list,
>>>>> the server SHOULD respond with a 4xx error code.
>>>>> - Each sub-operation is executed "as if" it were sent separately in
>>>>> the given sequence.
>>>>> - Servers MUST preserve any "id" fields.
>>>>> - The sub-operation's result is reflected in the new envelope,
>>>>> which mirrors the relevant headers of the equivalent HTTP response, and
>>>>> possibly a body:
>>>>> - "code" is the response code from the server and is REQUIRED.
>>>>> - "ETag" mirrors the HTTP ETag header and is OPTIONAL.
>>>>> - "body" is in general optional and provides the data that would
>>>>> have been in the individual HTTP response body.
>>>>>
>>>>>
>>>>> 2.2 Batch Updates on Behalf of Multiple Users
>>>>> Below is an example of a server-to-server interaction in which the
>>>>> requester is acting on behalf of many users, updating their locations as
>>>>> new
>>>>> data comes in. In this particular example, it uses stored OAuth tokens to
>>>>> allow it to update the users' locations.
>>>>>
>>>>> *Request:*
>>>>>
>>>>> POST /batchOps HTTP/1.1
>>>>> Content-Type: application/json
>>>>>
>>>>> [
>>>>> {
>>>>> "method" : "PUT",
>>>>> "url" : "/people/@me/@self?fields=currentLocation",
>>>>> "Authorization:OAuth" : {
>>>>> "realm" : "http://example.org/",
>>>>> "oauth_consumer_key" : "dpf43f3p2l4k3l03",
>>>>> "oauth_token" : "iopq578d01el5iuy",
>>>>> "oauth_signature_method" : "HMAC-SHA1",
>>>>> "oauth_signature" : "wX3%2BZo71lMeYAr%2FFid0kMTYa%2FWM%3D",
>>>>> "oauth_timestamp" : "1191242096",
>>>>> "oauth_nonce" : "kllo9940pd9333jh",
>>>>> "oauth_version" : "1.0"
>>>>> },
>>>>> "body" :
>>>>> {
>>>>> "currentLocation" : {...some new location for user X
>>>>> here...}
>>>>> },
>>>>> },
>>>>> {
>>>>> "method" : "PUT",
>>>>> "url" : "/people/@me/@self?fields=currentLocation",
>>>>> "Authorization:OAuth" : {
>>>>> "realm" : "http://example.org/",
>>>>> "oauth_consumer_key" : "dpf43f3p2l4k3l03",
>>>>> "oauth_token" : "rznh874d67el5ooi",
>>>>> "oauth_signature_method" : "HMAC-SHA1",
>>>>> "oauth_signature" : "iO3%3FBZo98lZeREruEid0kMTYaqZI%2B",
>>>>> "oauth_timestamp" : "1191242096",
>>>>> "oauth_nonce" : "kllo9940pd9333jh",
>>>>> "oauth_version" : "1.0"
>>>>> },
>>>>> "body" :
>>>>> {
>>>>> "currentLocation" : {...some new location for user Y
>>>>> here...}
>>>>> },
>>>>> }
>>>>> ]
>>>>>
>>>>>
>>>>> *Notes:*
>>>>>
>>>>> - This authorizes each sub-request separately.
>>>>> - The Authorization: header has a special mapping to the
>>>>> sub-operation format: It becomes a multi-part key
>>>>> "Authorization:OAuth" and
>>>>> an object with the remaining authorization parameters translated 1:1
>>>>> to JSON
>>>>> notation.
>>>>> - The signature for each sub-operation is the same as the signature
>>>>> that would have been generated for the equivalent HTTP operation
>>>>> (combining
>>>>> the Authorization fields, the url path and parameters, and the consumer
>>>>> secrets as described in the OAuth 1.0 specification).
>>>>> - A top-level Authorization: HTTP header, if present, is used to
>>>>> authorize any sub-operation which lack authorization (note that this
>>>>> omits
>>>>> the signature on the URL parameters of the individual sub-operation).
>>>>> - Aside: This proposal does not include signing of bodies; it
>>>>> assumes that this is either impossible (no secret keys) or
>>>>> unnecessary
>>>>> (secure connection already established) in 80% of cases. If this
>>>>> assumption
>>>>> is wrong, then it would adopt the JSON-RPC proposal's signing.
>>>>> - I disclaim all responsibility for any escaping errors in the
>>>>> strings above. If it works conceptually I'll fix them. Similarly the
>>>>> OAuth
>>>>> values above for signature, etc. are completely made up.
>>>>>
>>>>>
>>>>> *Response:*
>>>>>
>>>>> HTTP/1.x 200 OK
>>>>> Content-Type: application/json
>>>>>
>>>>> [
>>>>> {
>>>>> "code" : 200,
>>>>> "ETag" : "C8933duid"
>>>>> },
>>>>> {
>>>>> "code" : 401,
>>>>> "WWW-Authenticate:OAuth" : "..."
>>>>> "body" {
>>>>> "message" : "User token expired."
>>>>> }
>>>>> }
>>>>> ]
>>>>>
>>>>>
>>>>> *Notes:
>>>>> *
>>>>>
>>>>> - In the example above, the first operation succeeded and the
>>>>> second failed because oauth_token supplied has expired.
>>>>> - The WWW-Authenticate:OAuth element contains additional machine
>>>>> readable information.
>>>>> - In general, errors can contain bodies with more details (see
>>>>> below.)
>>>>>
>>>>>
>>>>> Note: Can extend this to provide examples for Activity, Appdata, etc.
>>>>> but it will basically be "more of the same" -- would be good to get
>>>>> feedback
>>>>> on above before proceeding further.
>>>>>
>>>>> 3. Standard Batch-Level ErrorsServers SHOULD use these error codes to
>>>>> indicate the corresponding batch-specific error conditions.
>>>>>
>>>>> Code
>>>>> Meaning
>>>>> 400 Parse error/invalid request
>>>>> Invalid JSON or invalid batch syntax. An error occurred on the server
>>>>> while parsing the JSON body. The request SHOULD NOT be repeated without
>>>>> modification per HTTP 1.1.
>>>>> 500 Internal server error
>>>>> Internal server error; batch may or may not have been partially
>>>>> executed.
>>>>> 503 Server unavailable
>>>>> Temporary server error; batch may or may not have been partially
>>>>> executed; if retryable, a Retry-After: header SHOULD be supplied.
>>>>> 501 Not implemented
>>>>> Server does not support a batching extension which the client requests.
>>>>>
>>>>> 401 Unauthorized
>>>>> The consumer key, IP address, or (less likely) oauth token do not
>>>>> provide authorization to even attempt to execute batch operations.
>>>>> 404 Not Found
>>>>> On the /batchOps URL, implies that the server does not support batching
>>>>> (but servers MUST support batching, so this is a "should not happen"
>>>>> case).
>>>>> 303 See Other
>>>>> Indicates that the final result of the batch can be found at another
>>>>> location, specified in the Location: header, and retrieved via GET.
>>>>> (This
>>>>> result is possibly cacheable, whereas the POST is not; thus it is likely
>>>>> to
>>>>> be usable only for a batch of idempotent operations.)
>>>>>
>>>>> 4. Standard Operation-Level ErrorsThese are supplied in the "code"
>>>>> field of an executed operation, and are the same as the corresponding HTTP
>>>>> response. In particular, clients SHOULD be aware of and properly process
>>>>> 200 OK, 201 Created, 202 Accepted, 204 No Content, 304 Not Modified, 400
>>>>> Bad
>>>>> Request, 401 Unauthorized, 409 Conflict, and the 5xx error range.
>>>>>
>>>>> For errors, the error fields as specified in the JSON-RPC proposal are
>>>>> hereby incorporated by reference (TBD: Copy these in and make this
>>>>> explicit).
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>
>>>>
>>>>
>>>
>>>
>>>
>>
>>
>>
>
> --~--~---------~--~----~------------~-------~--~----~
> You received this message because you are subscribed to the Google Groups
> "OpenSocial and Gadgets Specification Discussion" group.
> To post to this group, send email to
> [EMAIL PROTECTED]
> To unsubscribe from this group, send email to
> [EMAIL PROTECTED]
> For more options, visit this group at
> http://groups.google.com/group/opensocial-and-gadgets-spec?hl=en
> -~----------~----~----~----~------~----~------~--~---
>
>