How to enforce some custom logic after an object of a certain type is resolved?
- 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.