GraphQL
HarperDB supports GraphQL in a variety of ways. It can be used for defining schemas, and for querying Resources.
Get started by setting graphql: true
in config.yaml
.
This automatically enables a /graphql
endpoint that can be used for GraphQL queries.
HarperDB's GraphQL component is inspired by the GraphQL Over HTTP specification; however, it does not fully implement neither that specification nor the GraphQL specification.
Queries can either be GET
or POST
requests, and both follow essentially the same request format. GET
requests must use search parameters, and POST
requests use the request body.
For example, to request the GraphQL Query:
The GET
request would look like:
And the POST
request would look like:
Tip: For the best user experience, include the
Accept: application/graphql-response+json
header in your request. This provides better status codes for errors.
The HarperDB GraphQL querying system is strictly limited to exported HarperDB Resources. For many users, this will typically be a table that uses the @exported
directive in its schema. Queries can only specify HarperDB Resources and their attributes in the selection set. Queries can filter using arguments on the top-level Resource field. HarperDB provides a short form pattern for simple queries, and a long form pattern based off of the Resource Query API for more complex queries.
Unlike REST queries, GraphQL queries can specify multiple resources simultaneously:
This will return all dogs and owners in the database. And is equivalent to executing two REST queries:
Request Parameters
There are three request parameters for GraphQL queries: query
, operationName
, and variables
query
- Required - The string representation of the GraphQL document.Limited to Executable Definitions only.
If an shorthand, unnamed, or singular named query is provided, they will be executed by default. Otherwise, if there are multiple queries, the
operationName
parameter must be used.
operationName
- Optional - The name of the query operation to execute if multiple queries are provided in thequery
parametervariables
- Optional - A map of variable values to be used for the specified query
Type Checking
The HarperDB GraphQL Querying system takes many liberties from the GraphQL specification. This extends to how it handle type checking. In general, the querying system does not type check. HarperDB uses the graphql
parser directly, and then performs a transformation on the resulting AST. We do not control any type checking/casting behavior of the parser, and since the execution step diverges from the spec greatly, the type checking behavior is only loosely defined.
In variable definitions, the querying system will ensure non-null values exist (and error appropriately), but it will not do any type checking of the value itself.
For example, the variable $name: String!
states that name
should be a non-null, string value.
If the request does not contain the
name
variable, an error will be returnedIf the request provides
null
for thename
variable, an error will be returnedIf the request provides any non-string value for the
name
variable, i.e.1
,true
,{ foo: "bar" }
, the behavior is undefined and an error may or may not be returned.If the variable definition is changed to include a default value,
$name: String! = "John"
, then when omitted,"John"
will be used.If
null
is provided as the variable value, an error will still be returned.If the default value does not match the type specified (i.e.
$name: String! = 0
), this is also considered undefined behavior. It may or may not fail in a variety of ways.
Fragments will generally extend non-specified types, and the querying system will do no validity checking on them. For example,
fragment Fields on Any { ... }
is just as valid asfragment Fields on MadeUpTypeName { ... }
. See the Fragments sections for more details.
The only notable place the querying system will do some level of type analysis is the transformation of arguments into a query.
Objects will be transformed into properly nested attributes
Strings and Boolean values are passed through as their AST values
Float and Int values will be parsed using the JavaScript
parseFloat
andparseInt
methods respectively.List and Enums are not supported.
Fragments
The querying system loosely supports fragments. Both fragment definitions and inline fragments are supported, and are entirely a composition utility. Since this system does very little type checking, the on Type
part of fragments is entirely pointless. Any value can be used for Type
and it will have the same effect.
For example, in the query
The Dog
type in the fragment has no correlation to the Dog
resource in the query (that correlates to the HarperDB Dog
resource).
You can literally specify anything in the fragment and it will behave the same way:
As an actual example, fragments should be used for composition:
Short Form Querying
Any attribute can be used as an argument for a query. In this short form, multiple arguments is treated as multiple equivalency conditions with the default and
operation.
For example, the following query requires an id
variable to be provided, and the system will search for a Dog
record matching that id.
And as a properly formed request:
The REST equivalent would be:
Short form queries can handle nested attributes as well.
For example, return all dogs who have an owner with the name "John"
Would be equivalent to
And finally, we can put all of these together to create semi-complex, equality based queries!
The following query has two variables and will return all dogs who have the specified name as well as the specified owner name.
Long Form Querying
Coming soon!
Mutations
Coming soon!
Subscriptions
Coming soon!
Directives
Coming soon!
Last updated