Skip to content

Commit

Permalink
docs: various fixes to the graphql tutorial (#2965)
Browse files Browse the repository at this point in the history
* doc/md: fix resolver diff and isolation example

* doc/md: fix updateTodo input field

* doc/md: add missing extension and fix paths

Without entgql.WithSchemaGenerator entc.go fails to run.

* doc/md: add file titles

Note that the where:TodoWhereInput parameter is pre-filled in the
generated ent.graphql file.

* doc/md: add context to conjunction/negation example

Only add for the first example to provide a lead to readers.
  • Loading branch information
kortschak committed Sep 27, 2022
1 parent bd80e06 commit e02622a
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 34 deletions.
53 changes: 33 additions & 20 deletions doc/md/tutorial-todo-gql-filter-input.md
Expand Up @@ -47,14 +47,15 @@ go run ./cmd/todo/

### Configure Ent

Go to your `ent/entc.go` file, and add the 3 highlighted lines (extension options):
Go to your `ent/entc.go` file, and add the 4 highlighted lines (extension options):

```go {3-5} title="ent/entc.go"
```go {3-6} title="ent/entc.go"
func main() {
ex, err := entgql.NewExtension(
entgql.WithSchemaGenerator(),
entgql.WithWhereInputs(true),
entgql.WithConfigPath("../gqlgen.yml"),
entgql.WithSchemaPath("../ent.graphql"),
entgql.WithConfigPath("gqlgen.yml"),
entgql.WithSchemaPath("ent.graphql"),
)
if err != nil {
log.Fatalf("creating entgql extension: %v", err)
Expand All @@ -76,14 +77,14 @@ configures a path to a new, or an existing GraphQL schema to write the generated
After changing the `entc.go` configuration, we're ready to execute the code generation as follows:

```console
go generate ./ent/...
go generate .
```

Observe that Ent has generated `<T>WhereInput` for each type in your schema in a file named `ent/gql_where_input.go`. Ent
also generates a GraphQL schema as well (`ent.graphql`), so you don't need to `autobind` them to `gqlgen` manually.
For example:

```go title="ent/where_input.go"
```go title="ent/gql_where_input.go"
// TodoWhereInput represents a where input for filtering Todo queries.
type TodoWhereInput struct {
Not *TodoWhereInput `json:"not,omitempty"`
Expand Down Expand Up @@ -157,7 +158,7 @@ schema:
After running the code generation, we're ready to complete the integration and expose the filtering capabilities in GraphQL:

1\. Edit the GraphQL schema to accept the new filter types:
```graphql {8}
```graphql {8} title="ent.graphql"
type Query {
todos(
after: Cursor,
Expand All @@ -171,7 +172,7 @@ type Query {
```

2\. Use the new filter types in GraphQL resolvers:
```go {5}
```go {5} title="ent.resolvers.go"
func (r *queryResolver) Todos(ctx context.Context, after *ent.Cursor, first *int, before *ent.Cursor, last *int, orderBy *ent.TodoOrder, where *ent.TodoWhereInput) (*ent.TodoConnection, error) {
return r.client.Todo.Query().
Paginate(ctx, after, first, before, last,
Expand All @@ -188,21 +189,33 @@ Go code.

#### Conjunction, disjunction and negation

The `Not`, `And` and `Or` operators can be added using the `not`, `and` and `or` fields. For example:
The `Not`, `And` and `Or` operators can be added to the `where` clause using the `not`, `and` and `or` fields. For example:

```graphql
{
or: [
{
status: COMPLETED,
},
{
not: {
hasParent: true,
status: IN_PROGRESS,
```graphql {3-15}
query {
todos(
where: {
or: [
{
status: COMPLETED
},
{
not: {
hasParent: true,
status: IN_PROGRESS
}
}
]
}
) {
edges {
node {
id
text
}
cursor
}
]
}
}
```

Expand Down
2 changes: 1 addition & 1 deletion doc/md/tutorial-todo-gql-mutation-input.md
Expand Up @@ -147,7 +147,7 @@ The only thing left is to test the `UpdateTodo` resolver. Let's use it to update

```graphql
mutation UpdateTodo {
updateTodo(id: 2, input: {parent: 1}) {
updateTodo(id: 2, input: {parentID: 1}) {
id
text
createdAt
Expand Down
22 changes: 9 additions & 13 deletions doc/md/tutorial-todo-gql-tx-mutation.md
Expand Up @@ -37,34 +37,30 @@ srv := handler.NewDefaultServer(todo.NewSchema(client))

2\. Then, in the GraphQL mutations, use the client from context as follows:
```diff title="todo.resolvers.go"
func (mutationResolver) CreateTodo(ctx context.Context, todo TodoInput) (*ent.Todo, error) {
}
+func (mutationResolver) CreateTodo(ctx context.Context, input ent.CreateTodoInput) (*ent.Todo, error) {
+ client := ent.FromContext(ctx)
+ return client.Todo.
- return r.client.Todo.
Create().
SetText(todo.Text).
SetStatus(todo.Status).
SetNillablePriority(todo.Priority). // Set the "priority" field if provided.
SetNillableParentID(todo.Parent). // Set the "parent_id" field if provided.
Save(ctx)
+ return client.Todo.Create().SetInput(input).Save(ctx)
-func (r *mutationResolver) CreateTodo(ctx context.Context, input ent.CreateTodoInput) (*ent.Todo, error) {
- return r.client.Todo.Create().SetInput(input).Save(ctx)
}
```

## Isolation Levels

If you'd like to tweak the transaction's isolation level, you can do so by implementing your own `TxOpener`. For example:

```go
```go title="cmd/todo/main.go"
srv.Use(entgql.Transactioner{
TxOpener: entgql.TxOpenerFunc(func(ctx context.Context) (context.Context, driver.Tx, error) {
tx, err := client.BeginTx(ctx, &sql.TxOptions{Isolation: sql.LevelRepeatableRead})
if err != nil {
return nil, nil, err
}
ctx = NewTxContext(ctx, tx)
ctx = NewContext(ctx, tx.Client())
ctx = ent.NewTxContext(ctx, tx)
ctx = ent.NewContext(ctx, tx.Client())
return ctx, tx, nil
})
}),
})
```

Expand Down

0 comments on commit e02622a

Please sign in to comment.