can we generate go-code based on schema to multiple files and if the file is already exist, then just update the files ?
may be like bellow :
schema.graphql
schema {
query: MyQuery
mutation: MyMutation
}
type MyQuery {
todo(id: Int!): Todo
lastTodo: Todo
todos: [Todo!]!
}
type MyMutation {
createTodo(todo: TodoInput!): Todo!
updateTodo(id: Int!, changes: Map!): Todo
}
type Todo {
id: Int!
text: String!
done: Boolean!
}
input TodoInput {
text: String!
done: Boolean
}
gqlgen.yml
schema: schema/schema.graphql
exec:
filename: generated/generated.go
package: generated
model:
filename: models/model.go
# multiple_files: true ## maybe we can add this config
resolver:
filename: resolvers/resolver.go
package: resolvers
# multiple_files: true ## maybe we can add this config
type: Resolver
struct_tag: json
generated files
models/
model.go
todo.go
todoInput.go
resolvers/
resolver.go
queryResolver.go
mutationResolver.go
todoResolver.go
it would be nice if we can work on specific file.
Thank you.
The base generated server will likely always go into a single output file, but I can see a use-case for splitting up resolver stubs. Our stub generation still has a few issues, but I've marked this as an enhancement that we might consider when we look at improving it.
@mathewbyrne thank for your consideration.
happy monday. ๐
I've got similar issue, my schema contain ~160 types and 100 queries/mutations, so my generated.go contain 35k lines. It will be great, if gqlgen will generate interfaces, complexity, queries, mutations and subs in separate files
+1
@vektah Regarding models, could we do something like this:
models:
Todo:
#model: path/to/existing/model.Todo <-- for linking to existing model
filename: internal/graphql/model_gen.go <-- for generating a new model
package: todo
Where instead of binding models to existing models, you could instead specify a filename and package for gqlgen to generate the stubs.
This would help when splitting up a project based on domain like so:
todo/
service.go
model_gen.go
logger.go
todo.graphql
user/
service.go
model_gen.go
logger.go
user.graphql
graphql/
generated.go
schema.graphql
resolver/
resolver.go
query.go
mutation.go
todo.go <-- calls to todo package
user.go <-- calls to user package
rest/
handler/
todo.go <-- calls to todo package
user.go <-- calls to user package
This would massively help decouple a project from graphql if you wanted to say, add a cli interface or a restful interface...
+1 to this
I agree this would be extremely helpful for large and/or complex schemas. Similar to what @andrewmunro has above, another way to calculate the different packages could be based on the listed schemas in gqlgen.yml. For example, a schema such as:
schema:
- schema/todo.graphql
- schema/user.graphql
would end up with a directory structure that looks like what is above:
todo/
model_gen.go
todo.graphql
user/
model_gen.go
user.graphql
graphql/
generated.go
resolvers/
query.go
mutation.go
todo.go <-- calls to todo package
user.go <-- calls to user package
+1
For now i'm trying to find a workaround for this, i also have golang packages based on graphql types.
todo/
schema.graphql
user/
schema.graphql
query/
schema.graphql
I also want to get resolver for each type in its respective folder
todo/
schema.graphql
resolver.go
user/
schema.graphql
resolver.go
query/
schema.graphql
resolver.go
I am a bit stuck to find a way to avoid cyclic import with interfaces, because of this :
type userResolver struct{ *Resolver }
So the userResolver is dependent of the Resolver (which is defined by the ResolverRoot interface) and Resolver should return userResolver instance with the method User().
Is there someone who has already solve this problem ?
Thank you.
Yes, definitely ! I'm interested too cause my resolvers file is so long (2300 lines) that VSCode autocomplete is not working anymore.
+1
+1
+1
+1
+1
@jbltx i think if you're using multi folder, it's meaning multi endpoint,beacuse the folders need independent,golang can't allow cycle import, another way is
user_resolver.go
todo_resolver.go
+1 for this please
@imiskolee has a point that multiple resolvers can easily lead to circular dependencies.
One potential solution to bulky schema/resolvers could be Schema Federation, which is being addressed in #740
any news? this enhancement definitely would be so nice
+1 hope this issue and suggestions in comment could be implemented. I have trouble decouple QueryResolver and MutationResolver, they are currently two huge files and has tons of functions in each of them.
+1 hope this issue and suggestions in comment could be implemented. I have trouble decouple QueryResolver and MutationResolver, they are currently two huge files and has tons of functions in each of them.
I have setup the yml in such a way that the resolver is generated inside a "resolver" folder.
resolver:
filename: resolvers/resolver.go
type: Resolver
Then once the resolver file is generated, I move the code to separate file, for instance resolver code for users go into "resolver/user.go".After doing the same to the rest of the code in resolver.go, I remove the file. Since the code is under the same package, the project would compile without any issues.
When I add a new schema, I regenerate the resolver.go file, but this time, I move only the code relevant to the new schema and discard the rest.
Hope this approach helps you until this issue is resolved.
+1 hope this issue and suggestions in comment could be implemented. I have trouble decouple QueryResolver and MutationResolver, they are currently two huge files and has tons of functions in each of them.
I have setup the yml in such a way that the resolver is generated inside a "resolver" folder.
resolver:
filename: resolvers/resolver.go
type: ResolverThen once the resolver file is generated, I move the code to separate file, for instance resolver code for users go into "resolver/user.go".After doing the same to the rest of the code in resolver.go, I remove the file. Since the code is under the same package, the project would compile without any issues.
When I add a new schema, I regenerate the resolver.go file, but this time, I move only the code relevant to the new schema and discard the rest.Hope this approach helps you until this issue is resolved.
Thanks for your suggestion! I almost have the same implementation with you, but I grouped all mutations and queries into resolvers/query.go and resolvers/mutation.go since query.go and mutation.go technically are two resolvers, and yes I also have resolver/user.go. This structure undeniably results two large file. I'll refactor a little bit to see if that's getting better!
+1 hope this issue and suggestions in comment could be implemented. I have trouble decouple QueryResolver and MutationResolver, they are currently two huge files and has tons of functions in each of them.
I have setup the yml in such a way that the resolver is generated inside a "resolver" folder.
resolver:
filename: resolvers/resolver.go
type: ResolverThen once the resolver file is generated, I move the code to separate file, for instance resolver code for users go into "resolver/user.go".After doing the same to the rest of the code in resolver.go, I remove the file. Since the code is under the same package, the project would compile without any issues.
When I add a new schema, I regenerate the resolver.go file, but this time, I move only the code relevant to the new schema and discard the rest.Hope this approach helps you until this issue is resolved.
this seems like a good approach, perhaps should be in official documentation as a suggestion even. it helps streamline the process but still being organised without having to change the library implementation and other parts of the docs
When you split models in different files, what happens if you delete a model? You'll have to care about that case manually and delete the generated model. Just to keep in mind.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Any update on this feature? As code grows larger, this is a must, it's stopping our company with massive adoption.
Is this feature coming up any time soon? It is a mess to have everything in one file only
For anyone still interested in this, I've created a proposal #1265 describing a specific solution to this problem. I'd appreciate if folks can take a look and upvote/comment there to get a sense of interest and iron out any potential issues that may have been an oversight on my part.
cc @RobertoOrtis @pbrazdil since you two expressed continued interest
Proposal: Divided by file type and by business module. These two are the most common file directory organization structure.
.
โโโ go.mod
โโโ go.sum
โโโ gqlgen.yml
โโโ graph
โย ย โโโ generated
โย ย โโโ model
โย ย โย ย โโโ todo.go
โย ย โย ย โโโ user.go
โย ย โโโ resolver
โย ย โย ย โโโ todo.go
โย ย โย ย โโโ user.go
โย ย โโโ schema
โย ย โโโ todo.graphql
โย ย โโโ user.graphql
โโโ server.go
.
โโโ go.mod
โโโ go.sum
โโโ gqlgen.yml
โโโ graph
โย ย โโโ generated
โย ย โโโ modules
โย ย โโโ todo
โย ย โย ย โโโ model.go
โย ย โย ย โโโ resolver.go
โย ย โย ย โโโ typeDefs.graphql
โย ย โโโ user
โย ย โโโ model.go
โย ย โโโ resolver.go
โย ย โโโ typeDefs.graphql
โโโ server.go
Most helpful comment
@vektah Regarding models, could we do something like this:
Where instead of binding models to existing models, you could instead specify a filename and package for gqlgen to generate the stubs.
This would help when splitting up a project based on domain like so:
This would massively help decouple a project from graphql if you wanted to say, add a cli interface or a restful interface...