My understanding of REST (admittedly limited to pretty much the wikipedia page) is that idiom for GETing a collection is ../resource/ and an item is ../resource/itemId.
Is there a standard idiom for GETing for a sub-collection? For example, if the items in the collection have some state toggle (say states A, B, C, D), and I want to be able to ask for items with state B, is there a standard/common/best-practice way to do that?
If not, I'm currently fiddling with the following syntax options:
../resource/B
../resource/state/B
../resource?state=B
What pros/cons of those do you see?
You want to use the third one there, except plural (since you're getting more than one)
../resources?state=B
Because it accurately describe what you want. You're GETing a resource with a specific state.
../resource/B
Would indicate you're getting a specific resource uniquely identified by B
../resource/state/B
Would indicate you're getting a resource state, belonging to resource, uniquely identified by B.
An alternative if you're dealing with a finite number of states would be to make state a resource by itself and make the resource a child of that state. Then you would have
states/B/resources
The REST constraints actually say nothing about how you name resources. REST just says resources should have a name.
Having said that, Jamie's answer is probably the most obvious way of doing it. You can compare naming URLs to naming procedures, there is no right and wrong way to do it, just some names are more obvious than others.
Related
I have been struggling to find information on how a resource that contains generated values is modified. Below is a real world example:
Let's say we have 2 endpoints:
/categories and /products.
A category is used to contain various parameters that define any product belonging to it. For example, based on a category a product expiration date might be calculated, or some other properties might or might not be attached to a product.
Let's say we create a new product by sending a POST request to /products and among other fields we include the category ID property. Based on the category set a server creates and stores a new product along with various properties generated (expiration date, delivery policies) etc.
Now the problem arises when needing to modify (PATCH/ PUT) the mentioned product.
How are generated values edited? We can for example change a delivery policy, but then the product will contain a field that doesn't match what its attached category describes. Likewise, it might be very handy to modify its generated expiration date, however yet again that can create confusion about why a category says it should expire in 3 days but the product is set to expire in 20 days.
Another solution would be to make all these properties read-only and only allow regenerating them by changing the category, just like at creation.
However that poses 2 problems:
The biggest one being that a different category might not contain the same policy layout. For example, one category might enable generating GPS coordinates to ease the delivery, the other category does not. If we change the category, what do we do with these valuable properties already present? Do we drop them for the sake of clarity?
Another issue is limited flexibility. There might be cases when a property needs to be changed but the category needs to remain the same.
I think these questions are met and answered in probably every single REST API development and probably I am just missing something very simple and obvious. Could you help me understand the right way of going about this?
Thank you very much.
I think these questions are met and answered in probably every single REST API development and probably I am just missing something very simple and obvious. Could you help me understand the right way of going about this?
You write code to ensure that all of the invariants hold for the server's copy of the resource.
That can mean either (a) inspecting the body of the request, and returning a client error if the body doesn't satisfy the constraints you need to maintain, or (b) changing your resource in a way that doesn't exactly match the request you've received.
In the second case, you need to have a little bit of care with the response metadata, so that you don't imply that the representation of the request has been adopted "as is".
The code you are writing here is part of the origin server's implementation, deliberately hidden by the HTTP facade you present. The general purpose components in the middle don't care about those details; they just want you to use messaging semantics consistent with the HTTP (and related) specifications.
This is a relatively subjective question, but I want to get other people's opinion nonetheless
I am designing a REST Api that will be accessed by internal systems (a couple of clients apps at most).
In general the API needs to update parameters of different car brands. Each car brand has around 20 properties, some of which are shared between all car brands, and some specific for each brand.
I am wondering what is a better approach to the design for the endpoints of this API.
Whether I should use a single endpoint, that takes in a string - that is a JSON of all the properties of the car brand, along with an ID of the car brand.
Or should I provide a separate endpoint per car brand, that has a body with the exact properties necessary for that car brand.
So in the first approach I have a single endpoint that has a string parameter that I expect to be a JSON with all necessary values
PUT /api/v1/carBrands/
Whereas in the second approach in the second scenario I have an endpoint per type of car brand, and each endpoint has a typed dto object representing all the values it needs.
PUT /api/v1/carBrand/1
PUT /api/v1/carBrand/2
.
.
.
PUT /api/v1/carBrand/n
The first approach seems to save a lot of repetitive code - afterall the only difference is the set of parameters. However, since this accepts an arbitrary string, there is no way for the enduser to know what he should pass - he will need someone to tell it to him and/or read from documentation.
The second approach is a lot more readable, and any one can fill in the data, since they know what it is. But it involves mostly replicating the same code around 20 times.
Its really hard for me to pick an option, since both approaches have their drawbacks. How should I judge whats the better option
I am wondering what is a better approach to the design for the endpoints of this API.
Based on your examples, it looks as though you are asking about resource design, and in particular whether you should use one large resource, or a family of smaller ones.
REST doesn't answer that question... not directly, anyway. What REST does do is identify that caching granularity is at the resource level. If there are two pieces of information, and you want the invalidation of one to also invalidate the other, then those pieces of information should be part of the same resource, which is to say they should be accessed using the same URI.
If that's not what you want, then you should probably be leaning toward using separated resources.
I wouldn't necessarily expect that making edits to Ford should force the invalidation of my local copy of Ferrari, so that suggests that I may want to treat them as two different resources, rather than two sub-resources.
Compare
/api/v1/carBrands#Ford
/api/v1/carBrands#Ferrari
with
/api/v1/carBrands/Ford
/api/v1/carBrands/Ferrari
In the former case, I've got one resource in my cache (/api/v1/carBrands); any changes I make to it invalidate the entire resource. In the latter case, I've got two resources cached; changing one ignores the other.
It's not wrong to use one or the other; both are fine, and have plenty of history. They make different trade offs, one or the other may be a better fit for the problem you are trying to solve today.
Suppose we have the books endpoint, at which we can return serialized Book objects. Most of the time, these are books already published (so the future is omitted), and most of the time we will be displaying a Book list belonging to some user. (so the user parameter is mostly present and we mostly filter to books that belong to some user)
Example query:
http://localhost:8000/api/books?future=true
http://localhost:8000/api/books?user=somebody
http://localhost:8000/api/books?future=true&user=somebody
I'm wondering if the above structure looks OK. Other ideas, some seem worse than others, have come to mind. For example, a different optional endpoint/path (instead of the former):
// this makes the least sense to me
http://localhost:8000/api/books/somebody?future=true
I have also contemplated whether getting those books from the users endpoint would make sense:
http://localhost:8000/api/users/somebody/books
http://localhost:8000/api/users/somebody/books?future=true
And then I can also call:
http://localhost:8000/api/users/somebody/settings
Do you agree the second option doesn't make sense?
Can the first and 3rd example live beside each other?
I guess what I'm really asking: should it be possible to reach the same exact resources by two different means in REST design? How do you prefer one over the other? When do you enforce only one? when do you allow both (if at all)?
In this case the API endpoints will be consumed by a future iOS app developed by myself, but I don't think that should be relevant to the question.
As I am not sure I stated the question very well originally, I am restating it to see if there is a better response.
I have a problem with how best to manage a specific kind collection with a RESTful API. To help illustrate the issue I have I will use an simple artificial example. Lets call it the 'Raffle Ticket Selector'. For this question I am only interested in how to perform one function.
I have a collection of unpurchased raffle tickets (raffleTickets). Each with a unique Raffle Number along with other information.
I need to be able to take an identified number of tickets (numTickets) from the raffleTickets collection without uniquely selecting them. The collection itself has a mechanism for random selection.
The result is that I am returned 5 unique tickets from the collection and the size of the collection is decreased by 5 as the 5 returned have been removed.
The quesition is, how do I do it in a RESTfull way?
I intuatively want to do METHOD .../raffelTickets?numTickets=5 but struggle with which HTTP Method to use
In answering; you are not allowed to suggest that I just PATCH/PUT a status change to effect a removal by marking them taken. It must result an actual change in the cardanality of the collection.
Note: Calling the method twice will return a different result set every time and will always alter the collection on which it is performed (unless it is empty!)
So what method should I use? PUT? POST? DELETE? PATCH? Identpotent restrictions would seem to only leave me with POST and PATCH neither of which feels ideal to me. Or perhaps there is another way of providing the overall behavior that is considered the correct approach.
I am really interested to know what is best practice and understand why.
Cheers
Original Post on which the first response was based:
I have a pool of a given item which is to be managed with a RESTful API. Now adding items to the pool is not an issue but how to I take items from the pool? Is it also a POST or is it a DELETE?
Lets say it is a pool of random numbers and I want to retrieve a variable number of items in a single method call.
I have two scenarios:
I am not checking them out as once taken they will not be returned to the pool.
I only want to check them out and they effectively remain part of the pool but have a status altered to 'inUse'
The important thing in each case is I do not care which items I get, I just want N of them.
What is considered the RESTful way performing each of the two actions on the pool? I have an opinion on the second option but I dither on the former so I am interested in your thoughts for both so I better understand the thought pattern
Thanks
Not sure if I understood well your question. It will mostly depend on the way you developed the API side of your REST communication.
In a generic solution, you would use DELETE to take items out of a list. However, if you just want to PARTIALY update the items, you could use PATCH instead of POST or PUT.
Give this a look: http://restcookbook.com/HTTP%20Methods/patch/
I read the article at REST - complex applications and it answers some of my questions, but not all.
I am designing my first REST application and need to return "subset" lists to GET requests. Which of the following is more "RESTful"?
/patients;listType=appointments;date=2010-02-22;user_id=1234
or
/patients/appointments-list;date=2010-02-22;user_id=1234
or even
/appointments/2010-02-22/patients;user_id=1234
There will be about a dozen different lists that I need to return. In some of these, there will be several filtering parameters and I don't want to have big 'if' statements in my server code to select the subsets based on which parameters are present. For example, I might need all patients for a specific doctor where the covering doctor is another and the primary doctor is yet another. I could select with
/patients;rounds=true;specific_id=xxxx;covering_id=yyyy;primary_id=zzzz
but that would require complicated branching logic to get the right list, where asking for a specific subset (rounds-list) will achieve that same thing.
Note that I need to use matrix parameters instead of query parameters because I need to do filtering at several levels of the URL. The framework I am using (RestEasy), fully supports matrix parameters.
Ralph,
the particular URI patterns are orthogonal to the question how RESTful your application will be.
What matters with regard to RESTfulness is that the client discovers how to construct the URIs at runtime. This can be achieved either with forms or URI templates. Both hypermedia controls tell the client what parameters can be used and where to put them in the URI.
For this to work RESTfully, client and server must know the possible parameters at design time. This is usually achieved by making them part of the specification of the link relationship.
You might for example define a 'my-subset' link relation to have the meaning of linking to subsets of collections and with it you would define the following parameters:
listType, date, userID.
In a link template that spec could be used as
<link rel="my-subset' template="/{listType}/{date}/patients;user_id={userID}"/>
Note how the actual parameter name in the URI is decoupled from the specified parameter name. The value for userID is late-bound to the URI parameter user_id.
This makes it possible for the URI parameter name to change without affecting the client.
You can look at OpenSearch description documents (http://www.opensearch.org) to see how this is done in practice.
Actually, you should be able to leverage OpenSearch quite a bit for your use case. Especially the ability to predefine queries would allow you to describe particular subsets in your 'forms'.
But see for yourself and then ask back again :-)
Jan
I would recommend that you use this URL structure:
/appointments;user_id=1234;date=2010-02-22
Why? I chose /appointments because it is simple and clear. (If you have more than one kind of appointment, let me know in the comments and I can adjust my answer.) I chose the semicolons because they don't imply hierarchy between user_id and date.
One more thing, there is no reason why you should limit yourself to just one URL. It is just fine to have multiple URL structures that refer to the same resource. So you might also use:
/users/1234/appointments;date=2010-02-22
To return a similar result.
That said, I would not recommend using /dates/2010-02-22/appointments;user_id=1234. Why? I don't think, in practice, that /dates refers to a resource. Date is an attribute of an appointment but is not a noun on its own (i.e. it is not a first-class kind of thing).
I can relate to what David James answered.
The format of your URIs can be like he suggested:
/appointments;user_id=1234;date=2010-02-22
and / or
/users/1234/appointments;date=2010-02-22
while still maintaining the discoverability (at runtime) of your resource's URIs (like Jan Algermissen suggested).