Skip to content

Commit

Permalink
Merge pull request 99designs#761 from 99designs/autobinding
Browse files Browse the repository at this point in the history
Autobind models
  • Loading branch information
vektah authored Jun 26, 2019
2 parents da9d1ee + 93954ad commit c9d00f6
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 8 deletions.
28 changes: 28 additions & 0 deletions codegen/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import (
"sort"
"strings"

"golang.org/x/tools/go/packages"

"github.com/99designs/gqlgen/internal/code"
"github.com/pkg/errors"
"github.com/vektah/gqlparser"
Expand All @@ -22,6 +24,7 @@ type Config struct {
Exec PackageConfig `yaml:"exec"`
Model PackageConfig `yaml:"model"`
Resolver PackageConfig `yaml:"resolver,omitempty"`
AutoBind []string `yaml:"autobind"`
Models TypeMap `yaml:"models,omitempty"`
StructTag string `yaml:"struct_tag,omitempty"`
Directives map[string]DirectiveConfig `yaml:"directives,omitempty"`
Expand Down Expand Up @@ -379,6 +382,31 @@ func (c *Config) normalize() error {
return nil
}

func (c *Config) Autobind(s *ast.Schema) error {
if len(c.AutoBind) == 0 {
return nil
}
ps, err := packages.Load(&packages.Config{Mode: packages.LoadTypes}, c.AutoBind...)
if err != nil {
return err
}

for _, t := range s.Types {
if c.Models.UserDefined(t.Name) {
continue
}

for _, p := range ps {
if t := p.Types.Scope().Lookup(t.Name); t != nil {
c.Models.Add(t.Name(), t.Pkg().Path()+"."+t.Name())
break
}
}
}

return nil
}

func (c *Config) InjectBuiltins(s *ast.Schema) {
builtins := TypeMap{
"__Directive": {Model: StringList{"github.com/99designs/gqlgen/graphql/introspection.Directive"}},
Expand Down
23 changes: 23 additions & 0 deletions codegen/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import (
"runtime"
"testing"

"github.com/vektah/gqlparser"
"github.com/vektah/gqlparser/ast"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
Expand Down Expand Up @@ -114,3 +117,23 @@ func TestConfigCheck(t *testing.T) {
require.EqualError(t, err, "filenames exec.go and models.go are in the same directory but have different package definitions")
})
}

func TestAutobinding(t *testing.T) {
cfg := Config{
Models: TypeMap{},
AutoBind: []string{
"github.com/99designs/gqlgen/example/chat",
"github.com/99designs/gqlgen/example/scalars/model",
},
}

s := gqlparser.MustLoadSchema(&ast.Source{Name: "TestAutobinding.schema", Input: `
scalar Banned
type Message { id: ID }
`})

require.NoError(t, cfg.Autobind(s))

require.Equal(t, "github.com/99designs/gqlgen/example/scalars/model.Banned", cfg.Models["Banned"].Model[0])
require.Equal(t, "github.com/99designs/gqlgen/example/chat.Message", cfg.Models["Message"].Model[0])
}
5 changes: 5 additions & 0 deletions codegen/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ func BuildData(cfg *config.Config) (*Data, error) {
return nil, err
}

err = cfg.Autobind(b.Schema)
if err != nil {
return nil, err
}

cfg.InjectBuiltins(b.Schema)

b.Binder, err = b.Config.NewBinder(b.Schema)
Expand Down
5 changes: 5 additions & 0 deletions docs/content/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ resolver:
# Optional, turns on binding to field names by tag provided
struct_tag: json

# Instead of listing out every model like below, you can automatically bind to any matching types
# within the given path. EXPERIMENTAL in v0.9.1
autobind:
- github.com/my/app/models

# Tell gqlgen about any existing models you want to reuse for
# graphql. These normally come from the db or a remote api.
models:
Expand Down
11 changes: 3 additions & 8 deletions example/starwars/.gqlgen.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,10 @@ exec:
model:
filename: models/generated.go

autobind:
- github.com/99designs/gqlgen/example/starwars/models

models:
Droid:
model: github.com/99designs/gqlgen/example/starwars/models.Droid
FriendsConnection:
model: github.com/99designs/gqlgen/example/starwars/models.FriendsConnection
Human:
model: github.com/99designs/gqlgen/example/starwars/models.Human
Review:
model: github.com/99designs/gqlgen/example/starwars/models.Review
ReviewInput:
model: github.com/99designs/gqlgen/example/starwars/models.Review
Starship:
Expand Down
5 changes: 5 additions & 0 deletions plugin/modelgen/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ func (m *Plugin) MutateConfig(cfg *config.Config) error {
return err
}

err = cfg.Autobind(schema)
if err != nil {
return err
}

cfg.InjectBuiltins(schema)

binder, err := cfg.NewBinder(schema)
Expand Down

0 comments on commit c9d00f6

Please sign in to comment.