tags:

views:

1082

answers:

3

I see two types of examples in various places. One uses form fields like

curl -X PUT -d "phone=123.456.7890" "http://127.0.0.1/services/rest/user/123"

and the other uses an XML content like (some variation of) this

echo "<user><id>123</id><phone>123.456.7890</phone></user>" | curl -X PUT -d @- "http://127.0.0.1/services/rest/user/"

It seems like using the form fields has the advantage of brevity and clearly identifying the client's intent by targeting just the modified fields, but makes it awkward to address "deeper" metadata.

Using the XML content has an advantage of being more complete, but the disadvantage of the overhead of figuring out which field the client is actually modifying (assuming that they send back the entire resource with small modifications).

Is there a best practice, or even a more-common practice?

A: 

In the second example URL does not refer to a specific resource, so IMHO it's not RESTful.

If you fix that, the choice comes down to form and XML encoding.

If you need structured and extensible data, then XML might be useful:

<phone type="work, mobile"><num>555-555</num><ext>123</ext></phone>

but not neccessary:

phone=555-555&phone-ext=123&phone-type=work&phone-type=mobile

Lots of API users may get XML encoding wrong, have trouble grasping namespace indirection, so form encoding might be better for wide audience.

porneL
A: 

Good question! I don't know of a specific best practice or common practice. But I do want to point out that the question isn't really about form fields or XML, it's about partial representations vs. full representations. You've succinctly described the practical differences between them. One aspect of the question is who has the responsibility to determine what has changed: the client or the server.

A hybrid option would be some kind of format wherein a client could specify what exactly has changed, using some syntax to point to "deeper" metadata, such as XPath or JSONpath, along with the new value.

Avi Flax
+1  A: 

It could be something like JSON(P)? (I'm not sure about exact syntax):

$ echo '{user: {id: 123, phone: 123.456.7890}}' |\
> curl -X PUT -d @- 'http://127.0.0.1/services/rest/user/'

Or

$ echo '{phone: 123.456.7890}' |\
> curl -X PUT -d @- 'http://127.0.0.1/services/rest/user/123.json'
J.F. Sebastian