GraphQL and DQL schemas
We’re overhauling Dgraph’s docs to make them clearer and more approachable. If you notice any issues during this transition or have suggestions, please let us know.
The first step in mastering DQL in the context of GraphQL API is probably to understand the fundamental difference between GraphQL schema and DQL schema.
In GraphQL, the schema is a central notion
GraphQL is a strongly typed language. Contrary to REST which is organized in terms of endpoints, GraphQL APIs are organized in terms of types and fields. The type system is used to define the schema, which is a contract between client and server. GraphQL uses types to ensure Apps only ask for what’s possible and provide clear and helpful errors.
In the GraphQL Quick start, we used a schema to generate a GraphQL API:
The API and the engine logic are generated from the schema defining the types of objects we’re dealing with, the fields, and the relationships in the form of fields referencing other types.
In DQL, the schema described the predicates
Dgraph maintains a list of all predicates names with their type and indexes in the Dgraph types schema.
Schema mapping
When deploying a GraphQL Schema, Dgraph generates DQL predicates and types for
the graph backend. In order to distinguish a field name
from a type Person
from the field name
of different type (they may have different indexes),
Dgraph is using a dotted notation for the DQL schema.
For example, deploying the following GraphQL Schema
leads to the declaration of 3 predicates in the DQL Schema:
Person.id default
Person.name string
Person.friends [uid]
and one DQL type
Once again, the DQL type is just a declaration of the list of predicates that
one can expect to be present in a node of having dgraph.type
equal Person
.
The default mapping can be customized by using the @dgraph directive.
GraphQL ID type and Dgraph uid
Person.id isn’t part of the Person DQL type: internally Dgraph is using uid
predicate as unique identifier for every node in the graph. Dgraph returns the
value of uid
when a GraphQL field of type ID is requested.
Search directive and predicate indexes
@search
directive tells Dgraph what search to build into your GraphQL API.
Is simply translated into a predicate index specification in the Dgraph schema:
Constraints
DQL doesn’t have ‘non nullable’ constraint !
nor ‘unique’ constraint.
Constraints on the graph are handled by correctly using upsert
operation in
DQL.
DQL queries
You can use DQL to query the data generated by the GraphQL API operations. For example the GraphQL Query
can be executed in DQL
Note that in this query, we use aliases
such as name: Person.name
to name
the predicates in the JSON response,as they’re declared in the GraphQL schema.
GraphQL Interface
DQL doesn’t have the concept of interfaces.
Considering the following GraphQL schema :
The predicates and types generated for a Property
are:
Consequences
The fact that the GraphQL API backend is a graph in Dgraph, implies that you can use Dgraph DQL on the data that’s also served by the GraphQL API operations.
In particular, you can
- use Dgraph DQL mutations but also Dgraph’s import tools to populate the graph after you have deployed a GraphQL Schema
- use DQL to query the graph in the context of authorization rules and custom resolvers.
- add knowledge to your graph such as metadata, score, and annotations, but also relationships or relationships attributes (facets) that could be the result of similarity computation, threat detection a.s.o. The added data could be hidden from your GraphQL API clients but be available to logic written with DQL clients.
- break things using DQL: DQL is powerful and is bypassing constraints expressed in the GraphQL schema. You can for example delete a node predicate that’s mandatory in the GraphQL API! Hopefully there are ways to secure who can read/write/delete predicates. ( see the ACL) section.
- fix things using DQL: this is especially useful when doing GraphQL Schema updates which require some data migrations.
Was this page helpful?