Turning a GET Into a POST While Still Staying RESTful

It Just Depends on What you Define as the Resource

Steven Li
2 min readOct 24, 2018

A GET Request With Too Many or Too Complex Query Parameters

A problem I’ve encounter in API design is making a GET request with too many query parameters, something that looks like:

GET   /api/v1/movies?criteria1=value1&criteria2=value2&criteria3=value3&
criteria4=value4&criteria5=value5&criteria6=value6&
criteria7=value7&criteria8=value8&criteria9=value9

But this request is problematic for a couple of reasons. The query parameters typically only work in logic conjunction with each other, making queries which involve a combination of logic conjunction and disjunction difficult. For example, a query to find all movies directed by the Coen brothers or Spike Jonze between 1990 and 2000 excluding all those staring Francis McCormack would be a very difficult query to write using query parameters. It’s possible, but very unwieldy.

Another problem with using query parameters is that the URI length is subject to a 2083 character limit, and in rare cases, query parameters do exceed that limit.

Make it a POST (and Still Have it be RESTful)

Instead of using the GET request for querying the resource of movies, define a new resource called a movie search, and design the API as a POST request. Something like

POST /api/v1/movie_search{
directors: {
logic: "OR",
values: ["Coen Brothers", "Spike Jonze"]
},
years: { from: "1991", to: "2000" }
cast: { logic: "NOT", values: ["Franchise McDormand"]}
}
Response:
{
results: [
{ title: "The Big Lebowski" },
{ title: "Being John Malkovich" }
]
}

The use of POST may not seem RESTful at first. We are still getting movies, not creating them so how is the use of POST justified? But notice we have redefined the resource not as movies but as a movie search. From this perspective, the POST action is justified since we are creating a movie search resource which is ephemeral and not persisted.

In fact, the key here is recognizing that POST creates a resource that does not have to be persisted . According to the RFC which defines POST:

The action performed by the POST method might not result in a    resource that can be identified by a URI. In this case, either 200    (OK) or 204 (No Content) is the appropriate response status,    depending on whether or not the response includes an entity that    describes the result.

Because POST doesn’t always have to create resources that persist, this allows us to RESTfully use POST in a lot of other ways as long as we define the resource (however abstract) in the right way.

--

--

Steven Li

Writing About Rails, React, Web Application Technology, Databases, and Software Engineering