Modeling proposal for ReST/Cloud based commands.

3 views
Skip to first unread message

Adrian Cole

unread,
Oct 14, 2009, 3:30:20 PM10/14/09
to reststa...@googlegroups.com, jcl...@googlegroups.com, jclou...@googlegroups.com
Hi, all.

I'd like your opinion on modeling ReST commands on the server side.  I've placed a suggestion for thought on my blog [1].  Please let me know what you think.  The basic idea is to prefer not using entities on commands as it makes retry logic easier.  In such case, we can use Matrix Params instead.

Cheers.
-Adrian
founder jclouds

[1] http://anyweight.blogspot.com/2009/10/rest-be-nice-no-entities-please.html

http://www.reddit.com/r/programming/comments/9u2ic/rest_be_nice_no_entities_please/
http://digg.com/programming/ReST_be_nice_no_entities_please

Bill Burke

unread,
Oct 14, 2009, 5:55:03 PM10/14/09
to reststa...@googlegroups.com
REST is not an RPC model...Or maybe I'm misinterpreting you. Also, the
code examples in your blog are cut off.

--
Bill Burke
JBoss, a division of Red Hat
http://bill.burkecentral.com

Adrian Cole

unread,
Oct 14, 2009, 7:18:51 PM10/14/09
to reststa...@googlegroups.com
sorry.. the rendering is bad in firefox.

Here's the matrix example:

POST http://localhost:8080/objects/robot/action/kill;death=slow HTTP/1.1

Here's the entity example (objects renamed from a real cloud api):

POST http://localhost:8080/objects/robot/action HTTP/1.1
Content-Length: 25

{"kill":{"death":"slow"}}


This is probably more high-level, but if it is rest to address resources as /path/to and operate them with POST, DELETE, etc, it may come naturally for some who are FSMs to offer state transition commands.  In this case, simple command patterns come in handy and are currently in use in compute clouds, for example.

I hope this background helps.  If the topic doesn't fit the list, let me know.
Cheers,
-Adrian

Bill Burke

unread,
Oct 14, 2009, 7:43:17 PM10/14/09
to reststa...@googlegroups.com
Well, the more restful way of doing it would be:

GET of /objects/robot/3333 returns:

{"robot" :
{"name" : "Mr. Roboto",
"links" : [ {"rel" : "kill", "href" :
"http://.../objects/robot/3333/kill", "type" :
"application/x-form-urlencoded}]
}
}

So, the idea is you get the representation of the robot, and the links
define what relationships are to the robot. One of the relationships is
"kill". You follow the link by posting to it:

POST /objects/robot/333/kill

death=slow

GET of /objects/robot/333/kill might return:

"This robot died a slow death"

The thing is here that the URL patterns are irrelevant, the URLs are
opaque, you navigate to them by linking.

Adrian Cole

unread,
Oct 14, 2009, 7:56:49 PM10/14/09
to reststa...@googlegroups.com
Cool. I think we've arrived at the context I'm interested in your opinion on.

POST /objects/robot/333/kill

death=slow

and

POST /objects/robot/333/kill;death=slow

mean the same thing, except the latter is more redirect and replay friendly as it has no content.  What is your opinion on using matrix as opposed to form params for POST args?

Cheers,
-Adrian

Bill Burke

unread,
Oct 14, 2009, 8:10:10 PM10/14/09
to reststa...@googlegroups.com
IMO matrix parameters are part of the identity of the resource.
"death=slow" is a state of /kill, IMO. For example, you could GET /kill
of the robot and it might return a mpeg of the robot's death.

> <mailto:bbu...@redhat.com> <mailto:bbu...@redhat.com

Sam Johnston

unread,
Oct 14, 2009, 8:17:08 PM10/14/09
to reststa...@googlegroups.com, Adrian Cole, occ...@ogf.org
Bill,

Ironically Adrian wrote this post after being prompted by myself and Andy Edmonds from the OCCI-WG following criticism of exactly this approach. I definitely think links are a great way of satisfying the hypertext constraint (formerly known as HATEOAS) but I'm intrigued by what specific problems he has with this approach - e.g. "what could possibly go wrong"?

In many (most?) cases the "actions" are not parametrised in which case the entity-body is empty, but the alternative, doing an empty POST to a parametrised (GET-style) URL, feels [very] wrong. While URLs should be considered opaque, I'm ok with using either semicolons or path segments ('/') to delineate actions:

http://example.com/vm01;start

but the following "feels funky":

http://example.com/disk01;resize=20000

I much prefer:

POST http://example.com/disk01;resize
size=20000

So what we are currently doing for "actions" is a post/redirect/get pattern which I feel is quite elegant in that it allows us to handle more challenging realities such as asynchronous responses (e.g. returning HTTP 201 Accepted with a Location: header which can be monitored ala pubsubhubbub or polled).

Adrian was talking about servers returning 409 Conflict but I don't have a problem with that either - if so the client knows it can try again later and doing anything else (like saving and replaying the request on the server side) doesn't seem right to me either as it's a form of server-side state.

Anyway it's good to see this all starting to coalesce - just need to sort out the nitty gritty details.

Sam

Bill Burke

unread,
Oct 14, 2009, 8:35:30 PM10/14/09
to reststa...@googlegroups.com, Adrian Cole, occ...@ogf.org

Sam Johnston wrote:
> Bill,
>
> Ironically Adrian wrote this post after being prompted by myself and
> Andy Edmonds from the OCCI-WG following criticism of exactly this
> approach. I definitely think links are a great way of satisfying the
> hypertext constraint (formerly known as HATEOAS) but I'm intrigued by
> what specific problems he has with this approach - e.g. "what could
> possibly go wrong"?
>
> In many (most?) cases the "actions" are not parametrised in which case
> the entity-body is empty, but the alternative, doing an empty POST to a
> parametrised (GET-style) URL, feels [very] wrong. While URLs should be
> considered opaque, I'm ok with using either semicolons or path segments
> ('/') to delineate actions:
>
> http://example.com/vm01;start
>
> but the following "feels funky":
>
> http://example.com/disk01;resize=20000
>
> I much prefer:
>
> POST http://example.com/disk01;resize
> size=20000
>
> So what we are currently doing for "actions" is a post/redirect/get

> pattern <http://en.wikipedia.org/wiki/Post/Redirect/Get> which I feel is

> quite elegant in that it allows us to handle more challenging realities
> such as asynchronous responses (e.g. returning HTTP 201 Accepted with a
> Location: header which can be monitored ala pubsubhubbub or polled).
>

Actually, i should have probably said this to Adrian:

POST /robots/333/deaths
death=slow

Then a GET of /robots/333/deaths might returna feed of what the
different deaths were and when.

As for pubsubhubbub, I don't like the reliance on Etag semantics for
polling. Feels like you're tunneling a protocol. I'd much prefer to
send a link back to the client telling it how it can get further (new)
data. I also don't like the reliance on Atom. Atom is fine for text
formats, not great for others. So, what I'm going to do is turn Atom's
(and messaging metadata in general, Atom's metadata isn't something
revolutionary) Into a set of headers and use multipart to send batches.
IMO, multipart is much more appropriate.

Sam Johnston

unread,
Oct 16, 2009, 9:35:15 AM10/16/09
to reststa...@googlegroups.com, Adrian Cole, occ...@ogf.org, Brett Slatkin
On Thu, Oct 15, 2009 at 2:35 AM, Bill Burke <bbu...@redhat.com> wrote:

As for pubsubhubbub, I don't like the reliance on Etag semantics for polling.  Feels like you're tunneling a protocol.  I'd much prefer to send a link back to the client telling it how it can get further (new) data.  I also don't like the reliance on Atom.  Atom is fine for text formats, not great for others.  So, what I'm going to do is turn Atom's (and messaging metadata in general, Atom's metadata isn't something revolutionary) Into a set of headers and use multipart to send batches.  IMO, multipart is much more appropriate.

Just quickly on this point on PuSH, apparently Atom's intended as a bootstrap format, though you and I both know how these things go - once it's burnt into code it's there forever. I'd suggest sharing your concerns with the pubsubhubbub group who are generally fairly responsive (copying Brett - one of the PuSH "instigators").

I'd like to explore the topic of batches (what we call "collections") a bit more as currently I've sidestepped the issue somewhat by specifying text/uri-list be used to pass a list of resources by reference (sans metadata) rather than by value (e.g. embedded in Atom). This requires O(n+1) requests which isn't great for performance but it works it's easily optimised later.

The question then is how to do it. Ideally HTTP would allow us to request a single resource and have it return multiple responses (that is, full blown HTTP responses, headers and all). Technically this would be fairly straightforward, for example by avoiding parsing for boundaries by using content-length as a delineator for the end of this message (and therefore the start of the next) - but it would require a version bump for HTTP. The IETF boffins claim that collections are done in WebDAV but that's all based on XML and is like taking a sledgehammer to a tack. One can use envelope formats like SOAP or Atom but that's also fairly heavy handed. In any case this is unlikely to happen in our timeframes.

Using MIME isn't a bad idea per se, but it does mean your client not only needs to understand multipart/mixed MIME (and scan for boundaries) but then also needs to be able to decipher each of the message/http contained therein. Many clients include support for the former but not the latter. That said the format is trivial, especially given the alternatives, so this may still be both the path of least resistance and the option that is "closest" to HTTP.

Sam

Sam Johnston

unread,
Oct 18, 2009, 4:46:43 AM10/18/09
to Adrian Cole, reststa...@googlegroups.com, occ...@ogf.org
On Fri, Oct 16, 2009 at 9:48 PM, Adrian Cole <adr...@jclouds.org> wrote:

I postulate that regardless of java, python, curl, (name whatever you like), clients will be more efficient and capable on retrying transient failures if they are not required to store entities along with their requests.  I'll challenge anyone to write a test in any language showing parsing entities as faster, more resilient to retries, or more scalable then 0-length requests using matrix or headers for things like this=true or that=2000 :)

Agreed. Another thing to remember is that by diving in the main stream with the entities themselves you're taking on a good deal more work and forcing your clients to do the same. Not only do you have to define some domain-specific language for the task at hand but your clients then have to both parse and understand it which creates a very significant barrier to entry compared to using existing open standards like OVF.

Note that this isn't so much as a change in tack for me as a separation of duties - I'm still far from convinced that OVF is great for the industry (I see it becoming another MS Word document format if we're not careful) but standardising a plain text format like VMX is something we can tackle separately later if need be.

Sam

Reply all
Reply to author
Forward
0 new messages