🔍 Transparent query, pointer and path descriptors for JSON
json-where
converges the following standards and libraries in order to help normalize JSON query/addressing descriptors:
- JsonPath
- Specification: http://goessner.net/articles/JsonPath/
- Library: https://www.npmjs.com/package/jsonpath
- JsonPointer
- JsonQuery
The goal is to increase developer transparency and to provide a unified interface for matching related JSON data.
json-where
's simple interface spares developers from having to:
- decide between which query/addressing specifications(s) to support in their projects
- write an interface for when more than one standard needs support
- bottleneck integrators of their library into a certain specificaton
- write a mechanism that provides a consistent return format (e.g. array vs. element)
npm install json-where
This example shows how to use the main feature of json-where
, which is being able to provide any descriptor string to $
.
The $
"operator" will automatically imply the correct specification to use based on the descriptor itself:
import $ from 'json-where'
const data = {
foo: {
bar: 'baz'
}
}
let query = $('foo.bar').use(data).get() // 'baz'
let path = $('$.foo.bar').use(data).get() // 'baz'
let pointer = $('/foo/bar').use(data).get() // 'baz'
If you want to be slightly more concise you can avoid calling use
:
let query = $('foo[bar]', data).get() // 'baz'
let path = $('$.foo.bar', data).get() // 'baz'
let pointer = $('/foo/bar', data).get() // 'baz'
You may also, of course, access and use each specification individually:
import { query, path, pointer } from 'json-where'
query('foo[bar]', data).get() // 'baz'
path('$.foo.bar', data).get() // 'baz'
pointer('/foo/bar', data).get() // 'baz'
You can easily specify whether or not you should expect a single object or a collection:
$('foo[bar]', data).one() // 'baz'
$('foo[bar]', data).all() // ['baz']
A couple of common utility methods are also defined for working with collections:
$('foo[bar]', data).count() // 1
$('foo[bar]', data).any() // true
$('bar[baz]', data).any() // false
You can infer the specification directly from the descriptor itself via which
:
which('foo[bar]') // 'json-query'
which('$.foo.bar') // 'json-path'
which('/foo/bar') // 'json-pointer'
Currently only json-pointer
supports updating values via descriptors:
const path = pointer('/foo/bar', data)
path.get() // 'bar'
path.set('zab') // ...
path.get() // 'zab'