REST API HTTP GET with Body

11,752

Solution 1

I think the better solutions will be to use HTTP Get with body

RFC 7231 thinks otherwise:

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.

You can't count on general purpose components doing useful things with the body. For instance, caches will be using the target-uri as the primary cache key, and won't be considering the body at all. So strange behavior is likely there.

In effect, GET with a body is only going to work if you control the client, the web server, and the components in between. And if that is the case, you might as well define your own HTTP method with the semantics that you want it to have.

For example, you might look into HTTP SEARCH, and see if those semantics are a better fit for what you are trying to do.

That said, if you are trying to color inside the lines, it is okay to use POST.

POST serves many useful purposes in HTTP, including the general purpose of “this action isn’t worth standardizing.”


it's not REST because POST should be used to create data

REST doesn't define any sort of "create" constraint. REST says "use the appropriate method defined in the uniform interface"; HTTP says "use POST when no more specific method fits".

But if you are in an environment that won't accept that... one way to achieve what you want without "breaking the rules" is to think about creating a new resource that is the results of your query. So we POST some information, and that information gets associated with a new URI controlled by the server, and then subsequent attempts to GET the resource give you the results you want.

POST /foo

201 Created
Location: /c30e910e-7baa-4c31-9481-4c84c12884a1  
...Other Headers...

GET /c30e910e-7baa-4c31-9481-4c84c12884a1

200 OK
Content-Location: /c30e910e-7baa-4c31-9481-4c84c12884a1
...Other Headers...

The Answer

Following the standards, you can combine those two ideas to save a round trip

POST /foo

201 Created
Location: /c30e910e-7baa-4c31-9481-4c84c12884a1  
Content-Location: /c30e910e-7baa-4c31-9481-4c84c12884a1
...Other Headers...

The Answer

From there, it's a small step to

POST /foo

200 OK
...Other Headers...

The Answer

Solution 2

You have a good collection of questions, I'll answer based on my experience.

URL Limitation in size Generally, there is no limitation, but it's up to the browser and server, for example, Internet Explorer and Edge support 2083 Characters.

The HTTP specification provides HTTP Status Code 414, which will be returned when the server cannot handle the URL size.

.

Put a body in HTTP GET

Although technically it's possible, it's not the best practice.

The purpose of API is to share with other developer/application, so if you write a non-standard API it must be difficult for other developers who are going to consume it.

.

Use HTTP POST for Create

The restfulness is based on your architecture, not from the HTTP call you are going to use. Give meaningful response to the create call (HTTP Status Code 201)

Share:
11,752

Related videos on Youtube

S.Martignier
Author by

S.Martignier

Updated on May 27, 2022

Comments

  • S.Martignier
    S.Martignier almost 2 years

    I'm actually rewritting some APIs (in ASP.Net Core 3.1) we have at work and we try to make them RESTFull. I run into some methods where It should be called with HTTP GET because it's for retrieving some data but the parameters are wrapped in a pretty large DTO.

    So I was asking myself how to deal with it :

    • Let it put the DTO in the URL but then what are the limitation in size?
    • Put a body in the HTTP GET request. I made some search but the results I found were old. Apparently it's allowed but discouraged back in the time
    • Use HTTP Post, but then it's not REST because POST should be used to create data

    I think the better solutions will be to use HTTP Get with body (according to this article https://thecodebuzz.com/http-get-delete-request-body-guidelines/ it's possible)

    Have someone had the same issue? What are the guideline now a days?

    Thanks for your thoughts

    • CodeCaster
      CodeCaster over 3 years
      If you have a seach-like endpoint that accepts a lot of parameters, just make it POST. If you don't, and you aren't able to call your service "fully REST", what happens? Nobody will care.
    • Zinov
      Zinov over 3 years
      Does this answer your question? HTTP GET with request body
    • S.Martignier
      S.Martignier over 3 years
      @Zinov I've already read this post, but since it was made 11 years ago I was not sure It was still pertinent @ CodeCaster I know It's not such a big deal, but being a young programmer I want to learn as much best practice when I don't have bad habit of coding
    • Zinov
      Zinov over 3 years
      @S.Martignier there are a bunch of questions/answers around this similar topic, this will be creating a new thread of answers that are no needed. But answering part of your question, when you pass something in the body of your request you should use a Content-Type instead, semantically for the GET is wrong. Also you can check the specification here tools.ietf.org/html/rfc7231#section-3.1.1.5 . Also if you create a documentation for your API using swagger, the latest standard of openapi will be complaining about the body on a GET
  • S.Martignier
    S.Martignier over 3 years
    Thanks for the answer. About OAS3 can you point me to the part where it's say that they don't allow it? Because when I was making some research I found this PR github.com/OAI/OpenAPI-Specification/pull/2117 that allow body for GET For the Hackernoon article in the description of the POST they say it's for creating data (which I Know) and later in the article they said that if a GET request as a too long URL use POST so weird Can you tell me more about "Post a body via controller resource"? I don't understand what it's mean
  • API Alex
    API Alex over 3 years
    Hey, Your most welcome. I only found out about it as I imported an old API Blueprint into OAS3 and was warned it doesnt support Bodies with GETs, Its referenced on this page from SwaggerHub swagger.io/docs/specification/describing-request-body, Regarding posting to a controller that would be used for searching for things (these are the only resources that should have verbs in their names) Have a read through the naming conventions that gets into it restfulapi.net/resource-naming. Your link is interesting though that they merged it for OAS 3.0.1! Remains discouraged