Options
All
  • Public
  • Public/Protected
  • All
Menu

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.

Pattern

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.

Subject

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> }.

Group

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.

Expression

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.

Variable Expression

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" } }

Index

Type aliases

Atom

Atom: number | string | boolean | Variable | ValueObject

A basic atomic value used as a concrete value or in a filter.

Container

Container: List | Set

Used to express an ordered or unordered container of data.

see

https://json-ld.org/spec/latest/json-ld/#sets-and-lists

Expression

Expression: Atom | Constraint

A stand-in for a Value used as a basis for filtering. 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>...] }.

InlineFilter

InlineFilter: { @id?: Variable } & Constraint

An in-line filter, 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> }.

Reference

Reference: { @id: Iri }

A node object used to reference a node having only the @id key.

see

https://json-ld.org/spec/latest/json-ld/#dfn-node-references

Type declaration

  • @id: Iri

Result

SubjectPropertyObject

SubjectPropertyObject: Value | Container | InlineFilter | SubjectPropertyObject[]

The allowable types for a Subject property value, named awkwardly to avoid overloading Object. Represents the "object" of a property, in the sense of the object of discourse, whether it be a concrete value or a filter.

TermDef

TermDef: Iri | ExpandedTermDef

A term definition is an entry in a context, where the key defines a term which may be used within a JSON object as a property, type, or elsewhere that a string is interpreted as a vocabulary item. Its value is either a string (simple term definition), expanding to an absolute IRI, or an expanded term definition.

see

https://json-ld.org/spec/latest/json-ld/#dfn-term-definitions

Value

A value that can be assigned as the target of a graph edge.

Variable

Variable: string

A query variable, prefixed with "?"

see

https://www.w3.org/TR/sparql11-query/#QSynVariables

Functions

isAtom

isConstraint

  • isConstraint(value: object): value is Constraint
  • Parameters

    • value: object

    Returns value is Constraint

isConstruct

  • isConstruct(p: Pattern): p is Construct
  • Parameters

    Returns p is Construct

isDescribe

  • isDescribe(p: Pattern): p is Describe
  • Parameters

    Returns p is Describe

isDistinct

  • isDistinct(p: Pattern): p is Distinct
  • Parameters

    Returns p is Distinct

isExpression

  • isExpression(value: any): value is Expression
  • Parameters

    • value: any

    Returns value is Expression

isGroup

  • Parameters

    Returns p is Group

isList

isPropertyObject

  • isPropertyObject(property: string, object: Subject["any"]): object is SubjectPropertyObject
  • Determines whether the given property object from a well-formed Subject is a graph edge; i.e. not a @context or the Subject @id.

    Parameters

    • property: string

      the Subject property in question

    • object: Subject["any"]

      the object (value) of the property

    Returns object is SubjectPropertyObject

isQuery

  • Parameters

    Returns p is Query

isRead

  • Parameters

    Returns p is Read

isReference

isSelect

  • isSelect(p: Pattern): p is Select
  • Parameters

    Returns p is Select

isSet

isSubject

  • isSubject(p: Pattern): p is Subject
  • Parameters

    Returns p is Subject

isUpdate

  • isUpdate(p: Pattern): p is Update
  • Parameters

    Returns p is Update

isValueObject

isVariable

  • isVariable(value: any): value is Variable
  • Parameters

    • value: any

    Returns value is Variable

isVariableExpression

  • isVariableExpression(value: any): value is VariableExpression
  • Parameters

    • value: any

    Returns value is VariableExpression

isWritable

  • isWritable(p: Pattern, quick?: undefined | "quick"): p is Subject | Group | Update
  • Determines if a Pattern can be used as a top-level object to perform a write against a data set. A writeable Pattern can be:

    • A Subject with no variables in key or value positions, recursively
    • A Group with only a @graph key, containing writeable Subjects
    • An Update

    This check does not guarantee that any updates will actually be made. It also leaves a class of Patterns that are neither Reads nor Writeable. Such patterns should not be accepted by a data store as a transaction.

    An implementation may wish to leave the scan for variables until query processing, for efficiency; if so, pass the 'quick' parameter.

    Parameters

    • p: Pattern
    • Optional quick: undefined | "quick"

    Returns p is Subject | Group | Update

Object literals

Const clauses

clauses: object

@construct

@construct: object

sparql

sparql: string = "construct"

@describe

@describe: object

sparql

sparql: string = "describe"

@distinct

@distinct: object

sparql

sparql: string = "distinct"

@groupBy

@groupBy: object

sparql

sparql: string = "group by"

@having

@having: object

sparql

sparql: string = "having"

@limit

@limit: object

sparql

sparql: string = "limit"

@offset

@offset: object

sparql

sparql: string = "offset"

@orderBy

@orderBy: object

sparql

sparql: string = "order by"

@select

@select: object

sparql

sparql: string = "select"

@values

@values: object

sparql

sparql: string = "values"

@where

@where: object

sparql

sparql: string = "where"

Const groupPatterns

groupPatterns: object

@bind

@bind: object

sparql

sparql: string = "bind"

@filter

@filter: object

sparql

sparql: string = "filter"

@graph

@graph: object

sparql

sparql: null = null

@optional

@optional: object

sparql

sparql: string = "optional"

@union

@union: object

sparql

sparql: string = "union"

@values

@values: object

sparql

sparql: string = "values"

Const operators

operators: object

@and

@and: object

associative

associative: boolean = true

sparql

sparql: string = "&&"

@asc

@asc: object

sparql

sparql: string = "ascending"

@avg

@avg: object

aggregation

aggregation: boolean = true

sparql

sparql: string = "avg"

@bound

@bound: object

sparql

sparql: string = "bound"

@count

@count: object

aggregation

aggregation: boolean = true

sparql

sparql: string = "count"

@desc

@desc: object

sparql

sparql: string = "descending"

@divide

@divide: object

sparql

sparql: string = "/"

@eq

@eq: object

sparql

sparql: string = "="

@groupConcat

@groupConcat: object

aggregation

aggregation: boolean = true

sparql

sparql: string = "group_concat"

@gt

@gt: object

sparql

sparql: string = ">"

@gte

@gte: object

sparql

sparql: string = ">="

@in

@in: object

sparql

sparql: string = "in"

@lang

@lang: object

sparql

sparql: string = "lang"

@langmatches

@langmatches: object

sparql

sparql: string = "langmatches"

@lt

@lt: object

sparql

sparql: string = "<"

@lte

@lte: object

sparql

sparql: string = "<="

@max

@max: object

aggregation

aggregation: boolean = true

sparql

sparql: string = "max"

@min

@min: object

aggregation

aggregation: boolean = true

sparql

sparql: string = "min"

@minus

@minus: object

sparql

sparql: string = "-"

@neq

@neq: object

sparql

sparql: string = "!="

@not

@not: object

sparql

sparql: string = "!"

@notin

@notin: object

sparql

sparql: string = "notin"

@or

@or: object

associative

associative: boolean = true

sparql

sparql: string = "||"

@plus

@plus: object

sparql

sparql: string = "+"

@regex

@regex: object

sparql

sparql: string = "regex"

@sample

@sample: object

aggregation

aggregation: boolean = true

sparql

sparql: string = "sample"

@str

@str: object

sparql

sparql: string = "str"

@sum

@sum: object

aggregation

aggregation: boolean = true

sparql

sparql: string = "sum"

@times

@times: object

sparql

sparql: string = "*"

Legend

  • Property

Generated using TypeDoc. Delivered by Vercel. json-rql - v0.6.0 Source code licensed MIT. Privacy policy