Moving child resource to another parent in REST - rest

I have a REST service.
And now I need to have functionality to move some child resources from one parent to another, for example move a book from one author to another.
My variant is:
POST /api/books/x/moveto/y
But how to create such architect the RESTful way?

From a REST point of view, URLs should be used to locate the resources rather than expressing operations. To express operations, the existing HTTP verbs should be used.
Looks like your "move" operation is all about replacing the author of the book.
And the PUT method seems to be the way to go:
4.3.4. PUT
The PUT method requests that the state of the target resource be
created or replaced with the state defined by the representation
enclosed in the request message payload. [...]
So, you can have an endpoint like the following:
PUT /api/books/{bookId}/author
And the request payload will contain a representation of the new author.

I think in this case updating the author as suggested in Cassio's answer is a good solution. For less obvious "actions" I use PATCH endpoints. Consider archiving a book:
PATCH /api/books/{bookId}/archive
The intent is obvious -- archive the book with this identifier. For more complex actions, include a body or use a query string parameter. For instance, moving a book out of one category and into another (assume a book can have 0-many categories):
PATCH /api/books/{bookId}/move
{
fromCategoryId: 100,
toCategoryId: 200
}
Or:
PATCH /api/books/{bookId}/move?fromCategoryId=100&toCategoryId=200
In the end, IMO, what matters most is readability and consistency. There is not necessarily a "right" way to do this sort of thing.

Related

PATCH API REST best naming option

I want to add, or replace a coupon to an order via api. I thought in this two possibilities
PATCH /api/orders/{id}
{ "couponCode": "test"}
PATCH /api/orders/{id}/coupon/{couponCode}
I like the second because it's important in the application to apply a coupon code, and this url specifies it very well.
Are first and second valid possibilities following REST? The second option is valid with PUT and PATCH HTTP Methods?
Which do you think is better?
Thanks
The PATCH method is not particularly RESTful on its own. REST is about transferring state, and PATCH doesn't really do that, instead it sends an instruction for an update.
So to make things RESTful what you will want to do is a PUT request to create and replace the state of a coupon in full.
With that being out of the way, this is not an endorsement against using PATCH, but my idea about this is that it's a good idea to:
Provide a proper PUT request to fully replace existing state.
With that in place add support for PATCH to optimize things that might be slow or clumsy.
So if you want to use PATCH on /api/orders/{id}, I would first wonder: how does the PUT version look like?
I don't fully understand what a PATCH on /api/orders/{id}/coupon/{couponCode} would mean. Are you updating the coupon code? It's odd because the code exists in the uri. A DELETE + a PUT makes more sense to me. Or maybe the HTTP MOVE method might even help? (MOVE also falls in the 'not RESTful camp but it's a nice optimization for GET + DELETE + `PUT).
If an order only ever has 1 coupon, I would prefer a uri structure like /api/orders/{id}/coupon because it's a nice singular resource and it makes total sense to replace it with PUT (or PATCH it).

REST principle - resource update

Can you please confirm if below implementation for PUT vs POST defies REST principle:
If a resource was created via POST, allow update to the resource via POST (else return 412 error)
If the resource was created via PUT, allow update to resource via PUT (else return 412 error)
I understand both PUT and POST can be used to create a resource. What I think is not right in this case is dependency on how resource was created (PUT/ POST) and takes action based on it. Can you point me to the RFC?
If a resource was created via POST, allow update to the resource via POST (else return 412 error)
If the resource was created via PUT, allow update to resource via PUT (else return 412 error)
Can you please confirm if below implementation for PUT vs POST defies REST principle
It's probably wrong, but not necessarily so.
In particular, PUT in HTTP has very specific semantics
The PUT method requests that the state of the target resource be created or replaced with the state defined by the representation enclosed in the request message payload.
In other words, PUT is appropriate for replace, but it is not appropriate for modify.
So what your guideline is actually implying is that if you create a resource via a PUT of its representation, then all subsequent changes to that resource must also be complete replacements.
It's not obvious to me that's a good idea, and there is nothing in HTTP that requires you to be so strict; but it's certainly possible that your guideline authors had some bad experiences, which may be specific to the circumstances in which those guidelines apply.
The notes about using 412 response is... odd. Again, in HTTP, 412 has a very specific meaning; and that meaning is not related to the method used in the request. Using a conditional request to ensure that your edit doesn't conflict with another is good idea.
But if somebody has done a POST where they should do a PUT, or vice versa, then the correct status code to return in that case is 405.
The 405 (Method Not Allowed) status code indicates that the method received in the request-line is known by the origin server but not supported by the target resource. The origin server MUST generate an Allow header field in a 405 response containing a list of the target resource's currently supported methods.
Can you point me to the RFC?
There is no "RFC" for REST; it's not a standard, in that sense. REST is just a set of architectural constraints discovered by Roy T. Fielding during the early web standardization process. The appropriate reference is Chapter 5 of Fielding's thesis.
HTTP as a standard does (for the most part) use an architecture that satisfies the REST constraints. As of late 2016, the standard is documented by RFCs 7230-7235 inclusive.
A RESTful URL typically points to either a collection or an element.
A collection is typically denoted in plural and could look like this:
https://www.example.com/api/v1/cars
An element is typically adressed with its identifier and could look like this:
https://www.example.com/api/v1/cars/17
Collections can be children to elements:
<code>https://www.example.com/api/v1/workplaces/22/rooms</code>
Doing a POST to a collection usually means creating an element in the collection and the new element is typically returned with the response. The server would be responsible for creating the URI for the newly created element. It is the recommended "RESTful" way of creating elements.
Doing a POST to a element is not often used (and discouraged) as that would mean the client would be the one assigning the identifier. If used, most often, it means that you treat the element as a collection in itself and create a new element within it.
Doing a PUT to a collection is perfectly valid "RESTfulness" but would typically mean replacing the entire collection.
Doing a PUT to an element is common and typically means replacing the entire element, meaning that the entire element should be passed along in the request body. Some argue it is fine for the element to be created if it does not exist (but I would argue it being a bad request).
Doing a PATCH to an element typically means updating the element. The fields that should be updated are the only fields necessary in the request body.
I've never stumbled on doing a PATCH to a collection and would probably recommend against it.

Best practices for returning representation of resource that is also a collection

Let's say I want to make a RESTful interface, and I want to work with foos based upon their IDs. Nothing new here:
GET /api/foo1 returns a representation (e.g. using JSON) of foo1.
DELETE /api/foo1 deletes foo1.
etc.
Now let me tell you that a "foo" is a collection type thing. So I want to be able to add a "bar" to a "foo":
PUT /api/foo1/bar3 adds bar3 to foo1.
GET /api/foo1/bar3 returns a representation of foo1.
DELETE /api/foo1/bar3 removes bar3 from foo1.
DELETE /api/foo1 deletes foo1 altogether.
Now the question remains: what does GET /api/foo1 do? Does it it simply return a representation of foo1 as I originally assumed in this question? Or does it return a list of bars? Or does it return a representation of foo1 that is both a description of foo1 as well as includes a list of all contained bars?
Or should GET /api/foo1 merely return a representation of foo1 as I assumed at the beginning, and require a PROPFIND request to list the bars inside foo1 (the approach taken by WebDAV)? But then in order to be consistent, wouldn't I have to change all my other list-type functionality to PROPFIND, directly contradicting all those thousands of RESTful tutorials that say to use GET /api/foo1 to list the contents?
After some pondering, I think the best conceptual explanation from a RESTful perspective is that usually the "thing" is not the same thing as its "collection". So while in the WebDAV world a directory/ might be the same thing that holds its files, in the RESTful world I might have a separate directory/files/ subpath for the contained files. That way I can manipulate directories separately from the files that hold.
Consider a RESTful API for a farm which contains barns. The endpoint farm/api/barns/ might return a list of barns, one of which would be farm/api/barns/bigredbarn. Naively I would think that retrieving farm/api/barns/bigredbarn/ would provide me a list of animals in the barn, which is what prompted this question.
But really the animals in the barn is only one aspect of the Big Red Barn. It might contain vehicles and hay:
farm/api/barns/bigredbarn/animals/
farm/api/barns/bigredbarn/vehicles/
farm/api/barns/bigredbarn/haybales/
With this approach the dilemma I faced does not arise.
The semantics of webdav has never really been reconciled with the idioms of RESTful interfaces.
In theory, GET should retrieve a representation of a state of a resource and PROPFIND should be used to retrieve the members of a collection.
So you should do this:
GET /api/foo1/ - returns state of foo1 only
PROPFIND /api/foo1/ - returns the members of foo1
Most front end devs would freak out if you told them to use PROPFIND, although its completely supported in browser js implementations.
Personally i use a webdav/json gateway, where requests are made using RESTful idioms, but routed to my webdav implementation
For example i would do this:
GET /api/foo1/_PROPFIND?fields=name,fooProp1,fooProp2
And that would return
[
{ name : "bar1", fooProp1: "..", fooProp2 : ".."},
{ name : "bar2", fooProp1: "..", fooProp2 : ".."}
]
One advantage of this approach is that client's get to control the json properties returned. This is good because a rich API will have a lot of properties, but in most situations clients dont need all of them.
The routes and their operations in RESTfull API are completely designed by the developers. It's the developer who decides what to return while requesting a specific route say, GET /api/foo1.
And the developer should design every route including /api/foo1/bar. There is no specific rule on what a particular route should do. If your API is an open-source project make a clean and clear documentation of every route.
Don't waste your time thinking about the old school strategies.

REST - basic principles - Where to put the new and edit words

I'm wondering where to put the edit, and new keywords by rest application. I'll use express-resource in a project, and the default settings are these:
GET /forums -> index
GET /forums/new -> new
POST /forums -> create
GET /forums/:forum -> show
GET /forums/:forum/edit -> edit
PUT /forums/:forum -> update
DELETE /forums/:forum -> destroy
There is a problem with this solution: there is not a real resource behind the new and edit. I mean the URL-s refer to resources, and after any slash is a sub-resource.
For example:http://my.example.com/users/1 represents:
var firstUser = {
name: "John Smith",
birthDate: new Date(1952,10,4),
hobbies: ["skiing", "football"],
...
}
And http://my.example.com/users/1/birthDate represents:
firstUser.birthDate
But by http://my.example.com/users/1/edit there is no such property:
firstUser.edit
So something is wrong with this conception.
Where is the real place of these keywords? In queryString or in headers?
From the perspective of a REST API these do not exist anywhere as they are not related to the representation of resources. They are actions upon resources and therefore expressed by the HTTP methods used. They would not bee needed if you were to create an external client that uses the API.
There is likely a need to provide some support for this type of functionality so that something like a UI could be presented, but that is the concern of the particular application and not the API itself. At that point it becomes discretionary but I would certainly avoid using headers as that would be pretty outside of conventional practice. But by headers it appears that you actually meant URI path. Out of those 2 I would say the path is the better option since it clearly defines any type of UI as a distinct resource and would keep it apart from the clean API, while using a query string on a part of the API would more tightly (mistakenly) associate it with the underlying resource.
Some update after a year or so:
edit and new should be hyperlinks
these links are just the representations of possible operation calls
by following them it is possible to manipulate the resource they belong by sending representations of the intended resource state, and/or by calling the proper methods
these terms are no resources, they don't have their own URL (resource identifier)
Thanks the advices Matt Whipple!
I think the best way to learn REST is reading the Fielding dissertation. There are many tutorials out there, but the authors of most of these does not really understand REST.

Proper way to construct this REST URI?

I want to have a REST resource for Foo and I want to be able to perform a POST to create a new Foo.
Foos can only be of two subtypes - Fizz and Buzz (the models are FooFizz and FooBuzz on the backend and both extend Foo). All Foos are either a Fizz or a Buzz. Most of the other models follow this pattern too (generic with subtypes for Fizz and Buzz). For the short and medium term, there will not be a new type added to Foos. In the long term it's more likely that this application will be obsolete before a new type is added, but the possibility exists.
At any rate, here are some URI schemes I came up with for working with Foos.
POST /foo?type=fizz
POST /foo/fizz
POST /fizz/foo
POST /foo-fizz
POST /foo/{foo-id}/fizz
My thoughts on this:
(1) might be unnecessary client-server coupling since it's dependent on the query string being properly formed. But it makes the most sense to me.
(2) and (3) are undesirable because you want to be able to have the URI go /foo/{foo-id} for performing operations on an individual Foo.
(4) requires Fizzes and Buzzes to become completely separate branches of the URI tree
(5) seems like a decent scheme although it might mess up the URI tree.
I'd be strongly tempted to just have a POST to /foo with the type of foo to be created (fizz or buzz) being determined by the contents of the document being POSTed. It would respond with a suitable redirect to the URI for the newly created foo (/foo/{fooId}, presumably) through which you'd manipulate things in the normal way.
Admittedly, I am not a REST expert, however here are my two cents.
Why would you even have a post to foo/{foo-id}? In that case, it would be more of a PUT for an update. The only time you would need to post would be if the id was being auto-created and unknown until actually created. So, in that case, I would lean towards 1 as you are creating a foo and the rest is just information needed to create foo. After that point, would you even need to care about the subtype (fizz or buzz)? I would assume the foo/{foo-id} would be enough information to work on it individually and determine the type from it.
So:
POST /foo?type=fizz
**You could possibly even remove the query string and send it in as your creation data, but that is up to you
GET /foo/{foo-id} ...retrieve the created foo
PUT /foo/{foo-id} ...update the created foo
DELETE /foo/{foo-id} ...delete the created foo
That is what I would do at least.
<soapbox>If you are really doing a RESTful architecture, then you shouldn't need to ask this question</soapbox>.
RESTful architectures include links in the representation that direct the flow of the application. If you are creating a new resource that is a child of a parent resource, then the representation of the parent resource should have an embedded link that tells you what URL and (potentially) which verb to use. Something like:
<link rel="add-child" method="POST" href="http://foo/1234">Add a new child</link>
If you are creating a wholly new root resource then, you probably want to POST to an absolute URL and have either the response document or Location header tell your application where to retrieve a new representation from. The target resource is essentially the "entry point" into your application's state machine.