In what situation should the client choose the unique resource ID for REST URIs and in which should the server specify it? - api

It looks like there are two ways I can make my REST API. I can have users created with a POST without specifying the URI and it will create the user and return the URI OR I can have the create the users with a PUT and specify the URI themselves.
When should one be used over the other? The key difference here is that in one method MY system is deciding what the unique ID and thus URI for the resource should be, in the other situation THEY are specifying what it should be when I create.

It basically comes down to whether you are willing to cede the control of resource naming to the client.
The biggest issue simply being dealing with conflicts (If I PUT /photo.png and you PUT /photo.png, is that OK?).
Answer those questions, and you're on your way.

When your user is specifying the resource ID, they can PUT to the URI; the ID that they are performing the PUT to is the specification of the resource ID.
When you are specifying the resource ID, they can POST to the URI of the parent / group; your system will assign a URI to the resource, and return that to the client so they can reference their created resource.

The answer to this question hinges on two more specific questions:
Do clients know the location of the resource to be created? (This might be the case if, for instance, users are accessed via the name of the user rather than a server-assigned ID.)
Do clients have a full representation of the resource to be created? (This might not be the case if some portion of your resource is computed by the server.)
If the answer to both of those questions is 'yes', then a PUT is probably appropriate. If you answered 'no' to either, then you ought to stick with a POST.

I can have users created with a POST
without specifying the URI and it will
create the user and return the URI OR
I can have the create the users with a
PUT and specify the URI themselves.
When should one be used over the
other?
Use the first.
In RESTful HTTP the client should never construct URIs. The service should be well-connected, which means that the client should only ever follow URIs given by the server and make requests to those URIs.
It creates better separation between the client and server, and makes it easier to make changes to the service without breaking existing clients.
(And yes, lots of existing APIs get this wrong)
There's a really good post by Fielding related to this topic here:
http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven

Related

Multiple endpoints to expose different views of the same resource

I'm struggling to find an answer to this (perhaps because I'm not asking the question properly) ...
I'm building API to expose resources for a basic social networking service I'm creating.
My understanding is that the structure of URLs in an API is essentially a hierarchy, directory like structure. I think that means I can have multiple endpoints to reach the same resources or collections of resource links.
For example:
I have an endpoint
www.domain.api.org/users/{:uid}/posts
Which will return all posts sent by the user or that the user is tagged in. Seems ok, but what if I have an endpoint such as:
www.domain.api.org/posts
Which when hit with a http GET will return all public posts (i.e. all users' posts plus his friends' and public posts).
The difference is that the first URL points to user owned resources whereas the second to public ones (of which the users posts are included of course)
Are these okay or am I doing it the wrong / less sensible way?
To reiterate, can I have multiple endpoints which point to different contexts/views of the same resource?
Basically multiple endpoints for the same resources should be avoided. However in this particular case it does make sense.
What you can do is to introduce optional query param userId to the following endpoint:
www.domain.api.org/posts/?userId=<userId>
If this substitutes the first endpoint you mentioned that's the way to go.
I would like to add ontop of #Opal's answer.
Are these okay or am I doing it the wrong / less sensible way?
Ideally, like Opal mentioned, you would use queryParams in your url. For many applications I have build, I don't know the uids returned from the api beforehand, so selecting an item and passing it inside my url as a query parameter makes sense. But it also has the added benefit of having your key inside your url, allowing you to bookmark it, pass the url to another user and they will automatically see the same data you want them to see.
To iterate: Is your current implementation wrong? No, but ideally you would use a combination of both route parameters are query parameters to achieve this
To create an endpoints, you have to be sure that you have these information at once:
Name of the endpoint
Status: activate or not (required) - is the endpoint activated or disable
Service profile (required) - ID of the Service Profile assigned to the endpoint.
Tariff profile (required) - ID of the tariff Profile assigned to the endpoint.
You can add another optional informations, and be sure of the structure of your endpoint.
Hope this helps you.

Restful API design: how should user's and authority's endpoints be?

Based on similar questions, i came to the conclusion that the most convenient way to design this endpoints to GET requests should be something like:
GET /v3/users/
GET /v3/users/{userId}
GET /v3/users/{userId}/authorities
GET /v3/users/authorities/{authId}
My question is how should be the next endpoints:
1. Create authorities
POST /v3/users/authorities
POST /v3/users/{userId}/authorities
2. Update authorities
PUT/PATCH /v3/users/authorities/{authId}
PUT/PATCH /v3/users/{userId}/authorities/{authId}
3. Delete authorities
DELETE /v3/users/authorities/{authId}
DELETE /v3/users/{userId}/authorities/{authId}
What do you think? Intuitively, i go with first option on all cases but maybe is not the nicest thing passing the userId from body (i see it nicer passing it from url). Or should i implement both endpoints maybe?
Second approach is cleaner and more standard.
PUT/PATCH/POST/DELETE.. /v3/users/authorities/{authId} - [1]
PUT/PATCH/POST/DELETE.. /v3/users/{userId}/authorities/{authId} -[2]
Here, for example, if you pass authId in uri, why not userId ? The standard you will be following here is "resource/{uniqueId}/attribute/{uniqueId}". Ideally in your back-end code, you first look up for the specific resource, and then look up specific attribute(s) for the same resource with the keys/ids passed in the uri. Id is omitted when the action is going to affect all the resources!
If you use the approach [1], it looks like you are trying to add/update/delete an authority for ALL users! Definitely that is not the case.
It is doable to send the userId in the form/post data, but not the correct approach. In your form/post data, you should send the values that are going to be added/updated (in case of PUT/POST). Something like {authType: 'Admin', isGlobal: true, effectiveFrom: '12/12/2015'}. Obviously, userId does not fit here.
First, let me say that I agree with the answer Arghya placed, but I do think there could be a case made for shortening those UPDATE and DELETE urls down to v3/authorities/{authId}.
Of course, this would assume that the authId is unique for that Authority across the application. I personally don't see a point in specifying a user. Either the person that is hitting that route has access to the resource or not.
Just remember that RESTful is just an architectural style. You should do what fits best into your technology stack and makes the most sense for you and the clients interacting with this API.

How to build REST API with server-defined ids?

This is a classic RESTful way of creating resources I have in the application:
# This creates user. Client is responsible to create UUID, which is simple
PUT /users/CLIENT_GENERATED_UUID
# Access user by uuid
GET /users/UUID
When we touch the field of data storage performance it turns out that randomly generated UUIDs do not serve well by many reasons like data locality.
Server-generated IDs are good for performance but they don't really match REST:
If you use POST to create resources, you lose idempotency: PUT, GET, DELETE idempotency is implied by REST, while POST is not.
You may ask server to provide you with a nice ID before doing PUT. Despite it feels quite heavy and non-obvious, it also does not protect from dummy client that uses own random id instead of asking for it.
Could somebody give me a hint in this architecture matter?
Creating a resource using is not meant to be idempotent. If the server assigns the ID, it must choose a different ID for every resource to be created. Such an operation must not be idempotent, repeating it must create a different resource.
Using POST against a collecton resource as in
POST /users
is totally RESTful if the server assigns the ID. This request can be repeated and it will create a different resource.
Using an idempotent operation like PUT for creating a resource only makes sense if the problem domain allows the client to control the ID. I think that is ist not true for most domains.
My advice: use POST and let the server assign the ID.
Actually when you read RESTful Best Practices you can find that:
The POST verb is most-often utilized for creation of new resources.
in addtion to:
PUT can also be used to create a resource in the case where the resource ID is chosen by the client instead of by the server.
In REST environment you send POST to create resources and can return the server generated ID to send the values after with PUT or PATCH.
POST /users
PUT /users/id
Also, people create resources with PUT using client generated IDs
PUT /users
But I think the best aproach is use server generated IDs with POST.
Here are a clear explanation: http://www.restapitutorial.com/lessons/httpmethods.html

REST API: How to name a derived resource?

There is a gazillion of questions about RESTful interface naming conventions, esp. around singular vs plural resource names. A somewhat convention is:
GET /users Retrieve collection of users
GET /users/{id} Retrieve user
POST /users Create user
PUT /users/{id} Update user
DELETE /users/{id} Delete user
However, the above does not work when resource is a value derived from the environment.
My hypothetical application has the following endpoint:
GET /source Get information about the source of the query.
That responds with:
Referrer URL
Remote IP
Since source is derived from the environment, there is never more than one source, therefore calling the resource sources or providing sources/{foo} lookup is not practical.
Does REST style propose how to handle naming of these entities?
Dr. Fielding notes in section 6.2.1 of his famous dissertation :
..authors need an identifier that closely matches the semantics they
intend by a hypermedia reference, allowing the reference to remain
static even though the result of accessing that reference may change
over time.
Therefore, it makes sense to use plain source endpoint.
It would be a different thing if you wanted to provide more general service around IP address provided, like this one.

Api URI Design Preference

A quick api uri design question. We have resources that belong to our clients. These resources can be edited / viewed / deleted by the client who entered them into our system. The resources can be searched by all clients but access is only granted if certain criteria is met (client has level 3 access etc).
Choice 1: include the client who owns the resource in the uri.
client/:clientname/widgets
client/:clientname/widgets/:id
Choice 2: ditch the whole "client/:clientname" since this part of the uri has to be verified and checked against the credentials of the user accessing the information.
/widgets
/widgets:id
We have other resources other than widgets that also belong to clients.
Which way is the more preferred way and why? Cheers.
The only advantage that Choice 1 gives it that it allows you to effectively namespace widgets/whatever by the user that uploaded them. Similar to Github, how different users can have projects with the same name. If Github were to exclude the username, no two users could have a project with the same name. If the widgets are all unique, I would go with option two and you will have a 1:1 mapping from a widget the the user that created it, thus supplying it is just extra work for whoever is calling it.
If you can have the same widget name for different users, use an approach which includes the username. You may not need to actually use the 'client' word in your url though; using a path like '/:clientname/widget/:widgetid' instead.
Note that this is kind of an opinion based question, so you may get different answers. You'll have to weigh the information provided and in the end make your own decision.