As far as REST APIs go, which is the better structure to follow in general?
Assume GET/PUT/POST/DELETE for all resources.
1) Use currently signed in user for /users/**/* routes.
/users
/users/password
/users/email
/users/preferences
/users/documents
/documents/:id
2) Having absolute paths with IDs and using /users/:id for currently signed in user?
/users
/users/:id/password
/users/:id/email
/users/:id/preferences
/preferences/:id
Does it matter?
If the resource you are referring can be multiple, you should go with
/resource/resource_id
In the above case, user can only be the current person, so using a pattern like /users/user_id, sounds odd. Because, you will have to handle different cases like What if a logged in USER A triggers an api call with a different user-id USER B??
You can have a namespace like /profile for managing the email, name, image etc. You don't have to make it as /users/profile as it is implicit that the data is going to be manipulated / accessed for the current logged in user.
Both are fine. What's nice about creating unique endpoints for every user, is that one day you can allow user X to access information about user Y.
The pattern I followed in a recent API was to create a unique endpoint for every user, but 1 endpoint /current-user that redirects to the /user/:some-id.
A url might indicate an identity. It makes a lot of sense that other resources might refer to user as a 'creator' or 'modifier' of sommething, and in those places you might want to use a url (and not just a userId).
Related
Long Version
For some, myself included, one of the most painful and headache causing parts of building a REST API is determining the name for each resource and the accompanying endpoints.
Whilst it is, of course, down to personal preference; there are certain things that are encouraged by the community. For example, most people, including me, will pluralise their resource names:
GET /notifications
POST /posts
However, there are cases where pluralising just doesn't seem correct. Consider the following example where user essentially represents the logged in user, not the entire users resource:
Endpoints only relevant to the authenticated user
// Phone Verification
POST /user/phone/request
POST /user/phone/resend
POST /user/phone/verify
// User creation based on authenticated and verified phone
POST /user
// Update authenticated user's profile
PUT /user
// Delete the authenticated user
DELETE /user
// Add/remove the authenticated user's profile image
POST /user/image
DELETE /user/image
// Update the authenticated user's device token
PUT /device/token
Endpoints that access the entire users resource
GET /user
GET /user/{id|self}
In the above example, to me, it feels like the singular user resource name is more suited given on the majority of the endpoints, user refers to the authenticated user, not the entire database of users. But, on the other hand, having GET /user return all users just seems plain wrong...
As a result, I am now torn between user and users - both have strong arguments either way as I see it but would very much welcome another person's opinion on the matter...
Short Version
TLDR - To put it simply, consider the following two endpoints:
// Get all users
GET /users
// Update the authenticated user's device token
PUT /user/device
Both of the above seem correct in my eyes. The problem with the above is that there is no way I am going to have both user and users, it has to be one or the other in my opinion.
The dilemma; Why would I use user when the resource refers to the entire users database? Why would I use users when the resource only refers to the authenticated user?
I cannot get my head around this one... Anyone got any thoughts on this? Or, even better, an alternative solution to my proposed endpoint structure?
Update
After some deep thinking, I have come up with an alternative solution to this but I am still not 100% sure on it as I am not overly keen on using the auth resource name.
Consider this:
// auth = authenticated user
// users = users collection
POST /auth/request
POST /auth/resend
POST /auth/verify
POST /auth
PUT /auth
DELETE /auth
POST /auth/image
DELETE /auth/image
PUT /auth/device/token
GET /users
GET /users/{id}
There are obviously different opinions on this matter, the answer below contains my personal views.
The bottom line is that it's all quite subjective and depends on the way one looks at a certain (type of) resource.
Why would I use user when the resource refers to the entire users
database?
In my opinion, you should never use singular for an endpoint that contains multiple resources.
Some people, however, argue that we should stick to singulars for all resources, mostly for the sake of simplicity and uniformity.
Why would I use users when the resource only refers to the
authenticated user?
You will find quite some different opinions on this, but the consensus and most widely adopted is generally to stick with plurals, except for resources that can only contain a single item (for example, a user profile only containing only one avatar).
Also, since using a singular form for the users resource wouldn't make sense following the above logic, we don't want to mix singular and plural names.
// Update the authenticated user's device token
PUT /user/device
You can interpret 'updating the authenticated user's device token' as follows:
Add a device token to a user entity of the users resource collection.
If your API supports view devices' data of other users, the API can be like /users/$user_id/devices
whereas, when you always have to get the current logged-in user's devices information, the API can simply be /devices (as current user is implied).
i.e IMO, wherever you have only 1 parent resource accessible (say in this case current user is always singular), you can skip that resource in the API URL.
I'm creating an API where based on the permissions that authenticated user different properties of objects can be changed.
Whats the common way to approach this problem?
Should i have endpoints like
/admin/users and /users with different API definition and capabilities?
It sounds rather inflexible design, what about situation where user can have permission like can_modify_foo_prop and can_modify_bar_prop?
I was thinking a better solution would be instead to just provide one endpoint /users and based on authenticated user roles some fields would be read-only/hidden instead? That seems more flexible but could be more annoying to document/implement.
Remember, URI means Uniform Resource Identifier. Which means a given user (concept) should be always identified by the same URI, hence I would suggest your second proposal, to have a single hierarchy/list of users:
/users/1
/users/2
...
It is acceptable to define (in the appropriate Media-Type) the returning document to hold properties based on the current user's permissions.
Now, regarding whether that is easy to use or not is subjective. I would argue that returning pure data is always somewhat inconvenient, because the client has to parse and understand the data. This is why HTML and HTML Forms were created, so the client does not need to know how to present the data, and also doesn't need to know what's editable and what is not. Then again, I don't know your exact use-case.
I have resource endpoints that I would like to respond differently to the user that tries to access the endpoint.
Scenario
Let us say that I have a resource endpoint /users, and the following UserTypes:
GirlUser
BoyUser
Admin
When a GirlUser executes a GET on /users I want to only allow for other GirlUsers to be accessible. I would expect BoyUsers to have a similar result, and Admins to receive all users.
My Question
Is it more RESTful to:
Handle this with different GrantTypes or Scopes through OAuth, using the one /users endpoint.
Have different endpoints, such as: users/girls, users/boys, and users/all.
Have different APIs for the different types of users.
I'm totally off-base with possible answers and it's something that I don't expect.
Would anything change if I have other endpoints that I would want to only be operational for a certain UserType?
(For example, ones that process payments.)
Thank you.
Your endpoints should be independent of the sex of the user. What's the problem in having a common User endpoint. (You are doing it right already!!)
Though it depends on the kind of information that you want to return, the kind of resources in hand. Are you returning JSON/XML? You have a Girl and a Boy class that you work with in the backend. If a girl user hits the endpoint you serialize objects and return data to the user - that sounds okay to me.
If your UML design does not differentiate between girls/boys then you should have the same endpoint.
In order to understand the problem properly,
i) What kind of data are you returning?
ii) How have you designed the UML?
iii) Are you returning some data from a DB? Is it expensive to run all girls/all boys query on it everytime the endpoint is hit?
As for scopes, in OAuth one scope generally corresponds to one endpoint. Like in Google, G+ is a scope, google drive is a scope. We don't see G+ girls, G+ boys scopes, do we now?
In java terms, the closest match to the API design is a Factory pattern (that's how I explain it to myself, might not be technically correct) - depending on the type of user you call a specific method that returns data. The endpoint should be generic and extensible - having separate API's is indeed a bad design as it leaves little to expansion.
I'm slowly beginning to unerstand REST and theres one thing thats confusing me .
I understand that most of the things in REST is a "resource" . So i was wondering what kind of a resource would we be referring to in the case of a user signup / login ?
Is it users ? Then does it mean that a POST on users would signup for a new user . If that is the case , then how do i authenticate a user ? a GET on users with an encoded password / username pair?
I'm really confused with this.
I may be COMPLETELY wrong in my understanding given that i'm just starting to understand REST.
Any help is appreciated !
Thanks!
It's a bit of an unusual but common problem for REST. Keep thinking about resources.
When you login you're asking the server to create a session for you to access certain resources. So in this case the resource to create would be a session. So perhaps the url would be /api/sessions and a POST to that url with a session object (which could just be an object consisting of a username or password and perhaps the UUID) would create a session. In true REST you'd probably point to a new session at /api/sessions/{UUID} but in reality (and for security purposes) you'd probably just register a session cookie.
That's my own personal approach to login forms if I were to implement them myself but I always tend to use Spring security for that job so this requirement never really takes much consideration.
I am working on something similar and this is the solution I have taken so far. Any suggestions welcome :)
I have users exclusively for singup and account modifications.
GET /users/{id} gets a user for the profile page for instance
PUT /users creates a new user with username and password. In reality this should send an email with a link to somewhere that confirms the signup with a GET method.
POST /users/{id} modifies the user (for example change password)
DELETE /users/{id}
For authentication I tend to think that the resource I request is the token or the authentication. I have tried to avoid the word "session" because it is supposed to be anti-RESTful, but if you are just creating the illusion of an actual server-side session for your clients, I guess it is fine.
PUT /authentication/ with usename/password returns Set-Cookie with the pair user_id / hashed value. Maybe it should be POST. Not sure
DELETE /authentication/{user_id} just deletes the cookie and the user is signed out. Maybe instead of user_id it should be a unique token_id.
Resources can be created, read, update and deleted using a restful approach, see e.g.:
https://cwiki.apache.org/S2PLUGINS/restful-crud-for-html-methods.html
So if you'd like to administrate you users this would be the restful approach to do so.
If you'd like to authenticate the users which you have in your administration dataset you need
to design or select a restful authentication mechanism see e.g.
http://de.slideshare.net/sullis/oauth-and-rest-web-services
http://www.thebuzzmedia.com/designing-a-secure-rest-api-without-oauth-authentication/
For a jumpstart on these issues you might want to check out dropwizard:
http://dropwizard.codahale.com/
A resource may have one URI or many
but One URI will have exactly one Resource
Therefore, When Authenticating a user, you are addressing a user who is already registered
While when registering, you are addressing the user (resource) which is yet to be registered.
All you need is a way to process it to your SERVER.
THIS is an example taken from SUGARCRM REST web services implementation.
REST is like http requests to your SERVER.
For eg, when implementing REST Web Services.
Every REST Request is going to same File say
www.your_domain.com/Rest.php?json={your_json_method:'method',params:'watever'}
Where in Json is the request you are sending as a parameters
Requesting to authenticate a user
{method:'SignUp', username:'abc', pass:'pass', confirm_pass:'pass'}
Requesting to register a user
{method:'Login', username:'abc', pass:'pass'}
by this way you can have as many params as you want
Remember JSON is not necessory to be used. you can use simple get params for your query
I am new to both .Net & RESTful services.
Here is the object hierarchy I have in the database: Users->Folders->Notes.
The API: GET /api/note/{noteid}
would get mapped to the repository call
NoteRepository::GetNote(userId, noteId)
Notice that I am passing on the userId to make sure that the note belongs to the logged in user for security purpose.
Is this the right approach? Meaning, every repository call would have the first parameter as the userId to check if the object being accessed belongs to the user.
Is there any better approach?
You don't need the User Id since the
GET /api/note/{noteid}
is indeed unique.
A valid scenario for adding the id would be:
GET /api/{userId}/notes
And then if you want a specific note you can:
GET /api/{userId}/notes/{noteId}
I would implement security at the entry level. whether the user has rights to perform a method on that specific resource. A role model approach would be fine.
Regards.
I would also introduce the user id in the API, because of Stateless and Cacheable constraints described in the Wikipedia REST article.
However, if I check Google Tasks REST API, they don't include the user id, same thing for Twitter API, so it seems a trend not to include the user id. If someone can shed some light I would be grateful.
UPDATE: Thinking more about it, if the noteid is unique across all users, there is no need to include the user id, so a GET /api/note/{noteid} is fine.
However, the logical parent in a restful interface would be GET /api/note/ to get a list of all notes, and here I've the objection, since the list would differ according to the user requesting it, making it non cacheable.
As for your dot net part I think that passing the userid among dot net methods is perfectly fine.