Forum: Ruby on Rails REST

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
2017657725dd1bce83dc8a1e2e991d04?d=identicon&s=25 Luke Ivers (technodolt1)
on 2007-04-06 21:54
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.
6e9db38e16957cc51cf9cee9de399249?d=identicon&s=25 dasil003 (Guest)
on 2007-04-06 22:03
(Received via mailing list)
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...
2017657725dd1bce83dc8a1e2e991d04?d=identicon&s=25 Luke Ivers (technodolt1)
on 2007-04-06 22:22
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.
27c170f482104299af279902be0a9c26?d=identicon&s=25 Trevor Squires (Guest)
on 2007-04-06 22:36
(Received via mailing list)
Hey,

comments below:

On 6-Apr-07, at 12:54 PM, Luke Ivers 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
42172acdf3c6046f84d644cb0b94642c?d=identicon&s=25 Pat Maddox (pergesu)
on 2007-04-06 22:48
(Received via mailing list)
On 4/6/07, Trevor Squires <trevor@protocool.com> 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
2017657725dd1bce83dc8a1e2e991d04?d=identicon&s=25 Luke Ivers (technodolt1)
on 2007-04-06 22:52
(Received via mailing list)
On 4/6/07, Trevor Squires <trevor@protocool.com> 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
<any verb> /categories/<any action> 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;<action here>
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,
2017657725dd1bce83dc8a1e2e991d04?d=identicon&s=25 Luke Ivers (technodolt1)
on 2007-04-06 23:18
(Received via mailing list)
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)
2017657725dd1bce83dc8a1e2e991d04?d=identicon&s=25 Luke Ivers (technodolt1)
on 2007-04-06 23:22
(Received via mailing list)
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.
F5d61a3c93217e393cfdf7bf5c7ac628?d=identicon&s=25 Michael D. Ivey (Guest)
on 2007-04-06 23:31
(Received via mailing list)
On Apr 6, 2007, at 3:49 PM, Luke Ivers wrote:
> Exactly... except, this is the default methodology of Rails... you
> have all the actions like
> /categories/new
> /categories/create
> /categories/3;<action here>
> 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
27c170f482104299af279902be0a9c26?d=identicon&s=25 Trevor Squires (Guest)
on 2007-04-06 23:44
(Received via mailing list)
Hey,

again, comments below:

On 6-Apr-07, at 1:49 PM, Luke Ivers 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 :-) 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 <any verb> /
> categories/<any action> 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;<action here>
> 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
2017657725dd1bce83dc8a1e2e991d04?d=identicon&s=25 Luke Ivers (technodolt1)
on 2007-04-09 21:01
(Received via mailing list)
>
> 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 :-)
> 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 :)

Luke
This topic is locked and can not be replied to.