ActiveResource and a philosophical REST question

For all the REST fans out there, I have two questions.

Usually when we think of RESTful urls, we think in terms of rather simple struct-like objects. The canonical example is using ActiveResource to create person objects:

POST /people <person>   <first_name>Jeff</first_name>   <last_name>Cohen</last_name> </person>

We expect to get back a 201 response with the url to the newly-created resource, like /people/47. If I GET /people/47, I should see the exact same data as when I created it.

My first question is, what if this is not a symmetrical operation? For example, let's say I want to transmit a pizza order:

POST /orders <order>   <name>Jeff</name>   <phone>555-555-1212</phone>   <combo>3</combo> </order>

Here I'm ordering combo #3, which is a actually a large pepperoni, a 6- pack of root beer, and a slice of tiramisu. The server responds with a 201 to /orders/342.

But if I do a GET /orders/342, I might see this:

<order>   <id>342</id>   <name>Jeff</name>   <phone>555-555-1212</phone>   <items>     <item>       <id>1</id>       <desc>18" Pepperoni</desc>       <qty>1</qty>     </item>     <item>       <id>2</id>       <desc>Root Beer</desc>       <qty>6</qty>     </item>     <item>       <id>1</id>       <desc>Tiramisu</desc>       <qty>1</qty>     </item>   </items> </order>

Is this kind of thing acceptable in the REST world? I hope so, because having the client create each step of the hierarchy would be a pain (first create an empty order, then create each line item, etc.)

My second question is, how would I create the pizza order using ActiveResource? In other words, do I need to worry that the attributes that I use for the create action are not the same as the attributes I'll be receiving?

Thanks! Jeff

Of course it's acceptable. There's nothing that says that the client needs to send a hash to the server and the server needs to persist it, and that's all you can do.

Think about what you're trying to do. You're creating a new order resource. What info does it take to do that? Apparently in your case sending a combo ID is sufficient. The server can handle it however you want.

As far as how you create it, I think you just showed us. You pass some info into the controller. This might lead to something like:

class Order < ActiveRecord::Base   ...   def combo=(cid)     c = Combo.find cid     c.items.each {|i| items << i }   end end

or however you choose to implement it.

Pat

Jeff, don’t forget that the server responds to the POST to /orders with ‘201 created’ in the Status header and the URL ‘/orders/342’ in the ‘Location’ header (!).

The actuall content being returned by the POST request is actually:

342 Jeff 555-555-1212 1
 <desc>18" Pepperoni</desc>
 <qty>1</qty>
2 Root Beer 6 1 Tiramisu 1

Instead of the POST’ed parameters and is actually the same content as is retreived by ‘GET /orders/342’.

I hope this clears things up a bit for you.

  • Matthijs

Sorry, I meant what does the client side (the code that's using ActiveResource) look like; or more specifically, will I run into any trouble using ActiveResource to create the order and to retrieve the order, when the parameters are different going and coming (i.e. if ARes is doing any sort of parameter caching, and will I be confusing that caching).

Thanks! Jeff

Some implementations just do a HEAD on the created resource, but you're right that the full xml can be returned as well.

Thanks Jeff