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:
Stuff to mostly work.
Default from init command
gqlgen version - v0.9.1go version? - 1.12.6 darwin/amd64@dvelitchkov Same error here. Got any solution?
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
}
@als9xd I think you may have commented on the wrong issue buddy.
I can replicate the issue too, looks like something to do with how the default config already has the directives fields set and is used to unmarshal the local config here: https://github.com/99designs/gqlgen/blob/master/codegen/config/config.go#L36
Which was added in 17a82c3 by @lwc
Rolling back to an earlier version before May 27th may work due to removing this change, but will unfortunately roll back a load of other additions.
Simple reproduction here: https://play.golang.org/p/vFVkfwFpCTk
From the Yaml docs:
"UnmarshalStrict is like Unmarshal except that any fields that are found in the data that do not have corresponding struct members, or mapping keys that are duplicates, will result in an error."
Shows that this would never work. Should probably add those keys in to the default config only for writing the initial or if they are not found AFTER parsing the local gqlgen.yml
not sure why this was closed. i am very familiar with graphql but new to go. wanted to learn how its implemented on the go side and was recommended gqlgen.
i am appreciative of your tool and guide. but i hope that given a complete beginner perspective we can improve the docs. if you can sort me out id be happy to open a PR with fixes to improve it for future beginners
this is a list of my own confusions:
Create the database models
The generated model for Todo isnβt right, it has a user embeded in it but we only want to fetch it if the user actually requested it. So instead lets make a new model in todo.go:
todo.go is. that was not one of the generated files. did it mean to say edit the models_gen.go file (as it appears OP has done)? i read that as to create a file called todo.go and to put in the suggested structNext tell gqlgen to use this new struct by adding it to gqlgen.yml:
models:
Todo:
model: github.com/[username]/gqlgen-todos.Todo
my own gqlgen.yml file did not have a models field so i added it like this, is this correct?:
# .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
# there is no models field so i added it here
models:
Todo:
model: github.com/the-vampiire/gqlgen-todos.Todo
resolver:
filename: resolver.go
type: Resolver
autobind: []
directives:
deprecated:
skip_runtime: true
include:
skip_runtime: true
skip:
skip_runtime: true
i then ran the following commands:
$ vim gqlgen.yml
$ go run github.com/99designs/gqlgen
unable to parse config: yaml: unmarshal errors:
line 21: key "deprecated" already set in map
line 23: key "include" already set in map
line 25: key "skip" already set in map
exit status 2
using what i saw from OP i commented out the directives bit and then ran using the -v flag for the following result
$ vim gqlgen.yml
$ go run github.com/99designs/gqlgen -v
/Users/vampiire/codes/personal/gqlgen-todos/todo.go:3 adding resolver method for Todo.user, nothing matched
Skipped resolver: /Users/vampiire/codes/personal/gqlgen-todos/resolver.go already exists
since this is not working, instead of creating a todo.go file i was to edit the models_gen.go file itself (as in OP). but when i enter the file it looks like the Todo struct had been removed. pretty neat that it blends this generated models with your own models. but now i am unsure how to proceed
so the warning about "nothing matched" and "skipped resolver" did not have an impact. i continued with the rest of the guide and it worked.
maybe just clarify those beginning parts because the rest seems to be correct. thanks
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.
good to know man thank you for the information. if its not too much to ask i was trying to implement a little extension to the code so cement my understanding.
i added the following mutation to the schema
type Mutation {
completeTodo(todoID: ID!): Todo
}
then in my resolver.go i tried doing the following
edit: im dumb. in go types come after the var name!
string todoID -> todoID string
func (r *mutationResolver) CompleteTodo(ctx context.Context, todoID string) (*Todo, error) {
for _, todo := range r.todos {
if todo.ID == todoID {
todo.Done = true
return todo, nil
}
}
return nil, nil
}
this is clearly because i should learn more go and not a fault of the package. but could you tell me why i cant accept a string arg todoID here? i get undeclared name: todoID error. are scalar inputs not allowed in gqlgen?
another curiosity i have is why the schema uses lowercase but in the go code all the properties are capitalized. is this a go convention for structs or something to do with the lib itself?
In Go lowercase properties are private banks uppercase are exported I.e. public
In Go lowercase properties are private banks uppercase are exported I.e. public
is that a convention (like __prop in python) or a feature of the language?
deconstructing the code it looks like adding "methods" (not sure of terminology in go) onto a struct has the form
func (*this StructName) FuncName(args) returnType | (returnType, returnType2) {
// implementation
// this refers to the instance of the struct for accessing properties in the method
}
anyways this was pretty cool thank you for the guide. i think i will spend some time learning go now!
I submitted PR #801 to address a few of the inconsistencies, but I still get these errors:
$ 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
I see that #781 appears to address this, but I don't get the benefit. Do I need to do something to get this update?
This issue of yaml still exists.
Why issue was closed? The issue still exists:
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
It seems that just change from yarm.UnmarshalStrict to yarm. Unmarshal works, and also get the result we expect.
BUT I don't know whether any side effect exists.
https://github.com/99designs/gqlgen/blob/master/codegen/config/config.go#L76
Related Issue: #781
Still getting this error when following the getting started tutorial. Removing the following lines from gqlgen.yml squashes the error, but also not sure of the side effects:
directives:
deprecated:
skip_runtime: true
include:
skip_runtime: true
skip:
skip_runtime: true