Suppose I have the following api where vin is a Vehicle Identification Number and belongs to a single car.
GET /fleets/123/cars/55/vin
GET /fleets/123/cars/55/history
And I want to get all the vins for all the cars for a fleet. Which would be preferred among these:
GET /fleets/123/cars/all/vin
GET /fleets/123/cars/*/vin
GET /fleets/123/vins
GET /fleets/123/cars/vins
The first two preserve the hierarchy and make the controller more intuitive. The last three feels like it breaks consistency.
Are any of these preferred or is there a better way?
This is mostly an opinion-based question. There's no one true way here, so you'll get my opinion.
I'm not sure what a vin is, but if it's a type of resource, and there's a collection of vins as a child of a fleet resource, I would expect it to live here:
GET /fleets/123/vins
This communicates to me a vin is not a subordinate of a car. It's its own thing and I'm getting all vins for a specific fleet.
The fact that a vin also exists as a subordinate of car (to me) is kind of irrelevant to this. It makes perfectly sense to me that for those, that they live here:
GET /fleets/123/cars/55/vin
Similarly, if I would model the last 2 apis as 2 functions, I would call them:
findVinsForFleet(fleetId: number);
findVinForCar(fleetId: number, carId: number);
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/
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.