# Source: https://docs.hypermode.com/dgraph/graphql/schema/graphql-dql.md

# GraphQL and DQL schemas

<Info>
  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](https://github.com/hypermodeinc/docs/issues).
</Info>

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](/dgraph/graphql/quickstart), we used a schema to
generate a GraphQL API:

```graphql
type Product {
  productID: ID!
  name: String @search(by: [term])
  reviews: [Review] @hasInverse(field: about)
}

type Customer {
  username: String! @id @search(by: [hash, regexp])
  reviews: [Review] @hasInverse(field: by)
}

type Review {
  id: ID!
  about: Product!
  by: Customer!
  comment: String @search(by: [fulltext])
  rating: Int @search
}
```

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](./types).

### 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

```graphql
type Person {
  id: ID
  name: String!
  friends: [Person]
}
```

leads to the declaration of 3 predicates in the DQL Schema:

* `Person.id default`
* `Person.name string`
* `Person.friends [uid]`

and one DQL type

```dql
type Person {
   Person.name
   Person.friends
}
```

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](/dgraph/graphql/schema/directives/dgraph).

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

```graphql
type Person {
    name: String @search(by: [hash])
    ...
```

Is simply translated into a predicate index specification in the Dgraph schema:

```dql
Person.name: string @index(hash) .
```

#### 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

```graphql
query {
  queryPerson {
    id
    name
    friends {
      id
      name
    }
  }
}
```

can be executed in DQL

```graphql
{
  queryPerson(func: type(Person)) {
    id: uid
    name: Person.name
    friends: Person.friends {
      id: uid
      name: Person.name
    }
  }
}
```

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 :

```graphql
interface Location {
  id: ID!
  geoloc: Point
}

type Property implements Location {
  price: Float
}
```

The predicates and types generated for a `Property` are:

```graphql
Location.geoloc: geo .
Location.name: string .
Property.price: float .
type Property {
  Location.name
  Location.geoloc
  Property.price
}
```

### 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](/dgraph/admin/import) 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](/dgraph/enterprise/access-control-lists)) section.
* fix things using DQL: this is especially useful when doing GraphQL Schema
  updates which require some [data migrations](./migration).