Rest


#1

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

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)
PUT /categories (send a group of new categories)
POST /categories (update several categories at the same time)
DELETE /categories (delete several categories at the same time)

and

GET /category/#
PUT /category
POST /category/#
DELETE /category/#

At this point, we’ve narrowed it down to one verb, one noun: the object
being acted on, and how it’s being acted on… when we include a second
verb, the concept becomes confused.

Again, comments appreciated wherever you’d like to put them at.

Thanks.


#2

My comment is that you have PUT and POST mixed up. POST is for new,
PUT is for editing.

However, you never mention what your problem is…


#3

Hey,

comments below:

On 6-Apr-07, at 12:54 PM, Luke I. wrote:

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


#4

dasil003 wrote:

My comment is that you have PUT and POST mixed up. POST is for new,
PUT is for editing.

However, you never mention what your problem is…

Hah… what a stupid thing to miss.
But, I think the problem is clearly outlined: I think the way that Rails
by default uses REST architecture is creating confusion. REST is all
about using the HTML methods as verbs and your URLs as nouns… right
now, we are using the same noun to refer to both a collection of things,
and a single thing, and then further confusing the issue by using two
verbs at once (the action name and the HTML method) to take action.

I think we should be using one verb, and separating our nouns out into
the singular and plural cases… but I could be wrong. I’d be happy for
someone to show me why I am.


#5

On 4/6/07, Trevor S. removed_email_address@domain.invalid wrote:

copy the post here.
PUT /categories/create

collection which, IMHO, is wrong.
Here’s my take (I put ‘always’ in quotes because this isn’t dogma,
/categories/123 => a resource (that happens to be a ‘member’)
In the end it looks to me like you’re failing to see the distinction
POST /categories/selected_categories #=> makes no sense, don’t

being acted on, and how it’s being acted on… when we include a
second
verb, the concept becomes confused.

Again, comments appreciated wherever you’d like to put them at.

Thanks.

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] http://www.b-simple.de/documents/download/5


#6

Ok, so one parting comment for the evening:
I was confused on how the verbs interact with the mappings in Rails, and
would like to correct myself, but re-iterate my real point:

You would do
POST /categories
to get to the create action in the categories controller.

This makes more sense than what I though originally, but still makes
less
sense to me than having to seperately defined controllers… one for
interacting with single items such as
POST /category (this would create a single new resource)

And another for interacting with collections
POST /categories (this would be for the times when you want to create
several new items at once)

There have been plenty of people who have posted to this forum with
problems
along this line: how to handle batches of items… to me, this seems to
be
the correct way to do so… separate out what you’re really dealing
with:
either a collection (/categories) or a single item (/category)


#7

On 4/6/07, Trevor S. removed_email_address@domain.invalid wrote:

I’ll

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.

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.

HTH,


#8

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.


#9

On Apr 6, 2007, at 3:49 PM, Luke I. wrote:

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.

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


#10

Hey,

again, comments below:

On 6-Apr-07, at 1:49 PM, Luke I. wrote:

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.

hrm… this looks to me like "here is an updated representation of
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.

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.

/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.

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:

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.

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


#11

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.

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