One scenario is when you're creating a search endpoint. In the example below, I want to search a database of companies and the queries can become complicated; enough where I want to have the parameters passed as JSON objects instead of a flat list.
var hapi = require('hapi');
var joi = require('joi');
var server = new hapi.Server();
server.connection({port: 5555});
var simpleRoute = {
method: 'GET',
path: '/company/search',
config: {
validate: {
query: {
company: joi.object().keys({
name: joi.string(),
address: joi.string()
})
}
}
},
handler: (request, reply) => {
reply({
input: request.query,
results: 'SOME RESULTS'
});
}
};
server.route(simpleRoute);
server.start(() => {
console.log('server started -- ' + server.info.uri);
});
And the url for this looks like http://localhost:5555/company/search?company=%7B%22name%22%3A%22Cuthbert%22%2C%22address%22%3A%22123%20Main%20St%22%7D
.
The url is messy and doesn't look great and for a client-facing website, this can be difficult for a user to recreate if they wanted to redo a search.
There's also the character limit on urls. It's unlikely I'll hit it, but what happens a query becomes too complex for a GET request? I can change the route to POST/PUT, but the search also isn't modifying any data on my server.
So how do I pass complex objects over http while still making correct use of GET, PUT, POST, etc.?
Best Answer
Elastic Search has this issue, as well: their solution was to allow GET requests with bodies:
Though non-standard, it's not technically a violation of HTTP/1.1:
However, RFC 7321 does acknowledge that bodies of GET requests have no defined semantics:
Because of this, clients don't technically need to support GET requests with bodies, and for this reason, Elastic Search also accepts search queries via POST.