Skip to content

Latest commit

 

History

History
128 lines (115 loc) · 7.36 KB

json-rql.md

File metadata and controls

128 lines (115 loc) · 7.36 KB

github licence npm

json-rql

JSON Resource Query Language, for simple, consistent query APIs

json-rql is a convention for expressing queries against structured resources, using JSON. It helps resolve the tensions between expressibility and simplicity, and between agility and future-proofing, in API design. It is based on JSON-LD.

A simple example query:

{ "@where" : { "@type" : "Person", "birthPlace" : { "name": { "@contains" : "London" } } } }
  1. It's JSON: straightforward to construct in code, manipulate and serialize, and also to constrain. Use standard JSON tooling such as JSON schema to limit your API to the queries that your back-end has been designed and tested for.
  2. It's SPARQL: in context, all queries can be translated to the W3C standard language for directed, labeled graph data. This means that your API can be extended to cover future query requirements, without breaking changes.

See the project wiki for more discussion of the motivation behind json-rql.

syntax

Here we describe the syntax of json-rql informally in terms of JSON constructs (hashes and keys), for introductory purposes. The type definitions below and in the navigation panel on the left gives a more formal specification.

Hint: links are provided from keywords to examples. Note that these are rather SPARQL-ish, in that they make extensive use of prefixes and IRIs. An API doesn't have to use these much, if at all. Also linked in the formal type documentation are various SPARQL and JSON-LD definitions. Again, you generally don't have to follow these links to be able to use json-rql effectively; the examples given should be sufficiently explanatory.

All json-rql queries are an object/hash at top level (one of the sub-types of Pattern). All the recognised keys of this hash are keywords, which start with a @. However, any other keys can exist as required by the API design, such as a name or description for the query.

The recognised query keys are:

  1. @context: A JSON-LD Context for the query. In an API this is likely to be implicit. For example, using json-rql as the body of a POST to http://example.com/my-api/v1/person/query might have the implicit context of a Person (possibly found at http://example.com/my-api/v1/person). As a user of the API, therefore, you may not need to consider the Context.
  2. One of four options for the returned data. Again, in a typical API the choice will often be implicit, and the key omitted.
    • @construct specifies a Subject for the requested data, using Variables to place-hold data matched by the @where clause.
    • @describe specifies an IRI, a Variable, or an array of either. Each matched value will be output in some suitable expanded format, such as an entity with its top-level properties.
    • @select specifies a Result, which defines a set of outputs. The output will be a table of atomic values.
    • @distinct is like @select but returns only unique rows.
  3. @where specifies a Pattern to match, or an array of Patterns to match. Each can be a Subject, a Group, or another query (a sub-query).
  4. @orderBy specifies an Expression or array of expressions to order the results by.
  5. @groupBy specifies an Expression or an array of expressions to group the result by.
  6. @having specifies an Expression to filter individual grouped-by members.
  7. @values specifies a Variable Expression or array of Variable Expressions that define inline allowable value combinations for the query variables.
  8. @limit and @offset specify integer paging for the results.

This is a JSON-LD object with the following non-compliances:

  1. Object keys and values can be Variables like "?variable".
  2. Values can be in-line filters, of the form { <operator> : <Expression> }. The operator is acting as an infix, and in this case the Expression represents only the RHS. The object may specify a variable to be matched against the filter by including an @id key as well as the operator, like this: { "@id" : "?variable", <operator> : <Expression> }.

A Group object has one or more of the following keys:

  1. @graph specifies a Subject or an array of Subjects to match.
  2. @filter specifies a Constraint or an array of Constraints, each of the form { <operator> : [<Expression>...] }. Note that filters can also be specified in-line inside a Subject, see above.
  3. @union specifies an array of alternative Patterns (Subject, Group or query) to match.
  4. @optional specifies a Group that may or may not match.

An Expression can be

  1. a Variable like "?variable",
  2. a literal in JSON's native data types, i.e., number, strings, and booleans,
  3. a JSON-LD value object, or
  4. a Constraint of the form { <operator> : [<Expression>...] }. The key is the operator, and the value is the array of arguments. If the operator is unary, the Expression need not be wrapped in an array.

A variable Expression is either a plain variable (e.g. "?size"), or an object whose keys are variables, and whose values are expressions whose result will be assigned to the variable, e.g.

{ "?averageSize" : { "@avg" : "?size" } }