This is just a suggestion that I thought might be helpful, feel free to close if this doesn't sound useful to you. I'm just getting started as a user, and I found this in the docs:
This is a work in progress, we have a way to generate resolver stubs, but it cannot currently update existing code. We can force it to run again by deleting resolver.go and re-running gqlgen:
I used to work at a place that used a lot of generated code, and one thing that helped a lot with updating files with manual modifications made to them was explicitly marking each portion of the file intended for manual editing with a comment that identified the segment and its end. e.g., your example from the docs might end up looking something like
func (r *mutationResolver) CreateTodo(ctx context.Context, input NewTodo) (Todo, error) {
// BEGIN MANUAL SECTION mutation_resolver_create_todo
todo := Todo{
Text: input.Text,
ID: fmt.Sprintf("T%d", rand.Int()),
UserID: input.UserID,
}
r.todos = append(r.todos, todo)
return todo, nil
// END MANUAL SECTION mutation_resolver_create_todo
}
It's a slightly obnoxious intrusion in the file, but the upside is that now when you want to regenerate the file you can guarantee that you're doing so without touching anything the user has modified, as long as they haven't strayed outside the marked manual sections. And if you really want to ensure you don't accidentally overwrite any manual code, you can put a checksum of all the generated code in the file in a comment at the top, and then just have the tooling throw a warning/error if a user tries to re-generate a file whose generated sections don't match the checksum.
Great idea, I really need this...
another way to work around this would be to allow to register handlers
the autogenerated part
var CreateTodoHandler func(context.Context, NewTodo) (Todo, error)
func (r *mutationResolver) CreateTodo(ctx context.Context, input NewTodo) (Todo, error) {
return CreateTodoHandler(ctx, input)
}
somewhere else
resolver.CreateTodoHandler = func(ctx context.Context, input NewTodo) (Todo, error) {
todo := Todo{
Text: input.Text,
ID: fmt.Sprintf("T%d", rand.Int()),
UserID: input.UserID,
}
r.todos = append(r.todos, todo)
return todo, nil
}
i also worked on codegen on large projects. Marking portions that are user editted and for the codegenerator to ignore was really useful.
its eay to do because you run the normal codegen to the file system and then look at the user code and path the two together.
So its does not have to change using the new gql template codegen that uses golang templates
Thanks for the suggestions. We know there are issues with stub generation and are actually investigating some dynamic solutions here that we hope will be really seamless and Just Work the way you expect.
Demarcating manual sections should not be required since we can easily parse the code and figure out what are function signatures, what is user code, and what is missing in order to satisfy the interfaces.
I think they key take-away currently is to understand that the stubs are not the output of gqlgen, they're just a helper to give you the outline of the root resolver interface gqlgen expects you to provide.
Most helpful comment
another way to work around this would be to allow to register handlers
the autogenerated part
somewhere else