doc/tutorial: update entgql + gqlgen integration (#2915)

This commit is contained in:
Ariel Mashraki
2022-09-08 17:56:11 +03:00
committed by GitHub
parent d0943109b5
commit 82ee525676
6 changed files with 625 additions and 834 deletions

View File

@@ -39,7 +39,7 @@ Cursor Connections interface, read the following paragraphs that were taken from
The code for this tutorial is available under [github.com/a8m/ent-graphql-example](https://github.com/a8m/ent-graphql-example),
and tagged (using Git) in each step. If you want to skip the basic setup and start with the initial version of the GraphQL
server, you can clone the repository and checkout `v0.1.0` as follows:
server, you can clone the repository as follows:
```console
git clone git@github.com:a8m/ent-graphql-example.git
@@ -50,9 +50,8 @@ go run ./cmd/todo/
## Add Annotations To Schema
Ordering can be defined on any comparable field of ent by annotating it with `entgql.Annotation`.
Note that the given `OrderField` name must match its enum value in GraphQL schema (see
[next section](#define-ordering-types-in-graphql-schema) below).
Ordering can be defined on any comparable field of Ent by annotating it with `entgql.Annotation`.
Note that the given `OrderField` name must be uppercase and match its enum value in the GraphQL schema.
```go title="ent/schema/todo.go"
func (Todo) Fields() []ent.Field {
@@ -86,82 +85,25 @@ func (Todo) Fields() []ent.Field {
}
```
## Define Types In GraphQL Schema
Next, we need to add the ordering types along with the [Relay Connection Types](https://relay.dev/graphql/connections.htm#sec-Connection-Types)
to the GraphQL schema:
```graphql title="todo.graphql"
# Define a Relay Cursor type:
# https://relay.dev/graphql/connections.htm#sec-Cursor
scalar Cursor
type PageInfo {
hasNextPage: Boolean!
hasPreviousPage: Boolean!
startCursor: Cursor
endCursor: Cursor
}
type TodoConnection {
totalCount: Int!
pageInfo: PageInfo!
edges: [TodoEdge]
}
type TodoEdge {
node: Todo
cursor: Cursor!
}
# These enums are matched the entgql annotations in the ent/schema.
enum TodoOrderField {
CREATED_AT
PRIORITY
STATUS
TEXT
}
enum OrderDirection {
ASC
DESC
}
input TodoOrder {
direction: OrderDirection!
field: TodoOrderField
}
```
Note that the naming must take the form of `<T>OrderField` / `<T>Order` for `autobind`ing to the generated ent types.
Alternatively [@goModel](https://gqlgen.com/config/#inline-config-with-directives) directive can be used for manual type binding.
## Add Pagination Support For Query
```graphql
type Query {
todos(
after: Cursor
first: Int
before: Cursor
last: Int
orderBy: TodoOrder
): TodoConnection!
1\. The next step for enabling pagination is to tell Ent that the `Todo` type is a Relay Connection.
```go title="ent/schema/todo.go"
func (Todo) Annotations() []schema.Annotation {
return []schema.Annotation{
//highlight-next-line
entgql.RelayConnection(),
entgql.QueryField(),
entgql.Mutations(entgql.MutationCreate()),
}
}
```
That's all for the GraphQL schema changes, let's run `gqlgen` code generation.
## Update The GraphQL Resolver
2\. Then, run `go generate .` and you'll notice that `ent.resolvers.go` was changed. Head over to the `Todos` resolver
and update it to pass pagination arguments to `.Paginate()`:
After changing our Ent and GraphQL schemas, we're ready to run the codegen and use the `Paginate` API:
```console
go generate ./...
```
Head over to the `Todos` resolver and update it to pass `orderBy` argument to `.Paginate()` call:
```go title="todo.resolvers.go"
```go title="ent.resolvers.go" {2-5}
func (r *queryResolver) Todos(ctx context.Context, after *ent.Cursor, first *int, before *ent.Cursor, last *int, orderBy *ent.TodoOrder) (*ent.TodoConnection, error) {
return r.client.Todo.Query().
Paginate(ctx, after, first, before, last,
@@ -210,7 +152,7 @@ query {
# Output: { "data": { "todos": { "edges": [ { "node": { "id": "16", "text": "Create GraphQL Example" }, "cursor": "gqFpEKF2tkNyZWF0ZSBHcmFwaFFMIEV4YW1wbGU" }, { "node": { "id": "15", "text": "Create GraphQL Example" }, "cursor": "gqFpD6F2tkNyZWF0ZSBHcmFwaFFMIEV4YW1wbGU" }, { "node": { "id": "14", "text": "Create GraphQL Example" }, "cursor": "gqFpDqF2tkNyZWF0ZSBHcmFwaFFMIEV4YW1wbGU" } ] } } }
```
We can also use the cursor we got in the query above to get all items after that cursor:
We can also use the cursor we got in the query above to get all items that come after it.
```graphql
query {
@@ -230,5 +172,5 @@ query {
---
Great! With a few simple changes, our application now supports pagination! Please continue to the next section where we explain how to implement GraphQL field collections and learn how Ent solves
the *"N+1 problem"* in GraphQL resolvers.
Great! With a few simple changes, our application now supports pagination. Please continue to the next section where we
explain how to implement GraphQL field collections and learn how Ent solves the *"N+1 problem"* in GraphQL resolvers.