API Design – Is Passing JSON Objects on the Query String a Bad Idea?

api-designjsonrestweb-api

I'm building an API endpoint for a UI grid to search, filter, and display a list of domain objects, let's call them "widgets." In the past, I would have built this with a list of named query string parameters, like this:

GET /api/v1/widgets?type=2&name=what&from=2019-12-31&to=2020-01-03&pagesize=25&page=2&sort=name,-createdate

This would result in SQL something like

SELECT <selectlist>
FROM widget
WHERE type = 2
    AND name LIKE 'what%'
    AND createdate >= '2019-12-31'
    AND createdate <= '2020-01-03'
ORDER BY name ASC, createdate DESC
LIMIT 25, 25;

I've had a co-worker propose that instead of a long list of parameters, we pass a couple of JSON objects on the query string, like this:

"filters": {
    { "column": "type", "operator": "=", "value": 2 },
    { "column": "name", "operator": "like", "value": "what" },
    { "column": "createdate", "operator": ">=", "value": "2019-12-31" },
    { "column": "createdate", "operator": "<=", "value": "2020-01-03" }
},
"pagination": {
    "page": "2",
    "pagesize": "25",
    "sort": [ "name", "createdate" ],
    "sortdirection": [ "asc", "desc" ]
}

Which, after encoding, looks something like this as a URL (sorry if I messed up the encoding, I made this up as an example):

GET /api/v1/widgets?filters=[%7B%22column%22:%22type%22,%22operator%22:%22%3D%22,%22value%22:2%7D,%7B%22column%22:%22name%22,%22operator%22:%22like%22,%22value%22:%22what%22%7D,%7B%22column%22:%22createdate%22,%22operator%22:%22%3E%3D%22,%22value%22:%222019-12-31%22%7D,%7B%22column%22:%22createdate%22,%22operator%22:%22%3C%3D%22,%22value%22:%222020-01-03%22%7D]&pagination=%7B%22page%22:%222%22,%22pagesize%22:%2225%22,%22sort%22:[%22name%22,%22createdate%22],%22sortdirection%22:[%22asc%22,%22desc%22]%7D

We are in JavaScript on both client and server, so parsing the JSON object is not a difficult task. And I realize that the structure of the JSON object for querying would have to be altered, as it does not account for some things. Disregarding that, the basic question is:

Is this a bad/good idea? I see advantages and disadvantages, but I'm trying to look past my personal bias.

Best Answer

Its not a brilliant idea. The URI is not really a good place for data of unpredictable length, and although there is no 'official' maximum length, many webservers apply their own limit (IIS is 2083 characters, for example). Some webservers also have restrictions on acceptable characters in URIs.

There are also other considerations that are generic to URIs. Are the contents of the query in any way sensitive? Many servers will log URIs and query string parameters which may leave sensitive data in places you dont want it.

For this kind of variable length data, using HTTP Post would be best solution.

If you did still want to use the query string, another option would be to base64 the JSON string, meaning you wouldnt need to worry about escaping the spaces and special characters. This would mean the URI was not 'human readable', but I would argue that URI encoded JSON isn't particularly easy to read either.

Related Topic