GET or POST for stateless RESTFUL API - rest

I'm writing a stateless API. You send it a document, it processes the document, and then returns the processed document. I'm struggling to understand how the RESTFUL rules apply. I'm not retrieving data, creating data or updating data on the server. There is no data on the server. What do I need to use in this case as the http method and why?

Good news - you are right that it is confusing.
Nothing on the server changes in response to the request. That suggests that the request is safe. So GET is the natural choice here... BUT -- GET doesn't support message payloads
A payload within a GET request message has no defined semantics; sending a payload body on a GET request might cause some existing implementations to reject the request.
HEAD, the other ubiquitous safe method, has the same problem (and is unsuitable when you want to return a document in any case).
The straight forward thing to do at this point is just use POST. It's important to realize that POST doesn't promise that a request is unsafe, only that it doesn't promise that it is safe -- generic components won't know that the request is safe, and won't be able to take advantage of that.
Another possibility is to look through the method registry, to see if somebody has already specified a method that has the semantics that you want. Candidates include SEARCH and REPORT, from the WebDAV specifications. My read of those specifications is that they don't actually have the right semantics for your case.

A Lot of ways to do what you want. But here is a small guideline.
I would create an endpoint that receives the document:
/receive_document
with a 'POST' method. Since you are 'sending' your document to the server
I would create an endpoint that serves up the processed document:
/processed_document
with a 'GET' method. Since you want to retrieve / see your document from the server?

The problem that you are trying to solve is mainly related to the document size, and processing time before returning the response.
Theorically, in order to use a restful approach, you have an endpoint, like yourhost.com/api/document-manager (it can be a php script, or whatever you are using as backend).
OK, so instead of naming the endpoint differently for each operation type, you just change the HTTP method, I'll try to make an example:
POST: used to upload the document, returns 200 OK when the upload is completed.
GET: returns the processed document, you can also return a different HTTP code, in case the document is not ready or even different if the document hasn't been uploaded. 204 no content or 412 precondition failed can be good candidates in case of unavailable document. I'm not sure about the 412, seems like it's returned when you pass a header in the request, that tells the server which resource to return. In your case, I think that the user processes one document at time. But to make a more solid api, maybe you can return an ID token to the user, into the POST response, then forward that token to the GET request, so the server will be able to know exactly which file the user is requesting.
PUT: this method should be used when updating a resource that has been already created with POST
DELETE: removes a resource, then return 204 or 404
OPTIONS: the response contains the allowed methods on this endpoint. You can use it to know for example which privileges has the currently logged user on a resource.
HEAD: is the same as a GET call, but it shouldn't return the response body. This is another good candidate for you to know when the document has been processed. You can upload with POST, then when the upload is done, start some kind of polling to the same endpoint with the HEAD method, finally when it will return "found", the polling will stop, and make the final GET call, which will start the download of the processed document.
HTTP methods are a neat way of managing HTTP communications, if used properly are the way to go, and easily understandable by other developers. And not to forget, you don't have to invent lots of different names for your endpoints, one is enough.
Hope that this helped you a little... But there are loads of guides on the net.
Bye!

Related

Recommended or not: Sending a JSON body via POST HTTP Request without modification

Is it recommended to send a JSON body via a POST HTTP Request which doesn't modify anything?
Based on the link below, a Get request is not recommended to have a body. Thus, the other way is the one above.
HTTP GET with request body
Example:
Get the list of users, or anything for that matter based on parameters.
Http GET example.com/users
Body
{
name:"John",
age:1,
... long list of parameters
}
Is it recommended to send a JSON body via a POST HTTP Request which doesn't modify anything?
The rule is that POST is the default; it should be used unless there is something better.
For a request with "effectively read only" semantics, you want to use GET instead of POST... if it works. The challenge can be those cases where the request-target (aka: the URI) gets long enough that you start running into 414 URI Too Long responses. If your identifier is long enough that general purpose components refuse to pass the request along, then it is not something better, and you fall back to POST.
An origin server SHOULD NOT rely on private agreements to receive content, since participants in HTTP communication are often unaware of intermediaries along the request chain. (HTTP Semantics, 9.3.1)
In other words, introducing a private agreement to include content in a GET request trades away inter-op, which - if you want "web scale" - is not a winning trade. So GET-with-a-body is not better, and you fall back to POST.
The HTTP working group has been working on semantics for a new "effectively-read-only-with-a-body" method token, which could prove to be an alternative for requests where you need to include a bunch of information in the body because it is too long to encode it into the URI. But we don't have a standard for that today, which means that it is not something better, and you fall back to POST.

Payload for PUT vs POST in REST API

I was asked below question in the Interview -
If you are hitting the same request with PUT and with POST http method then what will be the difference in payload?
Considering I don't have much experience working in REST, I didn't even know what payload is. I tried googling but didn't find anything conviencing.
Can anyone help?
according to this page restfulapi.net the PUT request should refer to already existing item (for example in a database connected). In other words, it is meant to update existing item. So the payload don't have to contain all the attributes of the item, just those you want to update.
On the other hand POST is meant to insert new item. This means that the payload should contain (almost) everything.
Thing is, if you send more same PUT requests, the item should remain equivalent to the situation with just one PUT send.
If you send two same POST requests then two new same items (with different ids) will be created. This means that POST requests are not idempotent.
Edit: here might be help too.
I didn't even know what payload is.
The interviewer is probably referring to the message-body of the HTTP Request (see RFC 7230).
If you are hitting the same request with PUT and with POST http method then what will be the difference in payload?
This is probably an attempt to explore whether you understand the difference in semantics between the HTTP POST method and the HTTP PUT method.
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.
Think "save file".
The instructions for POST are a lot less specific
The POST method requests that the target resource process the representation enclosed in the request according to the resource's own specific semantics.
If that seems vague... you're right! The message-body of a POST request can mean almost anything. POST is the "junk drawer" of HTTP methods - anything not worth standardizing goes there.

Requesting RESTful GET with meaningful Body? Standards not clear

We found ourselves in a dead end when trying to follow standards as we need to build a request that should be a GET and should have a meaning Body.
The request just wants to retrieve some data, no modification inside the database, just getting some data. But at the same time we need to send an array of ids for the objects we want to retrieve, and no, these objects can't be indexed in any way so we really need to send the list of ids or alternatively make 100 requests to the server to get them one by one. That's not gonna happen.
We could also add the list to the URL, but we can't be sure the URL won't end up being too long if the list of ids were to be too big. So to ensure the system doesn't fail we want to use the Body.
I read that a GET can have a Body, but only if it isn't meaningful:
HTTP GET with request body
Yes. In other words, any HTTP request message is allowed to contain a message body, and thus must parse messages with that in
mind. Server semantics for GET, however, are restricted such that a
body, if any, has no semantic meaning to the request. The requirements
on parsing are separate from the requirements on method semantics.
So, yes, you can send a body with GET, and no, it is never useful to do so.
This is part of the layered design of HTTP/1.1 that will become clear again once the spec is partitioned (work in progress).
....Roy
But our Body IS meaningful, which takes us to have to decide between unfollowing HTTP standards or unfollowing REST standards.
Is there any alternative to that? (It's not that this blocks us but I would like to know the answer).
Thank you very much.
you should consider changing your request to POST method.
As I understand it, there are three potential issues with a GET with request body: (link to blog)
Not all servers will support this.
Not all tools will support this (Swagger, POSTMAN added support this year: https://github.com/postmanlabs/postman-app-support/issues/131)
There is not yet a consensus on GET with request body. (For example, is Dropbox still using a POST)
so you'll have problems process the body with GET

How to send response code in REST services.?

I am developing RESTful Services to CREATE operations. In my use case, it is enough to tell the clients whether the transaction is success or fail. And if fail, we need to send them back error code.
Is it possible to send only these information back without sending xml response or JSON response. If so, how to do it.
We have existing error code in 5 digits, we wont be changing this for this api. If this is not possible.
Will JSON response better than XML response.? We are accepting XML request.
Requesting your comments.
I'm going to assume this service will be called over HTTP, since that's what most people mean when they say "RESTful service."
Generally speaking, most people map "create" type functionality to POST methods (though you can also do it with PUT).
If you just need to indicate that the record was created, the answer is "None of the above" (i.e., you don't need a response body at all). Usually a 201 Created is returned with a Location header which specifies the URL of the newly-created resource. In theory, you could also return a 204 No Content since you don't need to pass anything other than the status code (though this would be more appropriate for a PUT, otherwise there is no way to communicate to the client the identifier of the newly-created resource).
For failures, usually a 400-series error is returned if the request message is bad (i.e., it's the client's fault) and a 500-series error is returned if a system error occurs when processing (i.e., it's the server's fault). If you need to convey additional information in the response body, consider returning a response that uses a media type of something like application/vnd.error which allows you to express context information about where the error occurred.

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.