--
John Panzer (http://abstractioneer.org)
I like this approach since I only have to state things once.
Is the proposal then:
PUT /appdata/john.doe/@self/@app?
post body : {foo : 5}
causes an update to foo
and
DELETE /appdata/john.doe/@self/@app?
fields=bar
causes the bar field to be removed?
The current restful spec says that the partial updates syntax is tbd. I'd like to propose the following syntax:
When the "fields" parameter is specified on a url, only those fields will be looked at when updating an object. If a field is in the parameter list but not part of the post, that would be considered a removal of that field. If the field is in the post but not in the parameter list it would be ignored. If a field is in both places then it will be updated normally.
For example,
PUT /appdata/john.doe/@self/@app?fields=foo
post body : {foo : 3}
The data store now has {foo : 3}
PUT /appdata/john.doe/@self/@app?fields=bar
post body : {bar : 5}
The data store now has {foo : 3, bar : 5}
(foo was not deleted because it wasn't in the fields list)
PUT /appdata/john.doe/@self/@app?fields=bar
post body : {foo : 5}
The data store now has {foo : 3}
(we ignored foo because it wasn't in the fields list. bar was treated as a delete because it wasn't posted)
From Cassies example
PUT /appdata/john.doe/@self/@app?fields=barthis scares me as there was obvious intent in the call that differed from the protocol and the call succeeds anyway. Similarly if I don't specify a field in the fields list it gets deleted from the resource. Both of these cases seem far too easy for developers to hit. In the case of the implicit delete there isn't any indication in the response what fields were deleted. I like batching and performance optimizations but I fear the wrath of unintended consequences far more.
post body : {foo : 5}
The data store now has {foo : 3}
(we ignored foo because it wasn't in the fields list. bar was treated as a delete because it wasn't posted)
In situations where the object is more complex such as a Person/Contact the situation is much worse than for AppData. Most containers have fields specific to them and a consumer of this API would need to know how to generate an appropriate fields param to cover all of the variations. For large objects this makes an update to a single field incredibly verbose. Many developers would make mistakes forming up the appropriate object and field list for all containers.
Could we simplify and say we don't support the fields param on PUT and only use the content of the body to perform explicit updates on those specified fields. This would allow clients to perform updates on objects for which they only have partial representations to begin with (because ironically they used the fields param on GET) or where they want to directly author the field without first fetching the object at all.
I believe in REST this would actually be an HTTP MERGE/PATCH which if thats the right semantic for what people should be using then lets support and encourage the use of that because its the right thing to use and forego PUT.
On Thu, Jul 31, 2008 at 12:50 AM, Louis Ryan <lr...@google.com> wrote:From Cassies example
PUT /appdata/john.doe/@self/@app?fields=barthis scares me as there was obvious intent in the call that differed from the protocol and the call succeeds anyway. Similarly if I don't specify a field in the fields list it gets deleted from the resource. Both of these cases seem far too easy for developers to hit. In the case of the implicit delete there isn't any indication in the response what fields were deleted. I like batching and performance optimizations but I fear the wrath of unintended consequences far more.
post body : {foo : 5}
The data store now has {foo : 3}
(we ignored foo because it wasn't in the fields list. bar was treated as a delete because it wasn't posted)
This scares me as well (see my proposal that this should result in a 400 Bad Request error; silent data loss is Bad).
But wait a second: "Similarly if I don't specify a field in the fields list it gets deleted from the resource". No, if you leave a field off your filter it means "don't touch this field, it's not part of the object I'm working on at the moment".
So we've got 3, anybody else want to chime in on this thread so we can
close it up?
Thanks.
- Cassie
PUT /appdata/john.doe/@self/@app?fields=foo
post body : {foo : 3}
The data store now has {foo : 3}
PUT /appdata/john.doe/@self/@app?fields=bar
post body : {bar : 5}
The data store now has {foo : 3, bar : 5}
(foo was not deleted because it wasn't in the fields list)
PUT /appdata/john.doe/@self/@app?fields=bar
post body : {foo : 5}
returns a 400 error!
the post body contains a field that doesn't exist when "fields=bar" so
this request has a bad format.
PUT /appdata/john.doe/@self/@app?fields=bar
post body : {}
The data store now has {foo : 3}
(bar was treated as a delete because it wasn't posted)
DELETE /appdata/john.doe/@self/@app?fields=bar
The data store now has {foo : 3}
(nothing happened as bar was already deleted)
DELETE /appdata/john.doe/@self/@app
The data store now has {}
(all fields were deleted because no fields param was specified)
I am -1 on this so far. As I understand things, a PUT is supposed to be idempotent. Because of this, I don’t like the idea of combining insert and update on the same verb.
From: Kevin Marks
[mailto:kevin...@google.com]
Sent: Tuesday, August 12, 2008 12:36 PM
To: opensocial-an...@googlegroups.com
Cc: Scott Seely
Subject: Re: [0.8.1] Partial updates syntax for restful
LGTM er, I mean +1
I am -1 on this so far. As I understand things from RFC 2616, a PUT is supposed to be idempotent. Because of this, I don’t like the idea of combining insert and update on the same verb. When I PUT on the object and then issue the same PUT again, how do I guarantee idempotent inserts? Typically, the actor doing the INSERT doesn’t know the ID of the item being added since that ID is dependent on the backing store.
I can guarantee a PUT is idempotent if I can pass in some unique ID, such as by doing a PUT to a specific URL that uses that resource. In the case below, that doesn’t happen.
With a POST, we don’t guarantee idempotent POST. It seems that we need to INSERT using POST, UPDATE using PUT.
I’m more than welcome to hearing opinions on why this is incorrect. As of now, I think that this is the wrong path.
From: Kevin Marks
[mailto:kevin...@google.com]
Sent: Tuesday, August 12, 2008 12:36 PM
To: opensocial-an...@googlegroups.com
Cc: Scott Seely
Subject: Re: [0.8.1] Partial updates syntax for restful
LGTM er, I mean +1
"Partial updates avoid the need to send full representations
of data on updates, especially for People and App Data."
On Aug 12, 2008, at 10:23 PM, Scott Seely wrote:
> Given the thread, it's not clear if this discussion is solely for the
> appData resource or if it is a general implementation pattern for
> objects. Can someone clarify the intent of what we are being asked to
> vote on?
Patrick Mueller
pmu...@gmail.com
- someone previous asked about doing partial updates of 'inner'
fields. I assume an example would be something like setting the
"name.unstructured" field of Person. Or is this just for 'top-level'
fields; in this case, you couldn't JUST set "name.unstructured", you'd
need to set "name", whose value would be {name : { unstructured :
"Bob" }}
- is there a way to do this in XML?
- what is the JS API going to look like here?
- how do ETags factor in to handle concurrent/lost updates?
I'd say that something about this in general doesn't feel right, where
the ?fields={fieldList} bit is being treated like a resource itself -
someone phrased it well as a "projection" of a resource. Though
clearly you can use query string parameters with PUT and DELETE,
there's something about it that seems ... non-standard. Even though
it would end up being pretty non-performant to do it the way I'm about
to suggest, to update multiple fields, it seems ... RESTier. And that
way would be to handle field updates one at a time, where you don't
use a query string to specify th e field name, but some other
qualifier that moves it back into the main-line URL. Something like
/appdata/john.doe/@self/@app/@field/foo
What ETags mean in such a world is not clear.
On Aug 12, 2008, at 3:05 PM, Cassie wrote:
>
> Sure thing:
>
>
> PUT /appdata/john.doe/@self/@app?fields=foo
> post body : {foo : 3}
>
> The data store now has {foo : 3}
>
>
> PUT /appdata/john.doe/@self/@app?fields=bar
> post body : {bar : 5}
>
> The data store now has {foo : 3, bar : 5}
> (foo was not deleted because it wasn't in the fields list)
>
>
> PUT /appdata/john.doe/@self/@app?fields=bar
> post body : {foo : 5}
>
> returns a 400 error!
> the post body contains a field that doesn't exist when "fields=bar" so
> this request has a bad format.
>
>
> PUT /appdata/john.doe/@self/@app?fields=bar
> post body : {}
>
> The data store now has {foo : 3}
> (bar was treated as a delete because it wasn't posted)
>
>
> DELETE /appdata/john.doe/@self/@app?fields=bar
>
> The data store now has {foo : 3}
> (nothing happened as bar was already deleted)
>
>
> DELETE /appdata/john.doe/@self/@app
>
> The data store now has {}
> (all fields were deleted because no fields param was specified)
Patrick Mueller
pmu...@gmail.com