gqlgen: "Getting Started" docs seem pretty broken?

What happened?

Multiple steps seem broken/missing The tutorial tells you to define your own “getting started” schema - https://gqlgen.com/getting-started/#define-the-schema - then to run go run github.com/99designs/gqlgen init. Defining your own schema is completely pointless because init will just drop one in for you.

➜  work mkdir graphql-todos
➜  work cd graphql-todos 
➜  graphql-todos go mod init github.com/foobar/todos
go: creating new go.mod: module github.com/foobar/todos
 graphql-todos  go run github.com/99designs/gqlgen init
Exec "go run ./server/server.go" to start GraphQL server
➜  graphql-todos ls
generated.go   go.mod         go.sum         gqlgen.yml     models_gen.go  resolver.go    schema.graphql server
➜  graphql-todos cat schema.graphql 
# GraphQL schema example
#
# https://gqlgen.com/getting-started/

type Todo {
  id: ID!
  text: String!
  done: Boolean!
  user: User!
}

type User {
  id: ID!
  name: String!
}

type Query {
  todos: [Todo!]!
}

input NewTodo {
  text: String!
  userId: String!
}

type Mutation {
  createTodo(input: NewTodo!): Todo!
}

Ok, so far so good. Got my stuff in place. Second problem - need to enable “lazy loading” for the User model in the Todo model (sorry if my terminology is off, a bit new to graphql)

So I change

type Todo struct {
	ID   string `json:"id"`
	Text string `json:"text"`
	Done bool   `json:"done"`
	User *User  `json:"user"`
}

to

type Todo struct {
	ID     string `json:"id"`
	Text   string `json:"text"`
	Done   bool   `json:"done"`
	UserID string `json:"user"`
}

Ok then it says to run go run github.com/99designs/gqlgen and proceeds to tell me about the “verbose” flag which isn’t even in the command I just ran (?) But let’s ignore that and run gqlgen without any parameters which is the same as running it with the generate command (probably mention that?)

graphql-todos go run github.com/99designs/gqlgen
unable to parse config: yaml: unmarshal errors:
  line 18: key "deprecated" already set in map
  line 20: key "include" already set in map
  line 22: key "skip" already set in map
exit status 2
➜  graphql-todos 

Ouch? At this point, all I’ve done is changed the User entity a bit and I’m getting yaml unmarshal errors? Ok let’s remove the offending keys (why is the default gqlgen.yml causing errors?)

graphql-todos cat gqlgen.yml 
# .gqlgen.yml example
#
# Refer to https://gqlgen.com/config/
# for detailed .gqlgen.yml documentation.

schema:
- schema.graphql
exec:
  filename: generated.go
model:
  filename: models_gen.go
resolver:
  filename: resolver.go
  type: Resolver
autobind: []
# directives:
#   deprecated:
#     skip_runtime: true
#   include:
#     skip_runtime: true
#   skip:
#     skip_runtime: true
➜  graphql-todos go run github.com/99designs/gqlgen
➜  graphql-todos 

Finally - success. So is the expected workflow for me to comment out the directives every time I run generate?

So to sum up:

  1. Docs make user create a schema needlessly
  2. Mention of a “verbose” flag
  3. Following the steps with version 0.9.1 gives yaml unmarshal errors

What did you expect?

Stuff to mostly work.

Minimal graphql.schema and models to reproduce

Default from init command

versions

  • gqlgen version - v0.9.1
  • go version? - 1.12.6 darwin/amd64
  • dep or go modules? - go modules

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 7
  • Comments: 17 (1 by maintainers)

Most upvoted comments

In Go lowercase properties are private banks uppercase are exported I.e. public

In Go everything in the package can be spread over many files in the same directory. So todo.go should be placed in the same directory as models_gen.go. I would not recommend modifying models_gen.go, just move it out.

The model field should be your the full package + struct type i think (more of a go packages thing). I would recommend autobind function, you don’t need to indicate every different struct and just the package is enough.

I think there is also a typo with the Todos resolver.

.\resolver.go:17:24: cannot use &queryResolver literal (type *queryResolver) as type QueryResolver in return argument:
*queryResolver does not implement QueryResolver (wrong type for Todos method) have Todos(context.Context) ([]Todo, error) want Todos(context.Context) ([]*Todo, error) .\resolver.go:38:10: cannot use r.Resolver.todos (type []*Todo) as type []Todo in return argument

func (r *queryResolver) Todos(ctx context.Context) ([]*Todo, error) {
	return r.todos, nil
}

instead of

func (r *queryResolver) Todos(ctx context.Context) ([]Todo, error) {
	return r.todos, nil
}