Can HTTP POST Be Used to Get Data -- Not Create New Data - http

Two things:
First, am I correct that an HTTP POST can be used to retrieve existing information? If so, what is the response code?
Second, if POST can be used, what id the format of the URL in a Web.API application, and what data should be sent to the server.
Company security does not prevent using HTTP Get, but they strongly discourage it because of some sort of security issues. OTOH, I really dislike naming a method PostInformation(), when I want to GET existing information.
Thanks

am I correct that an HTTP POST can be used to retrieve existing information?
From RFC 7231, section 4.3.3:
The POST method requests that the target resource process the representation enclosed in the request according to the resource's own specific semantics.
This implies that the server changes state while not strictly requiring it. So yes, while not really encouraged, this is safe to do. As a matter of fact, many web applications have done so in the past to circumvent limitations of the GET method such as overly long URLs.
what [is] the format of the URL in a Web.API application, and what data should be sent to the server.
The URL would be the same sans the query string. If you mark the body of your request being application/x-www-form-urlencoded, you can fill it with the same string you would normally use for the query string. For more complex or binary data, you should use multipart/formdata (see this answer).
I really dislike naming a method PostInformation(), when I want to GET existing information
That is pretty much a non-issue. I understand your worries, but consider this: What you ultimately do is getting data. How you do so is an implementation detail of the protocol in use. Nothing should prevent you from naming your method PostInformation(). Besides, what were you to do if the implementation changes and you suddenly used GET instead of POST? Refactor all occurences of PostInformation() into GetInformation()?

Related

Is POST the correct HTTP verb for resources that are produced by but not stored by the server?

Perhaps a partial duplicate of What is the correct http verb for a Download in a REST API? , though that is referring to a file download specifically.
In terms of CRUD operations, POST is the recommended HTTP verb for creating a resource. Does this still apply to creating resources, even if those resources are not persisted on the server? (i.e. stored in a database or similar) For example, generating some code based on code the client sent or converting a file and returning it to the client.
With such types of functionality, the server has indeed "created" something, though only in passing, returning or streaming it to the client, and not storing it in the traditional CRUD sense. I've always used POST for such functionality, but now I'm starting to double guess myself and think that those could have been GET endpoints the whole time.
Seems like a weird gray area in which neither HTTP verbs GET or POST completely match.
Is POST the correct HTTP verb for resources that are produced by but not stored by the server?
Yes - or alternatively, it's the least incorrect choice to use.
POST serves many useful purposes in HTTP, including the general purpose of “this action isn’t worth standardizing.” -- Fielding, 2009
In 2020, the HTTP-WG adopted a proposal to define a method token for "GET with a body", which would give as an alternative to POST when we want to indicate to general purpose components that the request has safe semantics, so there should eventually be some registered method that is a better fit.
There is no gray area here.
If the state of the server changes, use an unsafe method like POST. If it does not, you can use a safe methof like GET, as long as you stay within the documented limitations of GET (no request body).
If you're looking for a safe method that does take a request body, you may want to look at https://datatracker.ietf.org/doc/draft-ietf-httpbis-safe-method-w-body/.

Web API methods with lots of parameters

I am working on a Web API service for our Web application (current project). One controller in the Web API will be responsible to retrieve a list of entities of a certain type. So far so good. The problem is that we have a request to filter the list based on search criteria. This search/filter criteria has about a dozen different parameters, some of which can be null. So I figured I create a custom class (let's call it "EntityFilterCriteria") and I instantiate it on the Web application side with whatever filtering fields the user enters (I leave the ones that the user do not enter set to null). Now how do I pass this object to my Web API method? I do not want to build an URL with all parameters because it's going to be a huge URL, plus some parameters may be missing. I can't have a body in the GET HTTP command to serialize my EntityFilterCriteria object so what do I use? POST? It is not really a POST because nothing is updated on the server side. It is really a GET, as in "get me all the records that match this search criteria". What is the common approach in such situations?
Thanks,
Eddie
Serialize the class to JSON and post it to your server, the JSON string will be your post body. Once it is posted you can then deserialize into a class with the same signature. Most languages have either built-in support or free 3rd party modules that can do this for you.
Well the initial danger of using GET for such a request is that the longest url you can send which is guarenteed to work across all web browsers and servers is about 1400 bytes in length.
Personally I would use JSON to encode all of your filter parameters and submit them to the server in the body of a POST command due to the lack of size limit on the sent data.
While there is a semantic difference between GET and POST commands which was intentioned when the HTTP RFC's were written decades ago, those decades of practical use have shifted rather significantly (in the same way that barely anybody uses PUT or DELETE)
I don't see any drawbacks to use a POST method to execute your query and get the result back. For example, ElasticSearch uses this approach to execute queries against the database. See this link for example: http://exploringelasticsearch.com/searching_data.html. In REST, POST isn't necessary used to update data.
Hope it helps.
Thierry

HTTP OPTIONS - Not Cacheable?

I'm designing a RESTful service aligning to HATEOAS principles as much as possible. As a result, I need a way to have my cool URLs return a list of links describing available options. I'm using HAL-JSON to facilitate the data format so that's all good, but I'm now considering what HTTP method should pull this.
I'm sure I could stick with a simple GET, but from reading over the HTTP RFC, it seems that OPTIONS might fit the bill here. My only concern is in bold:
9.2 OPTIONS
The OPTIONS method represents a request for information about the
communication options available on the request/response chain
identified by the Request-URI. This method allows the client to
determine the options and/or requirements associated with a resource,
or the capabilities of a server, without implying a resource action or
initiating a resource retrieval.
Responses to this method are not cacheable.
Could someone with more experience on the standards side of the web please explain why this is the case? In my view, you would certainly want clients caching this result at least for a short period of time, as in a fully HATEOAS system this call is likely to be made quite frequently to traverse the rel links to arrive at the operation you're looking for.
I'd also love some opinions on using OPTIONS vs a simple GET for retrieval of operations from a cool URL.
The OPTION HTTP request returns the available methods which can be performed on a resource. (The objects methods)
I can not say for certain why you can not cache the response, but its most likely a precaution. Caching would have little value for the OPTION http method.
A Resource is "any information that can be given a name", that name is its URI. the response from the OPTIONs request is only a list of methods that can be requested on this resource (e.g. "GET PUT POST" maybe the response). To actually get at the information stored, you must use the GET method.
It's not cacheable, period. Sorry.

Which HTTP methods match up to which CRUD methods?

In RESTful style programming, we should use HTTP methods as our building blocks. I'm a little confused though which methods match up to the classic CRUD methods. GET/Read and DELETE/Delete are obvious enough.
However, what is the difference between PUT/POST? Do they match one to one with Create and Update?
Create = PUT with a new URI
POST to a base URI returning a newly created URI
Read = GET
Update = PUT with an existing URI
Delete = DELETE
PUT can map to both Create and Update depending on the existence of the URI used with the PUT.
POST maps to Create.
Correction: POST can also map to Update although it's typically used for Create. POST can also be a partial update so we don't need the proposed PATCH method.
The whole key is whether you're doing an idempotent change or not. That is, if taking action on the message twice will result in “the same” thing being there as if it was only done once, you've got an idempotent change and it should be mapped to PUT. If not, it maps to POST. If you never permit the client to synthesize URLs, PUT is pretty close to Update and POST can handle Create just fine, but that's most certainly not the only way to do it; if the client knows that it wants to create /foo/abc and knows what content to put there, it works just fine as a PUT.
The canonical description of a POST is when you're committing to purchasing something: that's an action which nobody wants to repeat without knowing it. By contrast, setting the dispatch address for the order beforehand can be done with PUT just fine: it doesn't matter if you are told to send to 6 Anywhere Dr, Nowhereville once, twice or a hundred times: it's still the same address. Does that mean that it's an update? Could be… It all depends on how you want to write the back-end. (Note that the results might not be identical: you could report back to the user when they last did a PUT as part of the representation of the resource, which would ensure that repeated PUTs do not cause an identical result, but the result would still be “the same” in a functional sense.)
I Was searching for the same answer, here is what IBM say.
IBM Link
POST Creates a new resource.
GET Retrieves a resource.
PUT Updates an existing resource.
DELETE Deletes a resource.
Right now (2016) the latest HTTP verbs are GET, POST, PATCH, PUT and DELETE
Overview
HTTP GET - SELECT/Request
HTTP PUT - UPDATE
HTTP POST - INSERT/Create
HTTP PATCH - When PUTting a complete resource representation is cumbersome and utilizes more bandwidth, e.g.: when you have to update partially a column
HTTP DELETE - DELETE
Hope this helps!
If you are interested on designing REST APIs this is an ansewome reading to have! website online version github repository
There's a great youtube video talk by stormpath with actually explains this, the URL should skip to the correct part of the video:
stormpath youtube video
Also it's worth watch it's over an hour of talking but very intersting if your thinking of investing time in building a REST api.
It depends on the concrete situation.. but in general:
PUT = update or change a concrete resource with a concrete URI of the resource.
POST = create a new resource under the source of the given URI.
I.e.
Edit a blog post:
PUT:
/blog/entry/1
Create a new one:
POST:
/blog/entry
PUT may create a new resource in some circumstances where the URI of the new ressource is clear before the request.
POST can be used to implement several other use cases, too, which are not covered by the others (GET, PUT, DELETE, HEAD, OPTIONS)
The general understanding for CRUD systems is GET = request, POST = create, Put = update, DELETE = delete
The building blocks of REST are mainly the resources (and URI) and the hypermedia. In this context, GET is the way to get a representation of the resource (which can indeed be mapped to a SELECT in CRUD terms).
However, you shouldn't necessarily expect a one-to-one mapping between CRUD operations and HTTP verbs.
The main difference between PUT and POST is about their idempotent property. POST is also more commonly used for partial updates, as PUT generally implies sending a full new representation of the resource.
I'd suggest reading this:
http://roy.gbiv.com/untangled/2009/it-is-okay-to-use-post
http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven
The HTTP specification is also a useful reference:
The PUT method requests that the
enclosed entity be stored under the
supplied Request-URI.
[...]
The fundamental difference between the
POST and PUT requests is reflected in
the different meaning of the
Request-URI. The URI in a POST request
identifies the resource that will
handle the enclosed entity. That
resource might be a data-accepting
process, a gateway to some other
protocol, or a separate entity that
accepts annotations. In contrast, the
URI in a PUT request identifies the
entity enclosed with the request --
the user agent knows what URI is
intended and the server MUST NOT
attempt to apply the request to some
other resource. If the server desires
that the request be applied to a
different URI,
Generally speaking, this is the pattern I use:
HTTP GET - SELECT/Request
HTTP PUT - UPDATE
HTTP POST - INSERT/Create
HTTP DELETE - DELETE
The Symfony project tries to keep its HTTP methods joined up with CRUD methods, and their list associates them as follows:
GET Retrieve the resource from the server
POST Create a resource on the server
PUT Update the resource on the server
DELETE Delete the resource from the server
It's worth noting that, as they say on that page, "In reality, many modern browsers don't support the PUT and DELETE methods."
From what I remember, Symfony "fakes" PUT and DELETE for those browsers that don't support them when generating its forms, in order to try to be as close to using the theoretically-correct HTTP method even when a browser doesn't support it.

HTTP Verbs and Content Negotiation or GET Strings for REST service?

I am designing a REST service and am trying to weight the pros and cons of using the full array of http verbs and content negotiation vs GET string variables. Does my choice affect cacheability? Neither solution may be right for every area.
Which is best for the crud and queries (e.g. ?action=PUT)?
Which is best for api version picking (e.g. ?version=1.0)?
Which is best for return data type(e.g. ?type=json)?
CRUD/Queries are best represented with HTTP verbs. A create and update is usually a PUT or POST. A retrieve would be a GET. Deletes would be a DELETE. Thats the generally mapping. The main point is that a GET doesn't cause side effects, and that the verbs do what you'd expect them to do.
Putting the action in the URI is OK if thats the -only- way to pass it (e.g, the http client library doesn't allow you to send non-GET/POST requests). Most libraries do, though, so its strongly advised not to pass the verb via the URL.
The "best" way to version the API would be using HTTP headers on a per-request basis; this lets clients upgrade/downgrade specific requests instead of every single one. Of course, that granularity of versioning needs to be baked in at the start and could severely complicate the server-side code. Most people just use the URL used the access the servers. A longer explanation is in a blog post by Peter Williams, "Versioning Rest Web Services"
There is no best return data type; it depends on your app. JSON might be easier for Ajax websites, whereas XML might be easier for complicated structures you want to query with Xpath. Protocol Buffers are a third option. Its also debated whether its better to put the return protocol is best specified in the URL or in the HTTP headers.
For the most part, headers will have the largest affect on caching, since proxies are suppose to respect them when told, as are user agents (obviously UA's behave differently, though). Caching based on URL alone is very dependent on the layers. Some user agents don't cache anything with a query string (Safari, iirc), and proxies are free to cache or not cache as they feel appropriate.

Resources