# GraphQL Generated Schema Ergonomics

**URL:** <https://discuss.dgraph.io/t/graphql-generated-schema-ergonomics/14101>\
**Category:** GraphQL\
**Tags:** discussion\
**Created:** [May 11, 2021, 3:30am UTC](https://discuss.dgraph.io/t/graphql-generated-schema-ergonomics/14101 "2021-05-11T03:30:28Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![dpeek](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/dpeek/32/3072_2.png) [@dpeek](https://discuss.dgraph.io/u/dpeek)\
**Post date:** [May 11, 2021, 3:30am UTC](https://discuss.dgraph.io/t/graphql-generated-schema-ergonomics/14101/1 "2021-05-11T03:30:28Z")

</div>

This topic describes possible improvements to the schema generated by the Dgraph GraphQL endpoint. The changes are focused on the ergonomics of type safe GraphQL clients (ie. TypeScript GraphQL Codegen) and minimising redundant null checking and field passing.

I’ll add to it over time, hopefully we can have some productive discussion on whether or not these changes make sense.

---

<div class="post-metadata">

**Author:** ![dpeek](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/dpeek/32/3072_2.png) [@dpeek](https://discuss.dgraph.io/u/dpeek)\
**Post date:** [May 11, 2021, 3:30am UTC](https://discuss.dgraph.io/t/graphql-generated-schema-ergonomics/14101/2 "2021-05-11T03:30:48Z")

</div>

Filter Queries should return `[Type]!` instead of `[Type]`

Currently, generated filter queries have a return type of `[Type]`, meaning the client can expect either `null` or an array of `Type` records. By returning `[Type]!` clients can expect an array, and avoid a `null` check.

Before:

```auto
graph.queryType().then(res => {
  if (res.queryType) {
    res.queryType.forEach(type => {...});
  }
})

```

After:

```auto
graph.queryType().then(res => {
  res.queryType.forEach(type => {...});
})

```

---

<div class="post-metadata">

**Author:** ![dpeek](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/dpeek/32/3072_2.png) [@dpeek](https://discuss.dgraph.io/u/dpeek)\
**Post date:** [May 11, 2021, 3:30am UTC](https://discuss.dgraph.io/t/graphql-generated-schema-ergonomics/14101/3 "2021-05-11T03:30:59Z")

</div>

Filter Queries should return `[Type!]` instead of `[Type]`

Currently, generated filter queries have a return type of `[Type]`, meaning the client can expect an array of either `Type` or `null` elements. By returning `[Type!]` clients can expect all elements in the array to be of `Type` and avoid filtering on `null` values.

The GraphQL endpoint may have to filter `null` values from the response but these values provide no information to the client at present.

Before:

```auto
graph.queryType().then(res => {
  res.queryType
    .filter((type: Type | null) => type !== null)
    .forEach((type: Type) => {...});
})

```

After:

```auto
graph.queryType().then(res => {
  res.queryType.forEach((type: Type) => {...});
})

```

---

<div class="post-metadata">

**Author:** ![dpeek](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/dpeek/32/3072_2.png) [@dpeek](https://discuss.dgraph.io/u/dpeek)\
**Post date:** [May 11, 2021, 3:31am UTC](https://discuss.dgraph.io/t/graphql-generated-schema-ergonomics/14101/4 "2021-05-11T03:31:09Z")

</div>

“To Many” fields on AddTypeInputs should be optional

Currently, a type with this schema:

```auto
type Book {
  authors: [Author!]!
}

```

Will generate an `AddBookInput` with this schema:

```auto
input AddBookInput {
  authors: [Author!]!
}

```

Meaning add mutations will need to provide an empty array of authors for new books. Since the presence of this array has no effect in dgraph terms (ie. we don’t create an “empty” edge) we should allow the input to omit this field.

```auto
input AddBookInput {
  authors: [Author!]
}

```

Note that `[Author!]!` does not mean “Book always has authors” but rather “Book always has an array of zero or more authors”. As dgraph will always return an array for “authors” when the type is queried `authors: [Author]` is not really possible.

---

<div class="post-metadata">

**Author:** ![chewxy](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/chewxy/32/4339_2.png) [@chewxy](https://discuss.dgraph.io/u/chewxy)\
**Post date:** [May 11, 2021, 4:03am UTC](https://discuss.dgraph.io/t/graphql-generated-schema-ergonomics/14101/5 "2021-05-11T04:03:28Z")

</div>

What do you do when you need to return null results then?

---

<div class="post-metadata">

**Author:** ![dpeek](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/dpeek/32/3072_2.png) [@dpeek](https://discuss.dgraph.io/u/dpeek)\
**Post date:** [May 11, 2021, 4:06am UTC](https://discuss.dgraph.io/t/graphql-generated-schema-ergonomics/14101/6 "2021-05-11T04:06:23Z")

</div>

I didn’t think that is possible with dgraph anyway? If an edge has a type of [uid] you will always get an empty array.

---

<div class="post-metadata">

**Author:** ![dpeek](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/dpeek/32/3072_2.png) [@dpeek](https://discuss.dgraph.io/u/dpeek)\
**Post date:** [May 13, 2021, 3:19am UTC](https://discuss.dgraph.io/t/graphql-generated-schema-ergonomics/14101/7 "2021-05-13T03:19:03Z")

</div>

Return type of `updateType` should be `UpdateTypePayload!` not `UpdateTypePayload`

Currently, the return type of the generated `updateType` mutation is an optional `UpdateTypePayload`. This means we must check for `null` before accessing its fields.

Unless the return type can sometimes be `null`, it should be `UpdateTypePayload!`

Edit: the same applies to addType and deleteType actually 🙂

---

<div class="post-metadata">

**Author:** ![dpeek](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/dpeek/32/3072_2.png) [@dpeek](https://discuss.dgraph.io/u/dpeek)\
**Post date:** [May 13, 2021, 3:21am UTC](https://discuss.dgraph.io/t/graphql-generated-schema-ergonomics/14101/8 "2021-05-13T03:21:02Z")

</div>

BTW, I’m happy to open PRs for all these, just looking for input from Dgraph team on whether they seem like worthwhile changes.

As most of them are around nullability of values, it’s possible that I’m not aware of some cases where things can actually be null. Although, I would argue that the GraphQL endpoint should avoid those cases if possible 🙂
