Confused about REST and custom actions

Robert Walker wrote:
[...]

From my experience starting off with an incorrect assumption about what
something is can engrain bad habits that are hard to break later.

Fair enough. I do agree with you there.

It's
best, at least for me, to approach learning something new by
understanding the theory behind it and only then applying that theory to
daily practice.

To some extent. But I think that in this case, the theory is a little
too weird to focus on before at least a little practical experience has
been had.

Best,

As this thread is about REST and custom actions then I'll post a
question here.

I have a REST client, it will be working with a non-Rails application,
but for initial development and testing I'm using a separate Rails REST
server to emulate the non-Rails app.

As part of the sequence of actions, a customer will log in and pass
their id and password information to the REST server and get back a
valid account (with ActiveResource as ancestor not ActiveRecord).

Following the pattern described in
http://api.rubyonrails.org/classes/ActiveResource/CustomMethods.html I
have a custom method 'authorize' and routes set up in client and server
as

map.resources :accounts,:new => { :authorize => :post }

If I'm reading the example right then when I do this

Account.new(:email=>'test@test-company.com',:password=>'123test').post(:authorize)

I'm expecting to get back an account id. But I don't, I get
#<Net::HTTPOK 200 OK readbody=true>
and the new account resource doesn't have the id set up.

So what am I doing wrong?

John Small wrote:

map.resources :accounts,:new => { :authorize => :post }

what is :new => { :authorize => :post }

Shouldn't that be something like:

map.resources :accounts, :collection => { :authorize => :post }

But, this does bring up an interesting extension to this discussion
about resources.

In your example your mapping is essentially say this:
POST: http://example.com/accounts/authorize

According to this, sending a POST to authorize should "create" a new
account. That's not, however, what you're really wanting to do. What's
really going on in terms of REST is that you are creating a new session.

Session is not necessarily an ActiveRecord model object, yet it
certainly can be a resource. Now with that in mind, the design is back
to basic CRUD actions. No custom actions are required.

When you want a new session you POST to the session resource collection.
When you want terminal a session you send a DELETE to the session
resource collection. You can then back the session resource with it's
own controller containing the create and destroy actions.

It's also okay to have more than one URI that refers to the session
resource.

So:
POST: http://example.com/session
and
POST: http://example.com/login

Could both reference the same action of the same resource performing the
same function.

Likewise:
DELETE: http://example.com/session
and
POST: http://example.com/logout

Could also both have the same functionality of deleting an active
session effectively logging out.

In your example your mapping is essentially say this:
POST: http://example.com/accounts/authorize

According to this, sending a POST to authorize should "create" a new
account. That's not, however, what you're really wanting to do. What's
really going on in terms of REST is that you are creating a new session.

Session is not necessarily an ActiveRecord model object, yet it
certainly can be a resource. Now with that in mind, the design is back
to basic CRUD actions. No custom actions are required.

You're quite right it is creating a session. I was just using the
example given in the ActiveResource documentation as a starting point to
see if it did what it says it should. It doesn't.

The other thing is that the REST server isn't a Rails application in
this case. I'm using Rails to act as a front end to a legacy Windows
application.

I've worked out how to deal with the data that comes back and convert it
into an account ActiveResource, so I'll change the naming a bit to make
it clear that we're starting a session not creating a new record and
move on.

Thanks for the hint

John Small