How to edit a resource? - rest

Pardon the simple question, but it seems most searches try to tell me which methods are designed for what actions. Eg, create & edit is PUT, create from plural (articles) is POST, and so on. (If you disagree with this, i was just using it as an example. :)
With that said, how do you initiate a resource edit? To create a resource, with a known url you preform a GET on an non-existing URL. Eg, GET:mysite/resource_one. This then returns a form, and the form submits a PUT to the same address and bam, the resource is created.
Now how do you edit that same resource? With 4 Methods, designed for CRUD, i am having issues because i can only seem to think of one way. To go to a new resource. Eg, GET:mysite/resource_one/edit. This then presents a form with existing data, you edit it, and then the data is submitted to GET:mysite/resource_one. This seems odd to me in a system that seems to be designed to allow full CRUD to be preformed on a resource, without leaving said resource.
So.. what is the proper method? I mean, if GET:mysite/resource_one/edit is right, then why not GET:mysite/resource_one/delete, GET:mysite/resource_two/create, and so on..
Replies much appreciated!

The URL always represents the resource, not the action. Thus, while mysite/resource_one/edit might be a proper URL to a page that initiates editing a resource, it's not a part of the REST API itself, it's part of the web app that uses that REST API to manipulate that resource. Moreover, in that example mysite/resource_one would be a confusing representation of the resource.
To create a new resource, you use POST on the parent resource, with the body of the request containing the data for the new resource. The response contains the URL for the newly created resource.
To update an existing resource, you use PUT on the resource URL, with the body of the request containing either full or partial update of the resource data.

Related

How to model REST URL for which there is no equivalent HTTP method?

I have customers and I want to activate and cancel their plans. I am trying to be as RESTful as possible.
Should the action to perform 'active' or 'suspend' be part of URI ?
1) POST customers/{customerId}/activatePlan/{planName}
2) POST customers/{customerId}/suspendPlan/{planName}
My problem is that both activate and cancel are verbs or actions. They do not have any equivalent HTTP action ( GET, POST, PATCH etc.)
Are my URL's restful ? if not, how to make them REST ful.
Everything is a resource on the RESTful paradigm and these resources are manipulated with one of the HTTP methods (GET, POST, PUT, DELETE, etc ...).
You can create a plan with POST:
POST customers/{customerId}/{planName}
once a plan is created we have to activate or deactivate it and here we have a couple of choices:
Using the action in the URI. We use PUT in this case as the planName resource exists (so it is an update):
PUT customers/{customerId}/{planName}/activate
Set a property on the planName resource (still a PUT as it is an update on the planName resource). The activate property in the body of the HTTP PUT request (i.e.: activate=true or activate=false):
PUT customers/{customerId}/{planName}
then you can use GET to return the status of the planName resource
GET customers/{customerId}/{planName}
and DELETE if you want to remove planName from a customer:
GET customers/{customerId}/{planName}
Are my URL's restful ?
All URI are RESTful -- REST doesn't care what spelling conventions you use for your resource identifiers.
Notice, please, that both of the following URI work exactly as you would expect them to:
https://www.merriam-webster.com/dictionary/activate
https://www.merriam-webster.com/dictionary/cancel
My problem is that both activate and cancel are verbs or actions. They do not have any equivalent HTTP action ( GET, POST, PATCH etc.)
There are a couple of different answers. Perhaps the easiest is to think about how you would design a web site that allowed you to activate and cancel plans. You would probably have a web page for this customers enrollment, and on that page might be a link with some hint, like "cancel". Clicking the link would load a new web page, with a form on it, including a bunch of fields for the customer to fill in. When the customer submits the form, the browser looks at the form, and its meta data, and figures out what request to send to the server.
A "REST API" isn't about putting your domain model on the web - it's about putting your interaction model on the web. We create a collection of documents (resources) that describe the domain, and we get useful work done by moving those documents around the network. See Jim Webber 2011.
Because we are working in the language of documents, REST interfaces are usually based on one of the following ideas
Here is a document; make local edits to your copy of the document, and send it back to the server (GET, PUT, PATCH, DELETE are the primary method tokens you see in this style)
Here is a form; fill in the details and submit it (GET and POST are the method tokens you see in these cases)
If you are unhappy with the use of POST, it may help to review Fielding 2009
POST serves many useful purposes in HTTP, including the general purpose of “this action isn’t worth standardizing.”

Restful Design - Parent collection object in response when POSTing a resource

Let's say we have a collection resource called shelf (of book resources) and we would like to POST a new book:
[POST] /shelves/{shelf-id}/books [request body -- a book]
I know that the response should be either empty with a reference to the newly created resource (201) or include the created resource (200).
Let's say the clients that are creating book resources, will need to show summary of the shelf the new book is added to. One solution should be making clients to first do a POST (let's call it Req#1 -- to create the new book), and then a GET (Req#2) on the shelf resource to get the summary.
What if we care a lot about efficiency and want to return the result of Req#2 implicitly when getting Req#1 on the server and save one request on the client side? Is it OK based on REST principles to return the parent collection resource information in the response when a resource is added to the collection?
Any alternative design?
It's 'OK' for REST design to return different resource states, but HTTP doesn't have a standard way to do this. If you uses the HAL format for you REST api, it does have a way to do embedding, so I suppose you could embed different resources to the response of a POST request.
Note that there's no standard I know of that suggests that the following statement is true: I know that the response should be either empty with a reference to the newly created resource (201) or include the created resource (200).
Anyway, what are you trying to solve? Is it really that expensive to do an extra HTTP request? Where do you base that concern on? What's expensive about it? Is it the latency of having to do an extra roundtrip?
If that's the case, you could consider using HTTP/2 push to push a new version of your parent resource. It's probably the most standards compliant way. If your server and client support this well, then this also means you can use this as a great standard mechanism to push things to clients because they might soon request it.
I know that the response should be either empty with a reference to the newly created resource (201) or include the created resource (200).
This isn't true. According to the spec:
The newly created resource can be referenced by the URI(s) returned in the entity of the response, with the most specific URI for the resource given by a Location header field. The response SHOULD include an entity containing a list of resource characteristics and location(s) from which the user or user agent can choose the one most appropriate. The entity format is specified by the media type given in the Content-Type header field. The origin server MUST create the resource before returning the 201 status code.
In summary, use a 201 status response with information about the new resource. Please don't mix information about other resources with it. That is not RESTful, and apart from pedantry, it probably will make a messy API for very little benefit.

REST - Creating Nested Resources with single POST

Thinking in a RESTful way, is it correct to use POST to create in a single call a resource and its sub-resource?
In my application I have the resource /notices/{notice} and sub-resource /notices/{notice}/photos/{photo}. A {photo} can't exists without a {notice}, but a {notice} doesn't have necessarily photos. Normally, I have to do first a POST to create a notice, then another POST to add a photo.
Now I want to allow the creation of a notice with a photo directly attached, enabling the creation of /notices/{notice} and /notices/{notice}/photos/{photo} with a single POST request to /notices/{notice}/photos/{photo}, with a multipart content describing both the resources (JSON for notice, binary for the photo). I think I will return the Location header only for the sub-resource.
Essentially, I want this to prevent Android clients to send two POST request to the server to upload a notice with a photo.
Is this correct? Or does it infringe REST principles? Should I consider to keep them separate and make two different requests? Or is it wrong to consider photos a separate entity from the notice? Should I keep only /notices/{notice} as resource, using PUT to add photos?
Which is the best solution?
Yes, there is nothing wrong with creating sub-resources at the same time you create the parent resource. It would even be OK to use PUT instead of POST to do this, as everything under the parent URL is part of/belongs to the resource you are uploading.
EDIT:
Now I want to allow the creation of a notice with a photo directly attached, enabling the creation of /notices/{notice} and /notices/{notice}/photos/{photo} with a single POST request to /notices/{notice}/photos/{photo}
This I disagree with. I suggest POSTing to the collection resource's URL, /notices. You provide the notice and its photos as a single representation (request body). The back end will then create resources for both the notice and any constituent photographs.
Although its essential in many cases, multiple edits/creates are not formally addressed by the RESTful architecture style.
Problem starts when you need to report failures on part of the collection, and the problem is worsen when they failures have different cause.
An it will effect choosing the right Hypermedia controls which are essential for the client to find a way forward in the given transaction/conversation.
so my suggestion is to have a nested cycle or POST requests rather than a sing POST to create nested Resources , so that it'd be easier and clearer to address each Resource state change.

Should I use a POST request on /resources/ or PUT request on /resources/id/ to create a new object?

What's the RESTful way to create an object?
Should I use POST on the /resources/ URI and return the URI to the newly created resource in the response or should I use PUT on the /resources/id/ URI?
A GET request for /resources/id/ would surely return a 404 but should PUT return a 404 as well?
Should both methods be used to create a new object?
Generally, you will use either or both depending on whether or not you want the client (and therefore the user) to define the URI or not. If the client POSTs to resources/ then the server gets to determine the URI for the resource. If the client PUTs to resources/{id}/ then the client is determining the URI for the resource.
One exception is if creation involves links, states, and other items that are not then properly considered part of the resource--you generally cannot PUT these extra "constructor args" if you will, since they are not part of the resource state. Instead, you must POST in that case.
Even if you use POST for creation, you still might then want to expose PUT for updates. It depends on the resource.
If you don't allow a PUT to create then yes, you should return 404 in that situation.

How do you implement resource "edit" forms in a RESTful way?

We are trying to implement a REST API for an application we have now. We want to expose read/write capabilities for various resources using the REST API. How do we implement the "form" part of this? I get how to expose "read" of our data by creating RESTful URLs that essentially function as method calls and return the data:
GET /restapi/myobject?param=object-id-maybe
...and an XML document representing some data structure is returned. Fine.
But, normally, in a web application, an "edit" would involve two requests: one to load the current version of the resources and populate the form with that data, and one to post the modified data back.
But I don't get how you would do the same thing with HTTP methods that REST is sort of mapped to. It's a PUT, right? Can someone explain this?
(Additional consideration: The UI would be primarily done with AJAX)
--
Update: That definitely helps. But, I am still a bit confused about the server side? Obviously, I am not simply dealing with files here. On the server, the code that answers the requests should be filtering the request method to determine what to do with it? Is that the "switch" between reads and writes?
There are many different alternatives you can use. A good solution is provided at the microformats wiki and has also been referenced by the RESTful JSON crew. As close as you can get to a standard, really.
Operate on a Record
GET /people/1
return the first record
DELETE /people/1
destroy the first record
POST /people/1?_method=DELETE
alias for DELETE, to compensate for browser limitations
GET /people/1/edit
return a form to edit the first record
PUT /people/1
submit fields for updating the first record
POST /people/1?_method=PUT
alias for PUT, to compensate for browser limitations
I think you need to separate data services from web UI. When providing data services, a RESTful system is entirely appropriate, including the use of verbs that browsers can't support (like PUT and DELETE).
When describing a UI, I think most people confuse "RESTful" with "nice, predictable URLs". I wouldn't be all that worried about a purely RESTful URL syntax when you're describing web UI.
If you're submitting the data via plain HTML, you're restricted to doing a POST based form. The URI that the POST request is sent to should not be the URI for the resource being modified. You should either POST to a collection resource that ADDs a newly created resource each time (with the URI for the new resource in the Location header and a 202 status code) or POST to an updater resource that updates a resource with a supplied URI in the request's content (or custom header).
If you're using an XmlHttpRequest object, you can set the method to PUT and submit the data to the resource's URI. This can also work with empty forms if the server supplies a valid URI for the yet-nonexistent resource. The first PUT would create the resource (returning 202). Subsequent PUTs will either do nothing if it's the same data or modify the existing resource (in either case a 200 is returned unless an error occurs).
The load should just be a normal GET request, and the saving of new data should be a POST to the URL which currently has the data...
For example, load the current data from http://www.example.com/record/matt-s-example and then, change the data, and POST back to the same URL with the new data.
A PUT request could be used when creating a new record (i.e. PUT the data at a URL which doesn't currently exist), but in practice just POSTing is probably a better approach to get started with.