Force Generating Models Doesn't Work with Go Field Force Resolver Directive
- 主要语言
- Go
- 星标
- 10.8k
- 派生
- 1.3k
- 平均合并
- 2 天 36 分钟
- 30 天内合并 PR
- 26
描述
### What happened?
I am building a GraphQL schema that makes a lot of use of interfaces and relations, where my internal models don't quite match up with the GQL representation so I need GQLGen to generate these models. For that I used the `@goModel(forceGenerate: true)` directive on my model which works fine.
However, the schema also has a lot of relations that need to be returned in field resolvers which is where I would want to use the `@goField(forceResolver: true)` directive.
If I combine the two it seems no model is generated, and GQLGen errors out with:
```go
merging type systems failed: unable to bind to interface: github.com/Dan6erbond/gqlgen-force-directives-playground/models.PrivateTodo does not satisfy the interface github.com/Dan6erbond/gqlgen-force-directives-playground/graph/model.Todo
exit status 1
graph\resolver.go:1: running "go": exit status 1
```
### What did you expect?
I expected GQLGen to generate the models and the resolvers.
Without the `@goField` directive it works fine, I get these models:
```go
type PrivateTodo struct {
ID string `json:"id"`
Text string `json:"text"`
Done bool `json:"done"`
User *User `json:"user"`
}
func (PrivateTodo) IsTodo() {}
type ProjectTodo struct {
ID string `json:"id"`
Text string `json:"text"`
Done bool `json:"done"`
User *User `json:"user"`
Project *Project `json:"project"`
}
func (ProjectTodo) IsTodo() {}
```
The current workaround I have is configuring the models and resolvers via the `gqlgen.yml` file, but with how large our API is, it's getting bloated and I'd prefer to make use of directives.
### Minimal graphql.schema and models to reproduce
Schema:
```gql
directive @goModel(
model: String
models: [String!]
forceGenerate: Boolean
) on OBJECT | INPUT_OBJECT | SCALAR | ENUM | INTERFACE | UNION
directive @goField(
forceResolver: Boolean
name: String
omittable: Boolean
) on INPUT_FIELD_DEFINITION | FIELD_DEFINITION
directive @goTag(
key: String!
value: String
) on INPUT_FIELD_DEFINITION | FIELD_DEFINITION
directive @goExtraField(
name: String
type: String!
overrideTags: String
description: String
) on OBJECT | INPUT_OBJECT
interface Todo
@goModel(
model: "github.com/Dan6erbond/gqlgen-force-directives-playground/graph/model.Todo"
) {
id: ID!
text: String!
done: Boolean!
user: User!
}
type PrivateTodo implements Todo @goModel(forceGenerate: true) {
id: ID!
text: String!
done: Boolean!
user: User! @goField(forceResolver: true)
}
type ProjectTodo implements Todo @goModel(forceGenerate: true) {
id: ID!
text: String!
done: Boolean!
user: User! @goField(forceResolver: true)
project: Project! @goField(forceResolver: true)
}
type User {
id: ID!
name: String!
}
type Project {
id: ID!
name: String!
}
type Query {
todos: [Todo!]!
}
input NewTodo {
text: String!
userId: String!
}
type Mutation {
createTodo(input: NewTodo!): Todo!
}
```
Models:
```go
package models
type Todo struct {
Type string
PrivateTodo
ProjectTodo
}
type PrivateTodo struct {
Text string
Done bool
UserID uint
}
type ProjectTodo struct {
Text string
Done bool
UserID uint
ProjectID uint
}
```
> **Important**: Enable the autobinding on the models folder so that GQLGen skips generating the `PrivateTodo` and `ProjectTodo` models by default.
> ```yml
> autobind:
> - "github.com/Dan6erbond/gqlgen-force-directives-playground/graph/model"
> - "github.com/Dan6erbond/gqlgen-force-directives-playground/models"
> ```
I have a sandbox repo [here](https://github.com/Dan6erbond/gqlgen-force-directives-playground) that showcases the issue on `main` and shows the workaround on [`feature/without-force-resolver`](https://github.com/Dan6erbond/gqlgen-force-directives-playground/tree/feature/without-force-resolver).
### versions
- `go run github.com/99designs/gqlgen version`: v0.17.49
- `go version`: go version go1.22.3 windows/amd64
贡献指南
评估
这个 Issue 还没有评估数据。