Skip to content

Commit

Permalink
Enable lowercase type names in GraphQL schema to properly render (#1359)
Browse files Browse the repository at this point in the history
The difficulty with lowercased type names is that in go code any lowercased name is not exported.
This change makes the names title case for go code while preserving the proper case when interacting with the GraphQL schema.

Co-authored-by: Liam Murphy <liamphmurphy@gmail.com>
  • Loading branch information
tkuhlman and Liam Murphy authored Oct 11, 2021
1 parent 50f6a2a commit 589a774
Show file tree
Hide file tree
Showing 9 changed files with 183 additions and 8 deletions.
2 changes: 1 addition & 1 deletion codegen/field.go
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,7 @@ func (f *Field) GoNameUnexported() string {
}

func (f *Field) ShortInvocation() string {
return fmt.Sprintf("%s().%s(%s)", f.Object.Definition.Name, f.GoFieldName, f.CallArgs())
return fmt.Sprintf("%s().%s(%s)", strings.Title(f.Object.Definition.Name), f.GoFieldName, f.CallArgs())
}

func (f *Field) ArgsFunc() string {
Expand Down
6 changes: 3 additions & 3 deletions codegen/generated!.gotpl
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ type Config struct {
type ResolverRoot interface {
{{- range $object := .Objects -}}
{{ if $object.HasResolvers -}}
{{$object.Name}}() {{$object.Name}}Resolver
{{ucFirst $object.Name}}() {{ucFirst $object.Name}}Resolver
{{ end }}
{{- end }}
}
Expand All @@ -46,7 +46,7 @@ type DirectiveRoot struct {
type ComplexityRoot struct {
{{ range $object := .Objects }}
{{ if not $object.IsReserved -}}
{{ $object.Name|go }} struct {
{{ucFirst $object.Name|go }} struct {
{{ range $_, $fields := $object.UniqueFields }}
{{- $field := index $fields 0 -}}
{{ if not $field.IsReserved -}}
Expand All @@ -60,7 +60,7 @@ type ComplexityRoot struct {

{{ range $object := .Objects -}}
{{ if $object.HasResolvers }}
type {{$object.Name}}Resolver interface {
type {{ucFirst $object.Name}}Resolver interface {
{{ range $field := $object.Fields -}}
{{- if $field.IsResolver }}
{{- $field.GoFieldName}}{{ $field.ShortResolverDeclaration }}
Expand Down
2 changes: 1 addition & 1 deletion codegen/object.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func (b *builder) buildObject(typ *ast.Definition) (*Object, error) {
Stream: typ == b.Schema.Subscription,
Directives: dirs,
ResolverInterface: types.NewNamed(
types.NewTypeName(0, b.Config.Exec.Pkg(), typ.Name+"Resolver", nil),
types.NewTypeName(0, b.Config.Exec.Pkg(), strings.Title(typ.Name)+"Resolver", nil),
nil,
nil,
),
Expand Down
144 changes: 144 additions & 0 deletions example/config/generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions example/config/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,13 @@ import "fmt"
type User struct {
ID string
FirstName, LastName string
Role UserRole
}

func (user *User) FullName() string {
return fmt.Sprintf("%s %s", user.FirstName, user.LastName)
}

type UserRole struct {
RoleName string
}
6 changes: 6 additions & 0 deletions example/config/user.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,10 @@ type User
@goModel(model:"github.com/99designs/gqlgen/example/config.User") {
id: ID!
name: String! @goField(name:"FullName")
role: role!
}

type role
@goModel(model:"github.com/99designs/gqlgen/example/config.UserRole") {
name: String!
}
20 changes: 20 additions & 0 deletions example/config/user.resolvers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package config

// This file will be automatically regenerated based on the schema, any resolver implementations
// will be copied through when generating and any unknown code will be moved to the end.

import (
"context"
)

func (r *roleResolver) Name(ctx context.Context, obj *UserRole) (string, error) {
if obj == nil {
return "", nil
}
return obj.RoleName, nil
}

// Role returns RoleResolver implementation.
func (r *Resolver) Role() RoleResolver { return &roleResolver{r} }

type roleResolver struct{ *Resolver }
2 changes: 1 addition & 1 deletion plugin/resolvergen/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ func (m *Plugin) generatePerSchema(data *codegen.Data) error {
}

rewriter.MarkStructCopied(templates.LcFirst(o.Name) + templates.UcFirst(data.Config.Resolver.Type))
rewriter.GetMethodBody(data.Config.Resolver.Type, o.Name)
rewriter.GetMethodBody(data.Config.Resolver.Type, strings.Title(o.Name))
files[fn].Objects = append(files[fn].Objects, o)
}
for _, f := range o.Fields {
Expand Down
4 changes: 2 additions & 2 deletions plugin/resolvergen/resolver.gotpl
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
{{ end }}

{{ range $object := .Objects -}}
// {{$object.Name}} returns {{ $object.ResolverInterface | ref }} implementation.
func (r *{{$.ResolverType}}) {{$object.Name}}() {{ $object.ResolverInterface | ref }} { return &{{lcFirst $object.Name}}{{ucFirst $.ResolverType}}{r} }
// {{ucFirst $object.Name}} returns {{ $object.ResolverInterface | ref }} implementation.
func (r *{{$.ResolverType}}) {{ucFirst $object.Name}}() {{ $object.ResolverInterface | ref }} { return &{{lcFirst $object.Name}}{{ucFirst $.ResolverType}}{r} }
{{ end }}

{{ range $object := .Objects -}}
Expand Down

0 comments on commit 589a774

Please sign in to comment.