Why JSON in URLs Is Worth Reconsidering

HTTP APIs commonly pass arguments through URL paths and query parameters. A typical Dropbox API search call looks like this:

/1/search/auto/My+Documents?query=draft+2013

That works for simple cases, but the encoding rules behind those URLs hide real complexity — complexity that JSON in the URL could help eliminate.

The Path Component Problem

Consider the plus sign. In a URL path, + is a literal character. In a query string, it decodes as a space. Both rules are easy to mix up, especially when libraries name their encoding functions ambiguously with terms like "urlencode." A bug in an early version of one SDK at Dropbox came from exactly that confusion.

The forward slash is another trap. /hello-world and /hello%2Dworld are equivalent. But /hello/world and /hello%2Fworld are not — the slash is a reserved delimiter whose percent-encoded form changes meaning. Most encoding libraries don't highlight how much is at stake, and often it doesn't matter. Occasionally, it matters a great deal.

Query Parameters Lack Expressiveness

URL query strings handle lists and nesting awkwardly. A list can be encoded with commas or repeated parameter names:

/docs/salary.csv?columns=1,2
/docs/salary.csv?column=1&column=2

Nested object fields require their own conventions:

/emails?from[name]=Don&from[date]=1998-03-24&to[name]=Norm

None of these are standardized; they're all workarounds. JSON expresses nesting naturally and consistently, so sending structured data in the URL removes the need to invent ad-hoc syntax for lists and objects.

Encoding Has Its Place

URL encoding isn't inherently bad — it fits human-interactive use well. JSON requires quoting every string, which adds robustness but makes URLs harder to type by hand. A quick parameter like ?a=b is far more readable than its JSON equivalent. For browsers and casual debugging, that tradeoff makes sense.

But an API isn't a browser. It's machine-to-machine communication, and that changes the calculus. The error-prone nature of URL encoding invites bugs, and any code that parses parameters reimplements the same complexity. JSON in URLs pushes further along the spectrum the same direction APIs have already moved elsewhere: structured, robust formats in place of loose string conventions.

APIs Already Prefer JSON

The industry has already settled on JSON for structured response bodies. URL-encoded response bodies essentially vanished after OAuth 1 — OAuth 2 moved to JSON. Request bodies are still split between formats, partly because URL encoding allows clean curl examples. But many modern APIs, including Dropbox's, increasingly use JSON payloads for requests.

That raises the question: why not also send JSON in the URL? A typical argument against is appearance and length:

  • URL-encoded: /log?a=b&c=4
  • JSON in URL: /log?%7B%22a%22:%22b%22,%22c%22:4%7D

JSON is longer, which could push requests near practical URL length limits. But ugliness solves itself with a good abstraction layer: developers should only face the decoded URL in error messages and logs, similar to how network packets remain invisible in normal operation.

Building that abstraction takes effort, especially when you're used to getting by without one. The upfront annoyances of JSON-in-URL encoding are real, but for APIs handling structured data, the consistency and clarity may justify the investment.