Looking for RESTful approach to update multiple resources with the same field set - rest

The task: I have multiple resources that need to be updated in one HTTP call.
The resource type, field and value to update are the same for all resources.
Example: have set of cars by their IDs, need to update "status" of all cars to "sold".
Classic RESTFul approach: use request URL something like
PUT /cars
with JSON body like
[{id:1,status:sold},{id:2,status:sold},...]
However this seems to be an overkill: too many times to put status:sold
Looking for a RESTful way (I mean the way that is as close to "standard" rest protocol as possible) to send status:sold just once for all cars along with the list of car IDs to update. This is what I would do:
PUT /cars
With JSON
{ids=[1,2,...],status:sold} but I am not sure if this is truly RESTful approach.
Any ideas?
Also as an added benefit: I would like to be able to avoid JSON for small number of cars by simply setting up a URL with parameters something like this:
PUT /cars?ids=1,2,3&status=sold
Is this RESTful enough?

An even simpler way would just be:
{sold:[1,2,...]}
There's no need to have multiple methods for larger or smaller numbers of requests - it wastes development time and has no noteable impact upon performance or bandwidth.
As far as it being RESTful goes, as long as it's easily decipherable by the recipient and contains all the information you need, then there's no problem with it.

As I understand it using put is not sufficient to write a single property of a resource. One idea is to simply expose the property as a resource itself:
Therefore: PUT /car/carId/status with body content 'Sold'.
Updating more than one car should result in multiple puts since a request should only target a single resource.
Another Idea is to expose a certain protocol where you build a 'batch' resource.
POST /daily-deals-report/ body content {"sold" : [1, 2, 3, 4, 5]}
Then the system can simply acknowledge the deals being made and update the cars status itself. This way you create a whole new point of view and enable a more REST like api then you actually intended.
Also you should think about exposing a resource listing all cars that are available and therefore are ready for being sold (therefore not sold, and not needing repairs or are not rent).
GET /cars/pricelist?city=* -> List of all cars ready to be sold including car id and price.
This way a car do not have a status regarding who is owning the car. A resource is usually independent of its owner (owner is aggregating cars not a composite of it).
Whenever you have difficulties to map an operation to a resource your model tend to be flawed by object oriented thinking. With resources many relations (parent property) and status properties tend to be misplaced since designing resources is even more abstract than thinking in services.
If you need to manipulate many similar objects you need to identify the business process that triggers those changes and expose this process by a single resource describing its input (just like the daily deals report).

Related

REST API Design - Collections as arrays with ETag

Take the following URL template:
~/pupil/{id}/subjects
If the subjects are a collection represented in the traditional way, as if each item stands alone like the pupil items, then is this the correct way to expose them?
It begins to feel wrong when you consider updating the collection in terms of the pupil and concurrently with another API caller.
Suddenly, you cannot synchronize access since there's no ETag to cover the set and you'll end up interleaving the changes and getting in a tangle.
A different design could see the subjects incorporated as a sub array in the entity of the pupil and the /subjects URL is just for read access.
Perhaps the subjects should be returned as a single array set entity with a discreet ETag and that POSTing individual subjects should be disabled and updates made via a POST/PUT of the whole set, but what if the list is very long? Needs paging?
Maybe the design decision is case-by-case, not a sweeping guideline. Not sure.
Thoughts?
It depends on whether you want to treat "subjects" as a single resource or not.
If, as you say, consumers of your API and going to want to add, remove or modify individual subjects then, yes the traditional way of representing them would be correct with regard to REST patterns:
~/pupil/{id}/subjects
would return a list of resources at
~/pupil/{id}/subjects/{subjectId}
Unless there's a strong reason to optimize bulk operations or caching, this is the most RESTful and straightforward implementation.

Designing a REST api by URI vs query string

Let's say I have three resources that are related like so:
Grandparent (collection) -> Parent (collection) -> and Child (collection)
The above depicts the relationship among these resources like so: Each grandparent can map to one or several parents. Each parent can map to one or several children. I want the ability to support searching against the child resource but with the filter criteria:
If my clients pass me an id reference to a grandparent, I want to only search against children who are direct descendants of that grandparent.
If my clients pass me an id reference to a parent, I want to only search against children who are direct descendants of my parent.
I have thought of something like so:
GET /myservice/api/v1/grandparents/{grandparentID}/parents/children?search={text}
and
GET /myservice/api/v1/parents/{parentID}/children?search={text}
for the above requirements, respectively.
But I could also do something like this:
GET /myservice/api/v1/children?search={text}&grandparentID={id}&parentID=${id}
In this design, I could allow my client to pass me one or the other in the query string: either grandparentID or parentID, but not both.
My questions are:
1) Which API design is more RESTful, and why? Semantically, they mean and behave the same way. The last resource in the URI is "children", effectively implying that the client is operating on the children resource.
2) What are the pros and cons to each in terms of understandability from a client's perspective, and maintainability from the designer's perspective.
3) What are query strings really used for, besides "filtering" on your resource? If you go with the first approach, the filter parameter is embedded in the URI itself as a path parameter instead of a query string parameter.
Thanks!
Something to note, is that since you use GET in your above examples,
dependant on the end user browser settings, proxy settings or other calling applications internal settings,
the response is likely to be cached somewhere on the message route, and the original request message may never actually reach your API layer where the most recent data is accessed.
so first, you may want to review your requirement of using the verb GET.
If you want your API to return the most recent data every time, then don't use GET, or if you still want to use GET, then require the caller to append a random number to the end of the url, to decrease the likely hood of caching.
or get the client to send the verb PURGE, after every GET.
this proxy caching behaviour that is present across the internet, in browsers, and server architectures is where REST fails for me, since caching of GET can be very useful but only sometimes.
stick to basic querystrings if you want to make it really simple for the end developer and caching of responses offers no problems for you,
or
just use POST and forget about this tiresome REST argument

Using a RESTFUL PUT, how should parent/child entities be updated (or informed)?

For a simple example, I'll use tires and cars. I intend to execute a PUT to increase the price of a tire. The UI also contains cars that use the tires being updated, therefore requiring a price update of their own.
Is it appropriate for the original PUT request to contain car pricing in its response? If not, how is this typically solved?
A PUT to update a /tire price should absolutely not return details of how it updated a different resource like a /car. Doing so would co-mingle the two entities and make your resource representations overly complex. It would also make "atomic" updates of individual resources difficult for clients.
The PUT response should only tell you whether or not the update succeeded on the /tire resource, and perhaps provide the new representation of the tire in the response content. Once the PUT call to the tire has returned, the client (your UI) can then GET the /car once more and it will see a new price for the overall car that takes into account the new tire cost.

Can a single url have two different objects (single item or collect of items) be posted and still be RESTfully designed?

I have person json objects that are posted to a rest service that is responsible for creating the objects and storing them in a database. But I have two situations I need to handle.
Post a single person object and have one person created
Post a person array and have multiple people created
Can I use the same url...ie www.mysite.com/people/ and have the server determine whether it is a single person or a collection of people? I know I can technically do this but how should I deal with this situation and still have a RESTful design?
Yes. "POST" is kind of a wildcard, and can "get away" with most anything. What you don't want to do is conflate this resource with the underlying resource. You don't want to POST to /people, rather something specific for the task.
So, you'll want something like /people_loader for this task that returns a explicit result of the process (/people_loader/1234), which is a resource linking to the new people you just created.
/people is your base resource, so a /people_loader result would be a collection of /people links, and perhaps some other information for those objects that weren't loaded (do to errors or other constraints).

Is it RESTful to create complex objects in a single POST?

I have a form where users create Person records. Each Person can have several attributes -- height, weight, etc. But they can also have lists of associated data such as interests, favorite movies, etc.
I have a single form where all this data is collected. To me it seems like I should POST all of this data in a single request. But is that RESTful? My reading suggests that the interests, favorite movies and other lists should be added in separate POST requests. But I don't think that makes sense because one of those could fail and then there would be a partial insert of the Person and it may be missing their interests or favorite movies.
I'd say that it depends entirely upon the addressability and uniqueness of the dependent data.
If your user-associated data is dependent upon the user (i.e., a "distinct" string, e.g. an attribute such as a string representing an (unvalidated) name of a movie), then it should be included in the POST creation of the user representation; however, if the data is independent of the user (where the data can be addressed independently of the user, e.g. a reference, such as a movie from a set of movies) then it should be added independently.
The reasoning behind this is that reference addition when bundled with the original POST implies transactionality; that is, if another user deletes the movie reference for the "favorite" movie between when it is chosen on the client and when the POST goes through, the user add will (should by that design) fail, whereas if the "favorite" movie is not associative but is just an attribute, there's nothing to fail on (attributes (presumably) cannot be invalidated by a third party).
And again, this goes very much to your specific needs, but I fall on the side of allowing the partial inserts and indicating the failures. The proper way to handle this sort of thing if you really want to not allow partial inserts is to just implement transactions on the back end; they're the only way to truly handle a situation where a critical associated resource is removed mid-process.
The real restriction in REST is that for a modifiable resource that you GET, you can also turn around and PUT the same representation back to change its state. Or POST. Since it's reasonable (and very common) to GET resources that are big bundles of other things, it's perfectly reasonable to PUT big bundles of things, too.
Think of resources in REST very broadly. They can map one-to-one with database rows, but they don't have to. An addressable resource can embed other addressable resources, or include links to them. As long as you're honoring your representation and the semantics of the underlying protocol's operations (i.e. HTTP GET POST PUT etc.), REST doesn't have anything to say about other design considerations that might make your life easier or harder.
I don't think there is a problem with adding all data in one request as long as its inherently associated with the main resource (i.e. the person in your case). If interest, fav. movies etc are resources of their own, they should also be handled as such.