Generated models (with multi-part member names) cannot be used with MongoDB
The ability to directly parse the resulting BSON from MongoDB queries into the models generated by gqlgen.
This is handy when the graphql schema exactly matches the models stored in MongoDB
type WithMultiPartMember {
multi_part_member: String
}
Would currently generate...
type WithMultiPartMember struct {
MultiPartMember *string `json:"multi_part_member"`
}
Would like it to generate...
type WithMultiPartMember struct {
MultiPartMember *string `json:"multi_part_member"` `bson:"multi_part_member"`
}
Replace plugin/modelgen/models.go:181
Tag: `json:"` + field.Name + `"`,
with
Tag: `json:"` + field.Name + `" bson:"` + field.Name + `"`,
gqlgen version v0.9.3-devgo version 1.13Can generate PR if you are happy with it
i need this feature
What about the possibility to add options in graphql schema file like this:
input WithMultiPartMember {
multi_part_member: String #`json:"multi_part_member" bson:"multi_part_member,omitempty"`
}
I need to add bson omitempty for mongo-go updates with optional fields.
Another use case is this:
type Car {
id: ID! # `json:"id" bson:"_id"`
...
}
Like this the _id in MongoDB is automatically well Marshaled and UnMarshaled
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.
@vektah - should I make a PR for this?
https://gqlgen.com/recipes/modelgen-hook/
models generated by modelgen plugin. and it has a hooks.
You can inject bson tag by yourself.
I think it seems convenient to write plugin settings in gqlgen.yml.
Following the tips from @vvakame, I created a file called runner.go inside an otherwise empty folder with the following code:
package main
import (
"fmt"
"os"
"github.com/99designs/gqlgen/api"
"github.com/99designs/gqlgen/codegen/config"
"github.com/99designs/gqlgen/plugin/modelgen"
)
func mutateHook(b *modelgen.ModelBuild) *modelgen.ModelBuild {
for _, model := range b.Models {
for _, field := range model.Fields {
name := field.Name
if name == "id" {
name = "_id"
}
field.Tag += ` bson:"` + name + `"`
}
}
return b
}
func main() {
cfg, err := config.LoadConfigFromDefaultLocations()
if err != nil {
fmt.Fprintln(os.Stderr, "failed to load config", err.Error())
os.Exit(2)
}
p := modelgen.Plugin{
MutateHook: mutateHook,
}
err = api.Generate(cfg,
api.NoPlugins(),
api.AddPlugin(&p),
)
if err != nil {
fmt.Fprintln(os.Stderr, err.Error())
os.Exit(3)
}
}
I then call it with go run runner\runner.go and it will generate my models with mongo friendly bson tags.
Following the tips from @vvakame, I created a file called runner.go inside an otherwise empty folder with the following code:
package main import ( "fmt" "os" "github.com/99designs/gqlgen/api" "github.com/99designs/gqlgen/codegen/config" "github.com/99designs/gqlgen/plugin/modelgen" ) func mutateHook(b *modelgen.ModelBuild) *modelgen.ModelBuild { for _, model := range b.Models { for _, field := range model.Fields { name := field.Name if name == "id" { name = "_id" } field.Tag += ` bson:"` + name + `"` } } return b } func main() { cfg, err := config.LoadConfigFromDefaultLocations() if err != nil { fmt.Fprintln(os.Stderr, "failed to load config", err.Error()) os.Exit(2) } p := modelgen.Plugin{ MutateHook: mutateHook, } err = api.Generate(cfg, api.NoPlugins(), api.AddPlugin(&p), ) if err != nil { fmt.Fprintln(os.Stderr, err.Error()) os.Exit(3) } }I then call it with
go run runner\runner.goand it will generate my models with mongo friendly bson tags.
You demonstrated how to mannually run the hook, the thing is, how could the mutate hook run alongside with the normal gqlgen generate procedure?
This recipe here doesn't show whether we should run the code separately, as what you did. Or we could incorporate the hook into gqlgen generate.
@vvakame Please advise.
It seems the plugin runs the gqlgen generate procedure automatically along with hook.
So I just changed //go:generate go run github.com/99designs/gqlgen to //go:generate go run hooks/bson.go and go generate ./... works as expected.
@SergeyYakubov this works, thanks!
It seems the plugin runs the gqlgen generate procedure automatically along with hook.
So I just changed//go:generate go run github.com/99designs/gqlgento//go:generate go run hooks/bson.goandgo generate ./...works as expected.
I got go generate exited with an error, check gopls logs error when running go generate ./...
Can you provide your bson.go?
Thanks.
@kockok - it is exactly the same example showed above https://github.com/99designs/gqlgen/issues/865#issuecomment-573043996, which itself a slight modification of a gqlgen recipe, so your errors must be somewhere else.
@SergeyYakubov Wondering if package main matters.
The recipe didn't indicate which package to implement, or ANY package, e.g. package graph is ok.
This should be implemented as default. It is a must!
This should be a parameter in gqlgen.yml file
Most helpful comment
Following the tips from @vvakame, I created a file called runner.go inside an otherwise empty folder with the following code:
I then call it with
go run runner\runner.goand it will generate my models with mongo friendly bson tags.