Most server-side APIs these days are JSON-over-HTTP. Developers are generally comfy with this, but I notice when I look at the JSON that it’s often, uh, what’s the tactful term these days? Let’s say “generously proportioned”. And I see clumsy code being written to walk through it. The options for dealing with this are interesting.

For example · I’ve been working with keybase.io recently; when you talk to their directory through their API, an entry is represented by a User Object, which is not exactly lightweight; here’s part of one which may be retrieved here.

{ "status": { "code": 0, "name": "OK" }, "guest_id": "05a8fdd28c23a5d5dc2c2f588c3e7b08", "them": { "id": "922d9f5ffd96b34b9133483091738a00", "basics": { "username": "timbray", "ctime": 1395088335, "mtime": 1395088335, "id_version": 9, "track_version": 11, "last_id_change": 1396452398 }, "profile": { "mtime": 1395088563, "full_name": "Tim Bray", "location": "Vancouver, Canada", "bio": "Long-time Web guy, usually observed wearing ... }, "public_keys": { "primary": { "kid": "0101389af6856a7ef3392860... "key_type": 1, "bundle": "-----BEGIN PGP PUBLIC KEY BLOCK-----...

And it goes on from there. For quite a bit, actually. But for what I’m actually going to do, I only need a couple of those fields (ctime and the ASCII-armored public key). Compose in your head, if you will, the sequence of JSONObject.getString() calls you’d need to retrieve the key bits in the bundle field. Feaugh.

Also, consider all the extra JSON bytes occupying network space that I fully intend never to look at; so there are two problems here.

Plan A: JPath · Back in the days when APIs were all XML, I got into the habit, in clients, of fishing the bits I needed out of overinflated server blobs using XPath. A reasonable person might think “JPath?” And indeed, there’s JPath at stsvilik/jPath and at artjock/jpath and JPath on npm and JSONPath and json-path and so on, and they all define idiosyncratic selector-string syntaxes that do way past than just walk down an object chain.

Plausible; maybe there’s a there in there somewhere.

Plan B: Send less · Wouldn’t it be better if the server just sent what I need? It turns out that Google+ goes part of the way there, clients can ask for Partial Responses, using a fields argument.

Which, by the way, uses an idiosyncratic selector-string syntax.

It clearly works at slimming down your JSON on the wire, but you still have to do the dorky walk-down-the-object-chain logic in the client.

Plan C: JWalk · I cooked this up in about fifteen minutes to help me pick out pieces of Keybase.io responses, without really thinking it over much. To get the primary public-key bytes out of an HTTP response body, you say:

JSONObject user = new JSONObject(response_body); String key = JWalk.getString(user, "them", "public_keys", "primary", "bundle");

Source on GitHub, not that it’s very sophisticated or anything. It doesn’t allow you to select a particular array element, or jump steps with a “descendent” relationship or, well, anything; except walk through an object chain. So, no query string, just a JSON object and enough strings to get you where you want in the tree.

Hmm, it occurs to me that JWalk.getArray() should return an Iterator<JSONObject> , since the only thing I’ve ever done with a JSON array is traverse it.

I suppose JWalk could be broken out as a separate package, but why bother?

Questions · Why isn’t this built-in to the JSON-API infrastructure?

What are the use-cases for anything more complicated than an list-of-string-keys selector?

If we could agree on a way to pick out a few pieces you need, wouldn’t it be better to send it to the server as part of the query, rather than using it in the client?

If you do get a big blob of JSON and know you only want a couple of pieces, why go through all the parse-time memory-management overhead of building data structures to hold the parts you don’t want?