0

I have read several tutorials to introduce myself to know more about the rest API recently. However, I have got some doubts here and there and hope someone can help me out with this.

Reading the Beginner's Guide to HTML and REST, which states:

"Resources are best thought of as nouns. For example, the following is not RESTful:

1 /clients/add

This is because it uses a URL to describe an action. This is a fairly fundamental point in distinguishing RESTful from non-RESTful systems."

As such, I was wondering if for such cases where I have a user resource and to access it to do the usual insert/update/delete/retrieve

would be as follow:

www.example.com/users [get] <-- to retrieve all records
www.example.com/users/1 [get] <-- to retrieve record with id of 1
www.example.com/users/1 [put] <-- to update record with id of 1
www.example.com/user/1 [delete] <-- to delete record with id of 1
www.example.com/user [post] <-- to insert a new user record

This would have used up the 4 common verbs to make request.

What if I were to require a function such as login or perhaps in general any other types of action commands? How should the url be formed and how should the router redirect in such cases?

EDIT:

After looking at the various comments and answers. My take away from them is that the final solution would be somewhere along "use rest principles whenever possible and use the query string method with functions whenever not."

However, I was thinking of a slight variant of the implementation (not a restful implementation anymore, but following similar concepts) and wondering if it could have work out this way. Hope you guys can advice me on this.

Using the same authenticate/login function I would require to implement, could it be something along this instead:

www.example.com/users [get] <-- to retrieve all records
www.example.com/users/1 [get] <-- to retrieve record with id of 1
www.example.com/users/1 [put] <-- to update record with id of 1
www.example.com/user/1 [delete] <-- to delete record with id of 1
www.example.com/user [post] <-- to insert a new user record

as usual and if I were to require an action to be performed it will be as such:

[controller]/[action] --- user/authenticate [post] --- to login
[controller]/[id]/[action] --- user/1/authenticate [put] --- to logout

Will this work? Will there be any foreseen problems that I would face and are there similar implementations out there like this already? Please kindly advice!

questions.
  • 26
  • 1
  • 4
  • The login function does not fit in the REST paradigm. – leftclickben Feb 05 '13 at 11:13
  • @leftclickben Thanks for your reply. In such a way, how should I implement a login/authentication feature using the REST Api? Does this apply to every general aspect as well? Such as having the need to create some action/functions for a particular resource (other than insert/update/delete/retrieve information directly from the resource? – questions. Feb 05 '13 at 11:20
  • Well, see answer from Neville K, but in my opinion using REST for login is trying to shoe-horn something that doesn't fit. Use REST when you need it, don't force it on yourself in every circumstance :-) – leftclickben Feb 05 '13 at 11:22
  • @leftclickben Does it means that the solution will end up to have various forms of requesting for the api? Like using REST for retrieve/insert/update/delete for the resource, while actions using the usual methods like passing in parameters in the url or post and a function name which executes the action? – questions. Feb 05 '13 at 11:33
  • Yes you are right, but I think this is inherent in what login is and what REST is. In REST, you are accessing resources, and you have 8 different actions depending on which method you are using and whether you are hitting a collection or an element. All 8 of these methods do not map to login, in fact none of them map particularly cleanly. Login and logout are plainly _actions_ and while the implementation of those actions requires resources, the action itself does not map directly to any resource. – leftclickben Feb 05 '13 at 11:41
  • @leftclickben Thanks! I think I have understood it better now. So as long it doesn't map to any resource, I shan't use the RESTful way to implement the API? However, will this make the API in some way messy or tough to use, because of it's inconsistency? – questions. Feb 05 '13 at 11:44

3 Answers3

1

REST is stateless so you need to put all the needed information into all queries. The idea is to work with the HTTP Verbs (GET, PUT, DELETE, POST - as you already descripted).

If you want an user authentification for your REST API, use something like HTTP Basic Auth, or your own Authentification. You have to send the Auth Information for every Request to the Server (stateless).

If you don't want an HTTP Basic Auth you can try some Token Authentification or any other auth.

Edit: If you want an "Check Login" Resource, build your own. For Example GET /account/checklogin with http basic auth header informations. The Result of this Request depends on your Authinformations.

take
  • 2,154
  • 2
  • 17
  • 36
  • Thanks for your reply! Yeah I was thinking of using my own auth tokens and sending it for every request to make it stateless. However, I would still require some "actions" for some resources. Does that still render it as stateless? – questions. Feb 05 '13 at 22:39
0

There are some actions that are hard to model in a true RESTful way - but login, for instance, can be implemented using the following pseudo code:

GET the user rights whose userID is x and password is y
if (user rights found)
  assign rights to current user
else
  do not assign rights to user

See this question for how to retrieve the user rights. The point in this question is that you usually need multiple ways of accessing your resources. Some are based on IDs or well-know attributes, for instance:

  • www.example.com/users/department [get] (get all users for a department)
  • www.example.com/users/roleName [get] (get all users in a particular role)
  • www.example.com/users/status/active [get] (get all users who are "active")

However, some ways of accessing users - especially when you need to combine two or more filtering attributes - are easier to manage using query string parameters. For instance:

www.example.com/users?department=xxx&role=yyy&status=active [get]

So, your REST API might expose a URL along the lines of:

www.example.com/users?userName=xxxx&password=yyy [get]

This URL would match the username and password parameters against the user database, and return either a 404 (if they don't match a known user), or a document representing the user, with their access rights.

Your client code then manages the current user's session - i.e. by setting the status to "logged in ", and associating the session with that user profile.

The key to making this work is assigning responsibility to the right layer - the API should not have to manage user sessions, that is the responsibility of the client application. There are cases where that doesn't work particularly well - not sure if yours is one, though.

If you really want to use a POST request, you can, of course, consider the "login" method the start of a session for that user. You could, therefore, do something like this:

www.example.com/session [POST] with parameters userID and password.

This would return a representation of the user profile and rights; it might also create documents accessible under the URLs

www.example.com/session/sessionID

www.example.com/session/user/ID/session

However, in general, it is a very dangerous idea to manage session state within the API - nearly always, you want the client session to be managed by the application interacting with the client, not by the API it talks to.

Community
  • 1
  • 1
Neville Kuyt
  • 27,150
  • 1
  • 34
  • 48
  • Thanks for your reply. I hope I have understand the question you have linked correctly. It explains the two different methods of passing in parameters to the server and which practice would be more applicable for whichever purpose. Please correct me if I have interpreted it wrongly. However, I am curious to find out how should actions be performed/executed through the REST concept. Or perhaps like what leftclickben and you mentioned, some actions are hard to model the true RESTful way and should be done in the normal way instead? – questions. Feb 05 '13 at 11:41
  • I'll update the answer to clarify - but many people would argue that RESTful _is_ the normal way! – Neville Kuyt Feb 05 '13 at 11:52
  • Thanks! Probably the word "normal" here is a little ambigious. Because the usual way I have been trying to work on is to send post/get request accordingly with a function parameter in the url stating which function in the script it should execute. – questions. Feb 05 '13 at 11:56
  • Would this also mean that in the user controller file, I would have to listen to the various types of parameters being passed in and react accordingly? – questions. Feb 05 '13 at 12:07
  • Updating the answer - but yes, you do. – Neville Kuyt Feb 05 '13 at 12:13
  • Thanks for the updates. I think I understood your explanation. But I doubt my api would be that complex, requiring so many filters yet. But I will keep that in mind when I write. I have just edited my question based on the comments and answers received. Could you please help me have a look too? Thanks! – questions. Feb 05 '13 at 13:09
  • I've updated the answer again. Query string parameters are RESTful - they just identify a resource in a different way to the path. Actions are not RESTful. – Neville Kuyt Feb 05 '13 at 20:38
  • Thanks for the update. Yeah, I think I kind of understand that actions are restful after your explanations. But I am just worried that having a mixed of query strings and path variables method of querying the api would be kinda confusing and messy just to add some "actions" to rest. – questions. Feb 05 '13 at 22:44
0

What if I were to require a function such as login or perhaps in general any other types of action commands? How should the url be formed and how should the router redirect in such cases?

It's not RESTful to have a login-action resource, but it is RESTful to provide a login-form resource:

/login-form

The HTML-form you return in the response functions as code-on-demand; you are supplying a configured piece of software to help the user supply their login credentials.

There would be nothing wrong with identifying the resource as just /login - I added the form-part to make the example clear.

You should avoid redirects where auth is required because it breaks the interface for clients other than web-browsers; instead you might either: provide a link to the login-form; or actually supply the login-form code in the response.

If you want to manage authentication, I prefer the approach of creating auth-tokens; in the case of Web-browsers I consider it acceptable to overload a single cookie for the purpose of helping the client supply the token with each request since they will have no other reasonable way to control the Auth header they send; obviously if you're writing your own client-application this is not a concern.

Answering your comments below, the purpose of the login form in an auth-token scenario is to create a new authentication token. So, thinking RESTfully, you model the users list of auth-tokens and POST a representation of the auth-token. This representation might contain the user's username and password. You might let the user choose their own token, or you might choose it for them and return this in the response. There is no action-URI required, and setting any cookies happens following successful creation of the new auth-token.

I recommend studying Amazon S3 REST API. It's slightly different than your requirement but its the best in-depth description of a potential REST authentication system I've seen set out:

http://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAPI.html

Your thoughts on managing users RESTfully are accurate.

Hope it helps :)

simony
  • 281
  • 2
  • 4
  • Thanks for your reply. I was just curious, by sending the client a form instead or a link, wouldn't it still require an function to accept the return values from the form in the action field? – questions. Feb 05 '13 at 22:33
  • Yeah, I was considering to use the auth token concept where I will store the id and auth token of the user on the client side(cookie) where he will send in this two necessary information before probing the api for data. – questions. Feb 05 '13 at 22:36
  • Updated answer.. Hope that covers it? – simony Feb 09 '13 at 22:51