99designs / 99designs/gqlgen

How to enforce some custom logic after an object of a certain type is resolved?

Ouverte
#3,306 0 commentaires 0 réactions 0 personnes assignées Voir sur GitHub
Langage dominant
Go
Étoiles
10.8k
Forks
1.3k
Merge moyen
2 j 36 min
PR mergées (30 j)
26

Description

### What happened?
I tried to add a directive on an SomeType, which implements SomeInterface, the generated directive code behaves like this:
1. If a resolver returns []*SomeType, the directive also receives a []*SomeType variable as argument
```go
func (ec *executionContext) _Query_todos(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
//...
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
directive0 := func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Query().Todos(rctx)
}
directive1 := func(ctx context.Context) (interface{}, error) {
// ...
// directive0 will return a slice of Todo, we cannot modify child context of each element
return ec.directives.Scope(ctx, nil, directive0, scope)
}
// ...
})
// ...
res := resTmp.([]*model.Todo)
fc.Result = res
return ec.marshalNTodo2ᚕᚖgqlgenᚑtodosᚋgraphᚋmodelᚐTodoᚄ(ctx, field.Selections, res)
}
```
3. If a resolver's signature returns SomeInterface, and it returns SomeType , the directive is not called
```go
func (ec *executionContext) _Query_node(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
// ...
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Query().Node(rctx, fc.Args["id"].(string))
// directive "scope" on "Todo" is not called at all
})
// ...
res := resTmp.(model.Node)
fc.Result = res
return ec.marshalONode2gqlgenᚑtodosᚋgraphᚋmodelᚐNode(ctx, field.Selections, res)
}
```
### What did you expect?
The generated directive will be called if the concrete type of resolver result is SomeType, with exactly one element
### Minimal graphql.schema and models to reproduce
```graphql
# GraphQL schema example
#
# https://gqlgen.com/getting-started/

directive @scope(scope: String) on OBJECT | FIELD_DEFINITION

interface Node {
id: ID!
}

type Todo implements Node @scope(scope: "todo:read") {
id: ID!
text: String!
done: Boolean!
user: User!
secret: String @scope(scope: "todo.secret:read")
}

type User implements Node {
id: ID! @scope(scope: "user:read")
name: String! @scope(scope: "user:read")
}

type Query {
todos: [Todo!]!
todo(
id: ID!
): Todo
node(
id: ID!
): Node
nodes(ids: [ID!]!): [Node]!
}

input NewTodo {
text: String!
userId: String!
}

type Mutation {
createTodo(input: NewTodo!): Todo!
}

```
### versions
- `go run github.com/99designs/gqlgen version`: v0.17.49
- `go version`: go version go1.23.1 darwin/arm64

Guide de contribution

Ouvrir le guide de contribution

Évaluation

Cette issue n'a pas encore été évaluée.

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.