REST

Hey,

comments below:

I posted on this at my blog (http://technodolt.blogspot.com/), and
I'll copy the post here. I'd love comments either place.

So: REST.

I'm having a problem here, and I think my problem derives from the
fact that we are, in reality, using one noun and two verbs.

We are doing

PUT /categories/create

RESTfully speaking, that reads to me like: "here is an updated
representation of the resource at /categories/create" - that doesn't
make much sense to me (explained below).

This has the PUT verb, the create verb, and the categories noun. Shouldn't we re-work the whole concept to be something like:

GET /categories (get an index of categories)

okay

PUT /categories (send a group of new categories)

hrm... this looks to me like "here is an updated representation of
the entire collection at /categories" - i.e. replacing the whole
collection. Then again, maybe the resource at /categories has
attributes which can be updated independent of its children so maybe
that's what it could mean. However, I've seen *many* people try to
do that as a way of doing bulk updates to a *subset* of the
collection which, IMHO, is wrong.

POST /categories (update several categories at the same time)

That should mean "create a new resource (a child) in the /categories
collection"

DELETE /categories (delete several categories at the same time)

Again, no. That means "delete the categories collection".

Here's my take (I put 'always' in quotes because this isn't dogma,
just starting principles):

PUT 'always' means "here's an updated representation of the resource" POST 'always' means "create a new child of the resource" DELETE 'always' means "delete the resource" GET ... duh

But what's "the resource"?

/categories => a resource (that happens to be a 'collection') /categories/123 => a resource (that happens to be a 'member') /categories/new => strictly speaking, another resource - the empty
form you can fill in to POST a new category /categories/123;edit => again, strictly speaking, another resource -
the form you can use to PUT the category

So, remember when I initially said that "PUT /categories/create"
makes no sense? It's because "/categories/create" isn't a resource
IMHO - it's more like RPC. Nothing wrong with that, just that it's
not quite REST.

In the end it looks to me like you're failing to see the distinction
between /categories and "a subset of resources under /categories".
Every situation is different but I'd *start* by treating a subset of
a collection as a different resource:

# order is significant map.resource :selected_categories, :path_prefix => '/categories' map.resources :categories

DELETE /categories/selected_categories?category_ids=[1,2,3,4] PUT /categories/selected_categories POST /categories/selected_categories #=> makes no sense, don't
implement update() in selected_categories_controller

When you find yourself wanting to add verbs, take a shot at adding a
noun.

Remember tho - ultimately this is all a matter of taste, style and
convention rather than 'rules'.

HTH, Trevor

Trevor,

Good comments.

The only thing I'm confused about from OP is his

PUT /categories/create

We don't do that...at least not in Rails. It's the standard POST /categories. So I'm not sure where that came from.

As you pointed out, a lot of the examples don't really make sense, presumably because of OP's lack of distinction between members and collections.

The one thing I'll add is that POST /categories/id doesn't make sense either...and that's because of the difference between PUT and POST.

PUT means "replace or create the resource identified by this URI with this payload" POST means "create a resource with this payload"

The difference is that with POST, you have no idea what the resulting URI is - the web server should give it back to you.

I think OP's problem is not that we're using two verbs and a noun anywhere, but that he just doesn't have a firm grasp on REST and Rails' implementation. There's a really good PDF [1] that ought to be helpful.

Pat

[1] Panel - Tizi-Server.de

Hey,

comments below:

I posted on this at my blog (http://technodolt.blogspot.com/), and I’ll

copy the post here. I’d love comments either place.

So: REST.

I’m having a problem here, and I think my problem derives from the fact that we are, in reality, using one noun and two verbs.

We are doing

PUT /categories/create

RESTfully speaking, that reads to me like: “here is an updated representation of the resource at /categories/create” - that doesn’t

make much sense to me (explained below).

I should have been more specific here and added an id.

This has the PUT verb, the create verb, and the categories noun. Shouldn’t we re-work the whole concept to be something like:

GET /categories (get an index of categories)

okay

PUT /categories (send a group of new categories)

hrm… this looks to me like “here is an updated representation of the entire collection at /categories” - i.e. replacing the whole collection. Then again, maybe the resource at /categories has

attributes which can be updated independent of its children so maybe that’s what it could mean. However, I’ve seen many people try to do that as a way of doing bulk updates to a subset of the collection which, IMHO, is wrong.

I would ask: why is this wrong? Why can’t categories, in this case, refer to any collection of categories, whether that be the entire collection, or a subset of such? To me, pluralizing simply means more than one, not the whole thing.

POST /categories (update several categories at the same time)

That should mean "create a new resource (a child) in the /categories

collection"

I think that you are inferring here because you are already familiar with this layout. To me, it seems the natural inference from POST /categories means that you are posting (updating) more than one category… again, categories is a plural, so when it is used as the noun, to me, that means it should ALWAYS be referring to a plural… you shouldn’t even be able to use /categories/ to reference a singular item… it should always be referring to a plural item.

DELETE /categories (delete several categories at the same time)

Again, no. That means “delete the categories collection”.

And again, I disagree… it means delete a collection of categories; there is no reason it must mean delete the ENTIRE collection of categories, simply a collection in general.

Here’s my take (I put ‘always’ in quotes because this isn’t dogma, just starting principles):

PUT ‘always’ means “here’s an updated representation of the resource” POST ‘always’ means “create a new child of the resource”

DELETE ‘always’ means “delete the resource” GET … duh

I agree completely.

But what’s “the resource”?

/categories => a resource (that happens to be a ‘collection’) /categories/123 => a resource (that happens to be a ‘member’)

Here is where I think the current idiom breaks apart. Your noun is still implying a collection. If anything, I would think that the resource that should be presented here (if available) is a collection of categories that can somehow grouped together by the id 123.

/categories/new => strictly speaking, another resource - the empty form you can fill in to POST a new category

/categories/123;edit => again, strictly speaking, another resource - the form you can use to PUT the category

So, remember when I initially said that “PUT /categories/create” makes no sense? It’s because “/categories/create” isn’t a resource

IMHO - it’s more like RPC.

Exactly… except, this is the default methodology of Rails… you have all the actions like /categories/new /categories/create /categories/3;

I think this last one is exactly revelatory of what I’m trying to say: instead of referring to collections and single instances differently (/categories, /category), we are forcing ourselves to refer to single instances as a member of said collection, instead of as a resource in and of themselves.

Nothing wrong with that, just that it’s not quite REST.

In the end it looks to me like you’re failing to see the distinction

between /categories and “a subset of resources under /categories”. Every situation is different but I’d start by treating a subset of a collection as a different resource:

order is significant

map.resource :selected_categories, :path_prefix => ‘/categories’ map.resources :categories

This is useful in some situations… but not, I think, in what I’m talking about… there are definitely reasons to set up new nouns for special referencing a set of resources… however, I think the default way should still be to have /categories refer to a collection (any collection, not necessarily the whole thing) of resources, and /category refer to a singular instance.

DELETE /categories/selected_categories?category_ids=[1,2,3,4] PUT /categories/selected_categories

POST /categories/selected_categories #=> makes no sense, don’t implement update() in selected_categories_controller

When you find yourself wanting to add verbs, take a shot at adding a noun.

Remember tho - ultimately this is all a matter of taste, style and convention rather than ‘rules’.

Agreed… however, I think that the default style of mappings used by Rails now will ultimately confuse people on what exactly REST is, and how it should be implemented.

Agreed that I don’t have as strong a grasp as I would like on Rails implementation of REST… but, that’s why I’m asking this question (and arguing my point) now… if I continue down the road of using Rails’s REST implementation, then I believe I would no longer pose this question: not because it is invalid, but because what Rails is using works, and so why try to change it?

I’m posting now, before I get to set into “the rails way”, so that I am more willing to defend myself and fight what’s being said, as opposed to just fall back on the argument of “what we have works, so why change it”.

NOT that I’m implying that is what’s being said by anyone else… just pointing out why I would start in on this before being 100% comfortable with what we have at hand.

Standard Rails REST practice doesn't use create

GET /resources => the list of resources GET /resources/new => the form for a new resource POST /resources => create a resource GET /resources/ID => an individual resource GET /resources/ID;edit => form to edit an individual resource PUT /resources/ID => update a resource DELETE /resources/ID => delete a resource

There are also singleton resources, like

GET /cart POST /cart PUT /cart DELETE /cart

Hey,

again, comments below:

Hey,

comments below:

I posted on this at my blog (http://technodolt.blogspot.com/), and I’ll copy the post here. I’d love comments either place.

So: REST.

I’m having a problem here, and I think my problem derives from the fact that we are, in reality, using one noun and two verbs.

We are doing

PUT /categories/create

RESTfully speaking, that reads to me like: “here is an updated representation of the resource at /categories/create” - that doesn’t make much sense to me (explained below).

I should have been more specific here and added an id.

I have no idea how adding an id to /categories/create makes any more sense… sorry.

This has the PUT verb, the create verb, and the categories noun. Shouldn’t we re-work the whole concept to be something like:

GET /categories (get an index of categories)

okay

PUT /categories (send a group of new categories)

hrm… this looks to me like “here is an updated representation of the entire collection at /categories” - i.e. replacing the whole collection. Then again, maybe the resource at /categories has attributes which can be updated independent of its children so maybe that’s what it could mean. However, I’ve seen many people try to do that as a way of doing bulk updates to a subset of the collection which, IMHO, is wrong.

I would ask: why is this wrong? Why can’t categories, in this case, refer to any collection of categories, whether that be the entire collection, or a subset of such? To me, pluralizing simply means more than one, not the whole thing.

I think it’s wrong for 2 reasons. 1 - allowing PUT on the collection makes me fight the framework (rails) and I’ve got better things to do :slight_smile: and 2 - rightly or wrongly, routes and URLs are a pretty handy if-statement. I don’t have to clutter my categories controller with “am I the collection or am I a subset of the collection”. If I need to operate on a subset I end up writing less code if I create another controller and let the URL decide what I’m supposed to be doing.

POST /categories (update several categories at the same time)

That should mean “create a new resource (a child) in the /categories collection”

I think that you are inferring here because you are already familiar with this layout. To me, it seems the natural inference from POST /categories means that you are posting (updating) more than one category… again, categories is a plural, so when it is used as the noun, to me, that means it should ALWAYS be referring to a plural… you shouldn’t even be able to use /categories/ to reference a singular item… it should always be referring to a plural item.

From the http spec:

“The POST method is used to request that the origin server accept the entity enclosed in the request as a new subordinate of the resource identified by the Request-URI in the Request-Line.”

POST /categories means create a new subordinate of /categories.

it’s got nothing to do with singular vs plural - it’s got to do with subordinates - whether you thing a subordinate of /categories has to be literally prefixed with /categories/ is up to you - I tend to favor it myself.

DELETE /categories (delete several categories at the same time)

Again, no. That means “delete the categories collection”.

And again, I disagree… it means delete a collection of categories; there is no reason it must mean delete the ENTIRE collection of categories, simply a collection in general.

Here’s my take (I put ‘always’ in quotes because this isn’t dogma, just starting principles):

PUT ‘always’ means “here’s an updated representation of the resource” POST ‘always’ means “create a new child of the resource” DELETE ‘always’ means “delete the resource” GET … duh

I agree completely.

But what’s “the resource”?

/categories => a resource (that happens to be a ‘collection’) /categories/123 => a resource (that happens to be a ‘member’)

Here is where I think the current idiom breaks apart. Your noun is still implying a collection. If anything, I would think that the resource that should be presented here (if available) is a collection of categories that can somehow grouped together by the id 123.

And suddenly I think I understand the disconnect here. For me, just because the url has /categories in it doesn’t mean that the resource I’m referencing is a collection of categories.

Take, for example, /categories/100/products/50 - there’s nothing there that says to you “the resource presented here is a collection of categories that can somehow be grouped together by ‘100/products/50’” is there?

The entire URL is what makes the resource unique. You can infer (by chopping off path components) containing ‘parents’ of your resource, but that doesn’t mean you are an instance of your parent resource’s type - you are just contained by it somehow.

/categories/new => strictly speaking, another resource - the empty form you can fill in to POST a new category /categories/123;edit => again, strictly speaking, another resource - the form you can use to PUT the category

So, remember when I initially said that “PUT /categories/create” makes no sense? It’s because “/categories/create” isn’t a resource IMHO - it’s more like RPC.

Exactly… except, this is the default methodology of Rails… you have all the actions like /categories/new /categories/create /categories/3; I think this last one is exactly revelatory of what I’m trying to say: instead of referring to collections and single instances differently (/categories, /category), we are forcing ourselves to refer to single instances as a member of said collection, instead of as a resource in and of themselves.

Well, IMHO that’s because they are subordinates of the collection. But that’s just my taste and the good news is you don’t have to agree with me - see below:

Nothing wrong with that, just that it’s not quite REST.

In the end it looks to me like you’re failing to see the distinction between /categories and “a subset of resources under /categories”. Every situation is different but I’d start by treating a subset of a collection as a different resource:

order is significant

map.resource :selected_categories, :path_prefix => ‘/categories’ map.resources :categories

This is useful in some situations… but not, I think, in what I’m talking about… there are definitely reasons to set up new nouns for special referencing a set of resources… however, I think the default way should still be to have /categories refer to a collection (any collection, not necessarily the whole thing) of resources, and /category refer to a singular instance.

Have you looked at http://agilewebdevelopment.com/plugins/resource_hacks yet? It allows you to specify the :member_path which would clean up your URLs into something you prefer - a starting point anyhow.

DELETE /categories/selected_categories?category_ids=[1,2,3,4] PUT /categories/selected_categories POST /categories/selected_categories #=> makes no sense, don’t implement update() in selected_categories_controller

When you find yourself wanting to add verbs, take a shot at adding a noun.

Remember tho - ultimately this is all a matter of taste, style and convention rather than ‘rules’.

Agreed… however, I think that the default style of mappings used by Rails now will ultimately confuse people on what exactly REST is, and how it should be implemented.

Okay, and like I said this is all a matter of taste etc - and don’t take offense… but that statement has me inferring that you feel you know the proper way that REST should be implemented. And yet you’ve shown a lack of understanding over something pretty simple/fundamental in the mechanics of the POST verb.

With a big smile to avoid any nasty arguments…

Trev

I think it’s wrong for 2 reasons. 1 - allowing PUT on the collection makes me fight the framework (rails) and I’ve got better things to do :slight_smile: and 2 - rightly or wrongly, routes and URLs are a pretty handy if-statement. I don’t have to clutter my categories controller with “am I the collection or am I a subset of the collection”.

In almost all cases, there is no need for this: POST: no need, as post is creating new information, and therefore, any information included is obviously an addition to what currently exists

PUT: no need… it is to update information… you parse the information supplied, and update the resources contained in the supplied information as requested GET: This requires no more logic than is already in use to determine if someone requests GET /categories or GET /categories/123

DELETE: This is the only one that requires more logic, and it could be written in exactly the same way that GET is: if no additional specifications are supplied, it refers to the entire resource, otherwise, it refers to a specified subset of the resource

If I need to operate on a subset I end up writing less code if I create another controller and let the URL decide what I’m supposed to be doing.

Indeed… and what you are suggesting (creating seperate controllers for specific subsets of items) makes a lot of sense… I just think that you should do it in addition to what I’m saying, as opposed to to replace what I’m saying.

From the http spec:

“The POST method is used to request that the origin server accept the entity enclosed in the request as a new subordinate of the resource identified by the Request-URI in the Request-Line.”

POST /categories means create a new subordinate of /categories.

Indeed… but there is nothing in that specification that says “the singular entity enclosed”… it could just as easily be referring to a collection of items.

it’s got nothing to do with singular vs plural - it’s got to do with subordinates - whether you thing a subordinate of /categories has to be literally prefixed with /categories/ is up to you - I tend to favor it myself.

And suddenly I think I understand the disconnect here. For me, just because the url has /categories in it doesn’t mean that the resource I’m referencing is a collection of categories.

I guess what I see as our disconnect is I think that the resources referred to should be semantically meaningful: if you refer to a resource as “categories”, it should be categories, not A category.

Take, for example, /categories/100/products/50 - there’s nothing there that says to you “the resource presented here is a collection of categories that can somehow be grouped together by ‘100/products/50’” is there?

No, it says to me: The resource presented here is the collection of products grouped together by ‘50’ which is a subordinate of the collection of categories grouped together by ‘100’.

The entire URL is what makes the resource unique. You can infer (by chopping off path components) containing ‘parents’ of your resource, but that doesn’t mean you are an instance of your parent resource’s type - you are just contained by it somehow.

Agreed.

Well, IMHO that’s because they are subordinates of the collection. But that’s just my taste and the good news is you don’t have to agree with me - see below:

Have you looked at http://agilewebdevelopment.com/plugins/resource_hacks yet? It allows you to specify the :member_path which would clean up your URLs into something you prefer - a starting point anyhow.

Agreed… however, I think that the default style of mappings used by Rails now will ultimately confuse people on what exactly REST is, and how it should be implemented.

Okay, and like I said this is all a matter of taste etc - and don’t take offense… but that statement has me inferring that you feel you know the proper way that REST should be implemented.

This is not at all how I intended to come off. It seemed to me that the Rails implementation of REST wasn’t correctly REST, and I was wrong; it is. It is simply working on a different understanding of how the “nouns” in REST should be used in reference to collections vs singular resources than I am… I think you should always be 100% explicit with your noun in whether it’s referring to a collection or a singular instance.

And yet you’ve shown a lack of understanding over something pretty simple/fundamental in the mechanics of the POST verb.

I don’t think I have a lack of understanding… I simply understand it to mean something different than you do.

With a big smile to avoid any nasty arguments…

Trev

I am not one for big nasty arguments… I really believe that this kind of dialog is the best way to learn. I am still not convinced that I am right and you are wrong… but I will keep valiantly arguing my side of this argument until you have proven all my points wrong. You have already proved numerous points wrong… but I believe I still have at least some room to stand on… and please, don’t give up on convincing me. You see, I would truly be 100% as happy with my saying “you were right, I was wrong” as I would be if you were to say “you were right, I was wrong”… and of course, the best possible result being “we were both right, and just share different views of the same thing”.

I simply want to understand REST and Rails better… and I think the best way to do so is to state what I think I know and what I see, and have someone vindicate that position, or instruct me on how I’m wrong.

Thanks for the dialog :slight_smile:

Luke