├── .chglog
├── CHANGELOG-full-history.tpl.md
└── config.yml
├── .dockerignore
├── .editorconfig
├── .gitattributes
├── .github
├── ISSUE_TEMPLATE.md
├── PULL_REQUEST_TEMPLATE.md
├── dependabot.yml
└── workflows
│ ├── GOVERSION.txt
│ ├── check-coverage
│ ├── check-federation
│ ├── check-fmt
│ ├── check-generate
│ ├── check-gomod.sh
│ ├── check-init
│ ├── check-integration
│ ├── coverage.yml
│ ├── fmt-and-generate.yml
│ ├── gomod-clean.yml
│ ├── integration.yml
│ ├── lint.yml
│ ├── report.yml
│ ├── security.yml
│ └── test.yml
├── .gitignore
├── .golangci.yml
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── RELEASE-CHECKLIST.md
├── TESTING.md
├── _examples
├── chat
│ ├── .gitignore
│ ├── .gqlgen.yml
│ ├── chat_test.go
│ ├── generated.go
│ ├── models_gen.go
│ ├── package.json
│ ├── public
│ │ └── index.html
│ ├── readme.md
│ ├── resolvers.go
│ ├── schema.graphql
│ ├── server
│ │ └── server.go
│ ├── src
│ │ ├── App.js
│ │ ├── Room.js
│ │ ├── components
│ │ │ └── room.js
│ │ ├── graphql-sse.ts
│ │ ├── graphql-ws.js
│ │ ├── index.js
│ │ └── react-app-env.d.ts
│ └── tsconfig.json
├── config
│ ├── .gqlgen.yml
│ ├── generated.go
│ ├── model.go
│ ├── models_gen.go
│ ├── resolver.go
│ ├── schema.graphql
│ ├── schema.resolvers.go
│ ├── server
│ │ └── server.go
│ ├── todo.graphql
│ ├── todo.resolvers.go
│ ├── user.graphql
│ └── user.resolvers.go
├── dataloader
│ ├── .gqlgen.yml
│ ├── addressloader_gen.go
│ ├── dataloader_test.go
│ ├── dataloaders.go
│ ├── generated.go
│ ├── itemsliceloader_gen.go
│ ├── models_gen.go
│ ├── ordersliceloader_gen.go
│ ├── readme.md
│ ├── resolvers.go
│ ├── schema.graphql
│ └── server
│ │ └── server.go
├── deferexample
│ ├── generated.go
│ ├── gqlgen.yml
│ ├── models_gen.go
│ ├── resolver.go
│ ├── schema.graphql
│ ├── schema.resolvers.go
│ └── server
│ │ └── server.go
├── embedding
│ ├── parent.graphqls
│ └── subdir
│ │ ├── cfgdir
│ │ ├── generate_in_gendir.yml
│ │ └── generate_in_subdir.yml
│ │ ├── directives.generated.go
│ │ ├── embedding_test.go
│ │ ├── entity.generated.go
│ │ ├── federation_gen.go
│ │ ├── gendir
│ │ ├── federation_gen.go
│ │ ├── generated.go
│ │ └── model.go
│ │ ├── model.go
│ │ ├── prelude.generated.go
│ │ ├── resolvers.go
│ │ ├── root.generated.go
│ │ ├── root_.generated.go
│ │ ├── schemadir
│ │ └── root.graphqls
│ │ └── subdir.graphqls
├── enum
│ ├── api
│ │ ├── enum.go
│ │ ├── exec.go
│ │ ├── model.go
│ │ └── resolver.go
│ ├── cmd
│ │ └── main.go
│ ├── enum.graphqls
│ ├── gen.go
│ ├── gqlgen.yaml
│ └── model
│ │ └── model.go
├── federation
│ ├── accounts
│ │ ├── gqlgen.yml
│ │ ├── graph
│ │ │ ├── entity.resolvers.go
│ │ │ ├── federation.go
│ │ │ ├── generated.go
│ │ │ ├── model
│ │ │ │ ├── model.go
│ │ │ │ └── models_gen.go
│ │ │ ├── resolver.go
│ │ │ ├── schema.graphqls
│ │ │ └── schema.resolvers.go
│ │ ├── schema
│ │ │ └── schema.go
│ │ └── server.go
│ ├── all
│ │ └── main.go
│ ├── gateway
│ │ └── index.js
│ ├── integration-test.js
│ ├── jest.config.js
│ ├── package.json
│ ├── products
│ │ ├── gqlgen.yml
│ │ ├── graph
│ │ │ ├── entity.resolvers.go
│ │ │ ├── federation.go
│ │ │ ├── generated.go
│ │ │ ├── model
│ │ │ │ ├── model.go
│ │ │ │ └── models_gen.go
│ │ │ ├── products.go
│ │ │ ├── resolver.go
│ │ │ ├── schema.graphqls
│ │ │ └── schema.resolvers.go
│ │ ├── schema
│ │ │ └── schema.go
│ │ └── server.go
│ ├── readme.md
│ ├── reviews
│ │ ├── gqlgen.yml
│ │ ├── graph
│ │ │ ├── entity.resolvers.go
│ │ │ ├── federation.go
│ │ │ ├── generated.go
│ │ │ ├── model
│ │ │ │ ├── models.go
│ │ │ │ └── models_gen.go
│ │ │ ├── resolver.go
│ │ │ ├── reviews.go
│ │ │ ├── schema.graphqls
│ │ │ └── schema.resolvers.go
│ │ ├── schema
│ │ │ └── schema.go
│ │ └── server.go
│ ├── start.sh
│ └── subgraphs
│ │ └── subgraphs.go
├── fileupload
│ ├── .gqlgen.yml
│ ├── fileupload_test.go
│ ├── generated.go
│ ├── model
│ │ └── generated.go
│ ├── readme.md
│ ├── schema.graphql
│ ├── server
│ │ └── server.go
│ ├── stubs.go
│ └── testfiles
│ │ ├── a.txt
│ │ ├── b.txt
│ │ └── c.txt
├── go.mod
├── go.sum
├── large-project-structure
│ ├── integration
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── integration.go
│ │ └── schema.graphqls
│ ├── main
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── gqlgen.yml
│ │ ├── graph
│ │ │ ├── generated.go
│ │ │ ├── model
│ │ │ │ └── models_gen.go
│ │ │ ├── resolver.go
│ │ │ ├── schema.graphqls
│ │ │ └── schema.resolvers.go
│ │ ├── server.go
│ │ └── tools.go
│ └── shared
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── schema.graphqls
│ │ └── shared.go
├── mini-habr-with-subscriptions
│ ├── .env
│ ├── Dockerfile
│ ├── README.md
│ ├── cmd
│ │ ├── db_connection
│ │ │ ├── cache.go
│ │ │ └── database.go
│ │ ├── main.go
│ │ └── server
│ │ │ └── server.go
│ ├── docker-compose.yml
│ ├── go.mod
│ ├── go.sum
│ ├── gqlgen.yml
│ ├── graph
│ │ ├── generated.go
│ │ ├── model
│ │ │ └── models_gen.go
│ │ ├── resolver.go
│ │ ├── schema.graphqls
│ │ ├── schema.resolvers.go
│ │ └── subscription.go
│ ├── internal
│ │ ├── handlers
│ │ │ ├── comment_mutation
│ │ │ │ ├── interface.go
│ │ │ │ └── mutations.go
│ │ │ ├── comment_query
│ │ │ │ ├── interface.go
│ │ │ │ └── query.go
│ │ │ ├── post_mutation
│ │ │ │ ├── interface.go
│ │ │ │ └── mutations.go
│ │ │ └── post_query
│ │ │ │ ├── interface.go
│ │ │ │ └── query.go
│ │ ├── model
│ │ │ └── model.go
│ │ ├── pkg
│ │ │ ├── cursor
│ │ │ │ └── cursor.go
│ │ │ └── errs
│ │ │ │ └── errors.go
│ │ └── storage
│ │ │ ├── db
│ │ │ └── resolvers.go
│ │ │ ├── in-memory
│ │ │ └── resolvers.go
│ │ │ └── interface.go
│ ├── migrations
│ │ └── 001_create_tables.up.sql
│ └── tools
│ │ └── tools.go
├── readme.md
├── scalars
│ ├── .gqlgen.yml
│ ├── external
│ │ └── model.go
│ ├── generated.go
│ ├── model
│ │ ├── generated.go
│ │ └── model.go
│ ├── resolvers.go
│ ├── scalar_test.go
│ ├── schema.graphql
│ └── server
│ │ └── server.go
├── selection
│ ├── .gqlgen.yml
│ ├── generated.go
│ ├── models_gen.go
│ ├── readme.md
│ ├── schema.graphql
│ ├── selection.go
│ ├── selection_test.go
│ └── server
│ │ └── server.go
├── starwars
│ ├── .gqlgen.yml
│ ├── benchmarks_test.go
│ ├── generated
│ │ └── exec.go
│ ├── models
│ │ ├── generated.go
│ │ └── model.go
│ ├── readme.md
│ ├── resolvers.go
│ ├── schema.graphql
│ ├── server
│ │ └── server.go
│ └── starwars_test.go
├── todo
│ ├── generated.go
│ ├── gqlgen.yml
│ ├── models.go
│ ├── models_gen.go
│ ├── readme.md
│ ├── schema.graphql
│ ├── server
│ │ └── server.go
│ ├── todo.go
│ └── todo_test.go
├── tools.go
├── type-system-extension
│ ├── README.md
│ ├── directive.go
│ ├── generated.go
│ ├── gqlgen.yml
│ ├── models_gen.go
│ ├── resolver.go
│ ├── schemas
│ │ ├── enum-extension.graphql
│ │ ├── input-object-extension.graphql
│ │ ├── interface-extension.graphql
│ │ ├── object-extension.graphql
│ │ ├── scalar-extension.graphql
│ │ ├── schema-extension.graphql
│ │ ├── schema.graphql
│ │ ├── type-extension.graphql
│ │ └── union-extension.graphql
│ └── server
│ │ └── server.go
├── uuid
│ ├── gqlgen.yml
│ ├── graph
│ │ ├── generated.go
│ │ ├── model
│ │ │ └── models_gen.go
│ │ ├── resolver.go
│ │ ├── schema.graphqls
│ │ └── schema.resolvers.go
│ └── server.go
└── websocket-initfunc
│ ├── graph
│ ├── generated.go
│ ├── model
│ │ └── models_gen.go
│ └── resolver.go
│ └── server
│ ├── Makefile
│ ├── go.mod
│ ├── go.sum
│ ├── gqlgen.yml
│ ├── graph
│ ├── generated.go
│ ├── model
│ │ └── models_gen.go
│ ├── resolver.go
│ ├── schema.graphqls
│ └── schema.resolvers.go
│ ├── readme.md
│ └── server.go
├── api
├── generate.go
├── generate_test.go
├── option.go
├── option_test.go
└── testdata
│ ├── default
│ ├── gqlgen.yml
│ └── graph
│ │ ├── model
│ │ └── doc.go
│ │ └── schema.graphqls
│ ├── federation2
│ ├── gqlgen.yml
│ └── graph
│ │ ├── model
│ │ └── doc.go
│ │ └── schema.graphqls
│ └── workerlimit
│ ├── gqlgen.yml
│ └── graph
│ ├── model
│ └── doc.go
│ └── schema.graphqls
├── bin
└── release
├── client
├── client.go
├── client_test.go
├── errors.go
├── incremental_http.go
├── options.go
├── readme.md
├── sse.go
├── websocket.go
├── withfilesoption.go
└── withfilesoption_test.go
├── codegen
├── args.go
├── args.gotpl
├── complexity.go
├── config
│ ├── binder.go
│ ├── binder_test.go
│ ├── config.go
│ ├── config_test.go
│ ├── exec.go
│ ├── initialisms.go
│ ├── initialisms_test.go
│ ├── package.go
│ ├── package_test.go
│ ├── resolver.go
│ ├── resolver_test.go
│ └── testdata
│ │ ├── autobinding
│ │ ├── chat
│ │ │ └── model.go
│ │ └── scalars
│ │ │ └── model
│ │ │ └── model.go
│ │ ├── binding
│ │ └── model.go
│ │ ├── cfg
│ │ ├── glob.yml
│ │ ├── glob
│ │ │ ├── bar
│ │ │ │ └── bar with spaces.graphql
│ │ │ └── foo
│ │ │ │ └── foo.graphql
│ │ ├── goInitialisms.yml
│ │ ├── gqlgen.yml
│ │ ├── malformedconfig.yml
│ │ ├── otherdir
│ │ │ └── .gitkeep
│ │ ├── outer
│ │ ├── subdir
│ │ │ ├── gqlgen.yaml
│ │ │ └── inner
│ │ ├── unknownkeys.yml
│ │ └── unwalkable.yml
│ │ ├── defaultconfig
│ │ └── schema.graphql
│ │ ├── enum
│ │ └── model.go
│ │ └── example.go
├── data.go
├── data_test.go
├── directive.go
├── directive_test.go
├── directives.gotpl
├── field.go
├── field.gotpl
├── field_test.go
├── generate.go
├── generated!.gotpl
├── input.gotpl
├── interface.go
├── interface.gotpl
├── object.go
├── object.gotpl
├── root_.gotpl
├── templates
│ ├── import.go
│ ├── import_test.go
│ ├── templates.go
│ ├── templates_test.go
│ ├── test.gotpl
│ ├── test_.gotpl
│ └── testdata
│ │ ├── a
│ │ └── bar
│ │ │ └── bar.go
│ │ ├── b
│ │ └── bar
│ │ │ └── bar.go
│ │ └── pkg_mismatch
│ │ └── turtles.go
├── testserver
│ ├── compliant-int
│ │ ├── compliant_int_test.go
│ │ ├── generated-compliant-strict
│ │ │ ├── models.go
│ │ │ ├── resolver.go
│ │ │ ├── schema.go
│ │ │ └── stub.go
│ │ ├── generated-default
│ │ │ ├── models.go
│ │ │ ├── resolver.go
│ │ │ ├── schema.go
│ │ │ └── stub.go
│ │ ├── gqlgen_compliant_strict.yml
│ │ ├── gqlgen_default.yml
│ │ └── schema.graphql
│ ├── empty.go
│ ├── followschema
│ │ ├── builtinscalar.generated.go
│ │ ├── builtinscalar.graphql
│ │ ├── bytes.go
│ │ ├── complexity.generated.go
│ │ ├── complexity.graphql
│ │ ├── complexity_test.go
│ │ ├── defaults.generated.go
│ │ ├── defaults.graphql
│ │ ├── defaults_test.go
│ │ ├── defer.generated.go
│ │ ├── defer.graphql
│ │ ├── directive.generated.go
│ │ ├── directive.graphql
│ │ ├── directive_test.go
│ │ ├── embedded.generated.go
│ │ ├── embedded.go
│ │ ├── embedded.graphql
│ │ ├── embedded_test.go
│ │ ├── enum.generated.go
│ │ ├── enum.graphql
│ │ ├── enums_test.go
│ │ ├── fields_order.generated.go
│ │ ├── fields_order.go
│ │ ├── fields_order.graphql
│ │ ├── fields_order_test.go
│ │ ├── generated_test.go
│ │ ├── gqlgen.yml
│ │ ├── input_test.go
│ │ ├── interfaces.generated.go
│ │ ├── interfaces.go
│ │ ├── interfaces.graphql
│ │ ├── interfaces_test.go
│ │ ├── introspection
│ │ │ └── it.go
│ │ ├── introspection_test.go
│ │ ├── invalid-packagename
│ │ │ └── invalid-identifier.go
│ │ ├── issue896.generated.go
│ │ ├── issue896.graphql
│ │ ├── loops.generated.go
│ │ ├── loops.graphql
│ │ ├── maps.generated.go
│ │ ├── maps.go
│ │ ├── maps.graphql
│ │ ├── maps_test.go
│ │ ├── middleware_test.go
│ │ ├── modelmethod_test.go
│ │ ├── models-gen.go
│ │ ├── models.go
│ │ ├── mutation_with_custom_scalar.generated.go
│ │ ├── mutation_with_custom_scalar.go
│ │ ├── mutation_with_custom_scalar.graphql
│ │ ├── mutation_with_custom_scalar_test.go
│ │ ├── nulls.generated.go
│ │ ├── nulls.graphql
│ │ ├── nulls_test.go
│ │ ├── otherpkg
│ │ │ └── model.go
│ │ ├── panics.generated.go
│ │ ├── panics.graphql
│ │ ├── panics_test.go
│ │ ├── prelude.generated.go
│ │ ├── primitive_objects.generated.go
│ │ ├── primitive_objects.graphql
│ │ ├── primitive_objects_test.go
│ │ ├── ptr_to_any.generated.go
│ │ ├── ptr_to_any.go
│ │ ├── ptr_to_any.graphql
│ │ ├── ptr_to_any_test.go
│ │ ├── ptr_to_ptr_input.generated.go
│ │ ├── ptr_to_ptr_input.go
│ │ ├── ptr_to_ptr_input.graphql
│ │ ├── ptr_to_ptr_input_test.go
│ │ ├── ptr_to_slice.generated.go
│ │ ├── ptr_to_slice.go
│ │ ├── ptr_to_slice.graphql
│ │ ├── ptr_to_slice_test.go
│ │ ├── recursive.go
│ │ ├── resolver.go
│ │ ├── response_extension_test.go
│ │ ├── root_.generated.go
│ │ ├── scalar_context.generated.go
│ │ ├── scalar_context.go
│ │ ├── scalar_context.graphql
│ │ ├── scalar_context_test.go
│ │ ├── scalar_default.generated.go
│ │ ├── scalar_default.graphql
│ │ ├── scalar_default_test.go
│ │ ├── schema.generated.go
│ │ ├── schema.graphql
│ │ ├── skip-include.generated.go
│ │ ├── skip-include.graphql
│ │ ├── slices.generated.go
│ │ ├── slices.graphql
│ │ ├── slices_test.go
│ │ ├── stub.go
│ │ ├── subscription_test.go
│ │ ├── thirdparty.go
│ │ ├── time_test.go
│ │ ├── typefallback.generated.go
│ │ ├── typefallback.graphql
│ │ ├── typefallback_test.go
│ │ ├── useptr.generated.go
│ │ ├── useptr.graphql
│ │ ├── useptr_test.go
│ │ ├── v-ok.generated.go
│ │ ├── v-ok.go
│ │ ├── v-ok.graphql
│ │ ├── v-ok_test.go
│ │ ├── validtypes.generated.go
│ │ ├── validtypes.graphql
│ │ ├── validtypes_test.go
│ │ ├── variadic.generated.go
│ │ ├── variadic.go
│ │ ├── variadic.graphql
│ │ ├── weird_type_cases.generated.go
│ │ ├── weird_type_cases.graphql
│ │ ├── wrapped_type.generated.go
│ │ ├── wrapped_type.go
│ │ ├── wrapped_type.graphql
│ │ └── wrapped_type_test.go
│ ├── generated_test.go
│ ├── nullabledirectives
│ │ ├── directive.graphql
│ │ ├── directive_test.go
│ │ ├── generated
│ │ │ ├── directive.generated.go
│ │ │ ├── models
│ │ │ │ └── models-gen.go
│ │ │ ├── prelude.generated.go
│ │ │ ├── resolvers
│ │ │ │ └── resolver.go
│ │ │ └── root_.generated.go
│ │ ├── gqlgen.yml
│ │ └── stub.go
│ ├── singlefile
│ │ ├── builtinscalar.graphql
│ │ ├── bytes.go
│ │ ├── complexity.graphql
│ │ ├── complexity_test.go
│ │ ├── defaults.graphql
│ │ ├── defaults_test.go
│ │ ├── defer.graphql
│ │ ├── defer_test.go
│ │ ├── directive.graphql
│ │ ├── directive_test.go
│ │ ├── embedded.go
│ │ ├── embedded.graphql
│ │ ├── embedded_test.go
│ │ ├── enum.graphql
│ │ ├── enums_test.go
│ │ ├── fields_order.go
│ │ ├── fields_order.graphql
│ │ ├── fields_order_test.go
│ │ ├── generated.go
│ │ ├── generated_test.go
│ │ ├── gqlgen.yml
│ │ ├── input_test.go
│ │ ├── interfaces.go
│ │ ├── interfaces.graphql
│ │ ├── interfaces_test.go
│ │ ├── introspection
│ │ │ └── it.go
│ │ ├── introspection_test.go
│ │ ├── invalid-packagename
│ │ │ └── invalid-identifier.go
│ │ ├── issue896.graphql
│ │ ├── loops.graphql
│ │ ├── maps.go
│ │ ├── maps.graphql
│ │ ├── maps_test.go
│ │ ├── middleware_test.go
│ │ ├── modelmethod_test.go
│ │ ├── models-gen.go
│ │ ├── models.go
│ │ ├── mutation_with_custom_scalar.go
│ │ ├── mutation_with_custom_scalar.graphql
│ │ ├── mutation_with_custom_scalar_test.go
│ │ ├── nulls.graphql
│ │ ├── nulls_test.go
│ │ ├── otherpkg
│ │ │ └── model.go
│ │ ├── panics.graphql
│ │ ├── panics_test.go
│ │ ├── primitive_objects.graphql
│ │ ├── primitive_objects_test.go
│ │ ├── ptr_to_any.go
│ │ ├── ptr_to_any.graphql
│ │ ├── ptr_to_any_test.go
│ │ ├── ptr_to_ptr_input.go
│ │ ├── ptr_to_ptr_input.graphql
│ │ ├── ptr_to_ptr_input_test.go
│ │ ├── ptr_to_slice.go
│ │ ├── ptr_to_slice.graphql
│ │ ├── ptr_to_slice_test.go
│ │ ├── recursive.go
│ │ ├── resolver.go
│ │ ├── response_extension_test.go
│ │ ├── scalar_context.go
│ │ ├── scalar_context.graphql
│ │ ├── scalar_context_test.go
│ │ ├── scalar_default.graphql
│ │ ├── scalar_default_test.go
│ │ ├── schema.graphql
│ │ ├── skip-include.graphql
│ │ ├── skip_include_test.go
│ │ ├── slices.graphql
│ │ ├── slices_test.go
│ │ ├── stub.go
│ │ ├── subscription_test.go
│ │ ├── thirdparty.go
│ │ ├── time_test.go
│ │ ├── typefallback.graphql
│ │ ├── typefallback_test.go
│ │ ├── useptr.graphql
│ │ ├── useptr_test.go
│ │ ├── v-ok.go
│ │ ├── v-ok.graphql
│ │ ├── v-ok_test.go
│ │ ├── validtypes.graphql
│ │ ├── validtypes_test.go
│ │ ├── variadic.go
│ │ ├── variadic.graphql
│ │ ├── variadic_test.go
│ │ ├── weird_type_cases.graphql
│ │ ├── wrapped_type.go
│ │ ├── wrapped_type.graphql
│ │ └── wrapped_type_test.go
│ └── usefunctionsyntaxforexecutioncontext
│ │ ├── directive.go
│ │ ├── generated.go
│ │ ├── generated_test.go
│ │ ├── gqlgen.yml
│ │ ├── models-gen.go
│ │ ├── resolver.go
│ │ ├── stub.go
│ │ └── test.graphql
├── type.go
├── type.gotpl
└── util.go
├── complexity
├── complexity.go
└── complexity_test.go
├── docs
├── build.sh
├── config.yml
├── content
│ ├── _introduction.md
│ ├── config.md
│ ├── feature-comparison.md
│ ├── getting-started.md
│ ├── introduction.md
│ ├── recipes
│ │ ├── authentication.md
│ │ ├── cors.md
│ │ ├── enum.md
│ │ ├── extra_fields.md
│ │ ├── federation.md
│ │ ├── gin.md
│ │ ├── migration-0.11.md
│ │ ├── modelgen-hook.md
│ │ └── subscriptions.md
│ └── reference
│ │ ├── apq.md
│ │ ├── changesets.md
│ │ ├── complexity.md
│ │ ├── dataloaders.md
│ │ ├── directives.md
│ │ ├── errors.md
│ │ ├── field-collection.md
│ │ ├── file-upload.md
│ │ ├── introspection.md
│ │ ├── model-generation.md
│ │ ├── name-collision.md
│ │ ├── plugins.md
│ │ ├── resolvers.md
│ │ └── scalars.md
├── layouts
│ ├── 404.html
│ ├── _default
│ │ ├── baseof.html
│ │ └── single.html
│ ├── index.html
│ ├── partials
│ │ ├── gqlgen.svg
│ │ ├── sidebar.html
│ │ ├── version-banner.html
│ │ └── version-switcher.html
│ └── sitemap.xml
├── readme.md
└── static
│ ├── external-link-alt.svg
│ ├── favicon.ico
│ ├── main.css
│ ├── main.js
│ ├── request_anatomy.png
│ ├── schema_layout.png
│ └── syntax.css
├── go.mod
├── go.sum
├── graphql
├── any.go
├── bool.go
├── bool_test.go
├── cache.go
├── cache_test.go
├── coercion.go
├── coercion_test.go
├── context_field.go
├── context_field_test.go
├── context_operation.go
├── context_operation_test.go
├── context_path.go
├── context_path_test.go
├── context_response.go
├── context_response_test.go
├── context_root_field.go
├── context_root_field_test.go
├── deferred.go
├── duration.go
├── duration_test.go
├── errcode
│ └── codes.go
├── error.go
├── executable_schema.go
├── executable_schema_mock.go
├── executor
│ ├── executor.go
│ ├── executor_test.go
│ ├── extensions.go
│ └── testexecutor
│ │ └── testexecutor.go
├── fieldset.go
├── fieldset_test.go
├── float.go
├── float_test.go
├── handler.go
├── handler
│ ├── apollofederatedtracingv1
│ │ ├── generated
│ │ │ ├── apollo_trace.pb.go
│ │ │ └── apollo_trace.proto
│ │ ├── logger
│ │ │ ├── logger.go
│ │ │ └── logger_test.go
│ │ ├── tracing.go
│ │ ├── tracing_test.go
│ │ └── tree_builder.go
│ ├── apollotracing
│ │ ├── tracer.go
│ │ └── tracer_test.go
│ ├── debug
│ │ └── tracer.go
│ ├── extension
│ │ ├── apq.go
│ │ ├── apq_test.go
│ │ ├── complexity.go
│ │ ├── complexity_test.go
│ │ ├── introspection.go
│ │ └── introspection_test.go
│ ├── lru
│ │ └── lru.go
│ ├── server.go
│ ├── server_test.go
│ ├── testserver
│ │ └── testserver.go
│ └── transport
│ │ ├── error.go
│ │ ├── headers.go
│ │ ├── headers_test.go
│ │ ├── http_form_multipart.go
│ │ ├── http_form_multipart_test.go
│ │ ├── http_form_urlencode_test.go
│ │ ├── http_form_urlencoded.go
│ │ ├── http_get.go
│ │ ├── http_get_test.go
│ │ ├── http_graphql.go
│ │ ├── http_graphql_test.go
│ │ ├── http_multipart_mixed.go
│ │ ├── http_multipart_mixed_test.go
│ │ ├── http_post.go
│ │ ├── http_post_test.go
│ │ ├── options.go
│ │ ├── options_test.go
│ │ ├── reader.go
│ │ ├── reader_test.go
│ │ ├── sse.go
│ │ ├── sse_test.go
│ │ ├── util.go
│ │ ├── websocket.go
│ │ ├── websocket_close_reason.go
│ │ ├── websocket_graphql_transport_ws.go
│ │ ├── websocket_graphqlws.go
│ │ ├── websocket_init.go
│ │ ├── websocket_resolver_error.go
│ │ ├── websocket_subprotocol.go
│ │ └── websocket_test.go
├── handler_test.go
├── id.go
├── id_test.go
├── input.go
├── int.go
├── int_test.go
├── introspection
│ ├── introspection.go
│ ├── query.go
│ ├── schema.go
│ ├── schema_test.go
│ ├── type.go
│ └── type_test.go
├── jsonw.go
├── jsonw_test.go
├── map.go
├── omittable.go
├── omittable_go123_test.go
├── omittable_go124_test.go
├── omittable_test.go
├── oneshot.go
├── playground
│ ├── altair_playground.go
│ ├── altair_playground_test.go
│ ├── apollo_sandbox_playground.go
│ ├── apollo_sandbox_playground_test.go
│ ├── helper_test.go
│ ├── playground.go
│ └── playground_test.go
├── recovery.go
├── response.go
├── root.go
├── stats.go
├── string.go
├── string_test.go
├── time.go
├── time_test.go
├── uint.go
├── uint_test.go
├── upload.go
├── uuid.go
├── uuid_test.go
└── version.go
├── handler
└── handler.go
├── init-templates
├── gqlgen.yml.gotmpl
└── schema.graphqls
├── integration
├── .gitignore
├── README.md
├── codegen.ts
├── graphql.config.yml
├── package-lock.json
├── package.json
├── server
│ ├── cmd
│ │ └── integration
│ │ │ └── server.go
│ ├── generated.go
│ ├── gqlgen.yml
│ ├── models-go
│ │ ├── element.go
│ │ ├── generated.go
│ │ └── viewer.go
│ ├── remote_api
│ │ └── user.go
│ ├── resolver.go
│ ├── schema
│ │ ├── schema.graphql
│ │ ├── testomitempty.graphql
│ │ └── user.graphql
│ └── testomitempty
│ │ └── testmodel.go
├── src
│ ├── __test__
│ │ └── integration.spec.ts
│ ├── generated
│ │ ├── .gitignore
│ │ ├── fragment-masking.ts
│ │ ├── gql.ts
│ │ ├── graphql.ts
│ │ ├── index.ts
│ │ └── schema-expected.graphql
│ └── queries
│ │ ├── coercion.graphql
│ │ ├── complexity.graphql
│ │ ├── date.graphql
│ │ ├── error.graphql
│ │ ├── jsonEncoding.graphql
│ │ ├── path.graphql
│ │ └── viewer.graphql
└── tsconfig.json
├── internal
├── code
│ ├── alias.go
│ ├── alias_test.go
│ ├── compare.go
│ ├── compare_test.go
│ ├── imports.go
│ ├── imports_test.go
│ ├── packages.go
│ ├── packages_test.go
│ ├── testdata
│ │ ├── a
│ │ │ └── a.go
│ │ ├── b
│ │ │ └── b.go
│ │ ├── c
│ │ │ └── c.go
│ │ └── p
│ │ │ └── p.go
│ ├── util.go
│ └── util_test.go
├── imports
│ ├── prune.go
│ ├── prune_test.go
│ └── testdata
│ │ ├── unused.expected.go
│ │ └── unused.go
├── rewrite
│ ├── rewriter.go
│ ├── rewriter_test.go
│ └── testdata
│ │ └── example.go
└── tools.go
├── main.go
├── plugin
├── federation
│ ├── constants.go
│ ├── entity.go
│ ├── federation.go
│ ├── federation.gotpl
│ ├── federation_computedrequires_test.go
│ ├── federation_entityresolver_test.go
│ ├── federation_explicitrequires_test.go
│ ├── federation_test.go
│ ├── federation_use_function_syntax_for_execution_context_test.go
│ ├── fedruntime
│ │ └── runtime.go
│ ├── fieldset
│ │ ├── fieldset.go
│ │ └── fieldset_test.go
│ ├── readme.md
│ ├── requires.gotpl
│ ├── test_data
│ │ ├── model
│ │ │ └── federation.go
│ │ └── model2
│ │ │ └── federation.go
│ └── testdata
│ │ ├── allthethings
│ │ ├── generated
│ │ │ └── federation.go
│ │ ├── gqlgen.yml
│ │ ├── model
│ │ │ └── federation.go
│ │ └── schema.graphql
│ │ ├── computedrequires
│ │ ├── entity.resolvers.go
│ │ ├── errors.go
│ │ ├── generated
│ │ │ ├── exec.go
│ │ │ ├── federation.go
│ │ │ └── models
│ │ │ │ └── models.go
│ │ ├── gqlgen.yml
│ │ ├── main
│ │ │ └── server.go
│ │ ├── resolver.go
│ │ ├── schema.graphql
│ │ └── schema.resolvers.go
│ │ ├── entities
│ │ ├── nokey.graphql
│ │ └── nokey.yml
│ │ ├── entityinterfaces
│ │ ├── generated
│ │ │ ├── exec.go
│ │ │ ├── federation.go
│ │ │ └── models_gen.go
│ │ ├── interface.graphql
│ │ └── interface.yml
│ │ ├── entityresolver
│ │ ├── entity.resolvers.go
│ │ ├── generated
│ │ │ ├── errors.go
│ │ │ ├── exec.go
│ │ │ ├── federation.go
│ │ │ └── model
│ │ │ │ └── models.go
│ │ ├── gqlgen.yml
│ │ ├── resolver.go
│ │ ├── schema.graphql
│ │ └── schema.resolvers.go
│ │ ├── explicitrequires
│ │ ├── entity.resolvers.go
│ │ ├── generated
│ │ │ ├── errors.go
│ │ │ ├── exec.go
│ │ │ ├── federation.go
│ │ │ ├── federation.requires.go
│ │ │ └── models.go
│ │ ├── gqlgen.yml
│ │ ├── resolver.go
│ │ ├── schema.graphql
│ │ └── schema.resolvers.go
│ │ ├── federation2
│ │ ├── federation2.graphql
│ │ ├── federation2.yml
│ │ └── generated
│ │ │ └── federation.go
│ │ ├── interfaces
│ │ ├── extends.graphqls
│ │ ├── extends.yml
│ │ ├── key.graphqls
│ │ ├── key.yml
│ │ ├── unused_key.graphqls
│ │ └── unused_key.yml
│ │ ├── multi
│ │ ├── multi.graphqls
│ │ └── multi.yml
│ │ ├── schema
│ │ ├── customquerytype.graphql
│ │ └── customquerytype.yml
│ │ └── usefunctionsyntaxforexecutioncontext
│ │ ├── entity.resolvers.go
│ │ ├── generated
│ │ ├── errors.go
│ │ ├── exec.go
│ │ ├── federation.go
│ │ └── model
│ │ │ └── models.go
│ │ ├── gqlgen.yml
│ │ ├── resolver.go
│ │ ├── schema.graphql
│ │ └── schema.resolvers.go
├── modelgen
│ ├── internal
│ │ └── extrafields
│ │ │ └── types.go
│ ├── models.go
│ ├── models.gotpl
│ ├── models_test.go
│ ├── out
│ │ ├── existing.go
│ │ ├── generated.go
│ │ └── generated_omit_root_models.go
│ ├── out_enable_model_json_omitempty_tag_false
│ │ ├── existing.go
│ │ └── generated.go
│ ├── out_enable_model_json_omitempty_tag_false_omitempty_tag_false_omitzero_tag_nil
│ │ └── generated.go
│ ├── out_enable_model_json_omitempty_tag_false_omitempty_tag_false_omitzero_tag_true
│ │ └── generated.go
│ ├── out_enable_model_json_omitempty_tag_false_omitzero_tag_false
│ │ ├── existing.go
│ │ └── generated.go
│ ├── out_enable_model_json_omitempty_tag_false_omitzero_tag_nil
│ │ ├── existing.go
│ │ └── generated.go
│ ├── out_enable_model_json_omitempty_tag_false_omitzero_tag_true
│ │ ├── existing.go
│ │ └── generated.go
│ ├── out_enable_model_json_omitempty_tag_nil
│ │ ├── existing.go
│ │ └── generated.go
│ ├── out_enable_model_json_omitempty_tag_true
│ │ ├── existing.go
│ │ └── generated.go
│ ├── out_enable_model_json_omitzero_tag_false
│ │ ├── existing.go
│ │ └── generated.go
│ ├── out_enable_model_json_omitzero_tag_nil
│ │ ├── existing.go
│ │ └── generated.go
│ ├── out_enable_model_json_omitzero_tag_true
│ │ ├── existing.go
│ │ └── generated.go
│ ├── out_nullable_input_omittable
│ │ ├── existing.go
│ │ └── generated.go
│ ├── out_omit_resolver_fields
│ │ └── generated.go
│ ├── out_struct_pointers
│ │ ├── existing.go
│ │ └── generated.go
│ ├── testdata
│ │ ├── customModelTemplate.gotpl
│ │ ├── gqlgen.yml
│ │ ├── gqlgen_custom_model_template.yml
│ │ ├── gqlgen_enable_model_json_omitempty_tag_false.yml
│ │ ├── gqlgen_enable_model_json_omitempty_tag_false_omitzero_tag_false.yml
│ │ ├── gqlgen_enable_model_json_omitempty_tag_false_omitzero_tag_nil.yml
│ │ ├── gqlgen_enable_model_json_omitempty_tag_false_omitzero_tag_true.yml
│ │ ├── gqlgen_enable_model_json_omitempty_tag_nil.yml
│ │ ├── gqlgen_enable_model_json_omitempty_tag_true.yml
│ │ ├── gqlgen_enable_model_json_omitzero_tag_false.yml
│ │ ├── gqlgen_enable_model_json_omitzero_tag_nil.yml
│ │ ├── gqlgen_enable_model_json_omitzero_tag_true.yml
│ │ ├── gqlgen_nullable_input_omittable.yml
│ │ ├── gqlgen_omit_resolver_fields.yml
│ │ ├── gqlgen_omit_root_models.yml
│ │ ├── gqlgen_struct_field_pointers.yml
│ │ ├── schema.graphql
│ │ ├── schema_omit_resolver_fields.graphql
│ │ └── schema_omit_root_models.graphql
│ └── types.go
├── plugin.go
├── resolvergen
│ ├── resolver.go
│ ├── resolver.gotpl
│ ├── resolver_test.go
│ └── testdata
│ │ ├── filetemplate
│ │ ├── gqlgen.yml
│ │ └── out
│ │ │ ├── model.go
│ │ │ ├── resolver.go
│ │ │ ├── schema.custom.go
│ │ │ └── schema.custom.go.txt
│ │ ├── followschema
│ │ ├── gqlgen.yml
│ │ └── out
│ │ │ ├── model.go
│ │ │ ├── resolver.go
│ │ │ ├── schema.resolvers.go
│ │ │ └── schema.resolvers.go.txt
│ │ ├── invalid_model_path
│ │ └── gqlgen.yml
│ │ ├── omit_template_comment
│ │ ├── gqlgen.yml
│ │ └── out
│ │ │ ├── resolver.go
│ │ │ └── schema.resolvers.go
│ │ ├── resolver_implementor
│ │ ├── gqlgen.yml
│ │ └── out
│ │ │ ├── model.go
│ │ │ ├── resolver.go
│ │ │ └── schema.resolvers.go
│ │ ├── resolvertemplate
│ │ ├── customResolverTemplate.gotpl
│ │ ├── gqlgen.yml
│ │ └── out
│ │ │ ├── resolver.go
│ │ │ └── schema.resolvers.go
│ │ ├── return_values
│ │ ├── gqlgen.yml
│ │ ├── ignored.go
│ │ ├── model.go
│ │ ├── resolvers.go
│ │ ├── return_values_test.go
│ │ └── schema.graphqls
│ │ ├── schema.graphql
│ │ ├── singlefile
│ │ ├── gqlgen.yml
│ │ └── out
│ │ │ ├── model.go
│ │ │ └── resolver.go
│ │ └── singlefile_preserve
│ │ ├── gqlgen.yml
│ │ └── out
│ │ ├── model.go
│ │ └── resolver.go
├── servergen
│ ├── server.go
│ └── server.gotpl
└── stubgen
│ ├── stubs.go
│ └── stubs.gotpl
└── testdata
├── gomod-with-leading-comments.mod
└── gqlgen.go
/.chglog/config.yml:
--------------------------------------------------------------------------------
1 | style: github
2 | template: CHANGELOG-full-history.tpl.md
3 | info:
4 | title: CHANGELOG
5 | repository_url: https://github.com/99designs/gqlgen
6 | options:
7 | commits:
8 | # filters:
9 | # Type: []
10 | commit_groups:
11 | # title_maps: []
12 | header:
13 | pattern: "^(.*)$"
14 | pattern_maps:
15 | - Subject
16 | notes:
17 | keywords:
18 | - BREAKING CHANGE
--------------------------------------------------------------------------------
/.dockerignore:
--------------------------------------------------------------------------------
1 | /**/node_modules
2 | /codegen/tests/gen
3 | /vendor
4 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | end_of_line = lf
5 | charset = utf-8
6 | trim_trailing_whitespace = true
7 | insert_final_newline = true
8 | indent_style = space
9 | indent_size = 4
10 |
11 | [*.{go,gotpl}]
12 | indent_style = tab
13 |
14 | [*.yml]
15 | indent_size = 2
16 |
17 | # These often end up with go code inside, so lets keep tabs
18 | [*.{html,md}]
19 | indent_size = 2
20 | indent_style = tab
21 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | /codegen/templates/data.go linguist-generated
2 | /_examples/dataloader/*_gen.go linguist-generated
3 | generated.go linguist-generated
4 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ### What happened?
2 |
3 | ### What did you expect?
4 |
5 | ### Minimal graphql.schema and models to reproduce
6 |
7 | ### versions
8 | - `go run github.com/99designs/gqlgen version`?
9 | - `go version`?
10 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | Describe your PR and link to any relevant issues.
2 |
3 | I have:
4 | - [ ] Added tests covering the bug / feature (see [testing](https://github.com/99designs/gqlgen/blob/master/TESTING.md))
5 | - [ ] Updated any relevant documentation (see [docs](https://github.com/99designs/gqlgen/tree/master/docs/content))
6 |
--------------------------------------------------------------------------------
/.github/workflows/GOVERSION.txt:
--------------------------------------------------------------------------------
1 | 1.23.0
2 |
--------------------------------------------------------------------------------
/.github/workflows/check-federation:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -euo pipefail
4 | export GO111MODULE=on
5 | cd _examples/federation
6 |
7 | ./start.sh &
8 |
9 | sleep 5
10 | curl -s --connect-timeout 5 \
11 | --max-time 10 \
12 | --retry 5 \
13 | --retry-delay 5 \
14 | --retry-max-time 40 \
15 | --retry-connrefused \
16 | localhost:4003 > /dev/null
17 |
18 | sleep 1
19 |
20 | echo "### running jest integration spec"
21 | export NODE_OPTIONS="--experimental-vm-modules"
22 | npx jest --color
23 |
24 |
--------------------------------------------------------------------------------
/.github/workflows/check-fmt:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -exuo pipefail
4 | export GO111MODULE=on
5 | export GOTOOLCHAIN=local
6 | go fmt ./...
7 | cd _examples && go fmt ./...
8 | if [[ $(git --no-pager diff) ]] ; then
9 | echo "you need to run "go fmt" and commit the changes"
10 | git --no-pager diff
11 | exit 1
12 | fi
13 |
--------------------------------------------------------------------------------
/.github/workflows/check-generate:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -exuo pipefail
3 | export GO111MODULE=on
4 | echo Generating code
5 | go generate ./...
6 | if [[ $(git --no-pager diff) ]] ; then
7 | echo "you need to run "go generate ./..." and commit the changes"
8 | git --no-pager diff
9 | exit 1
10 | fi
11 |
--------------------------------------------------------------------------------
/.github/workflows/check-gomod.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -euo pipefail
4 |
5 | export GOVERSION="$(cat GOVERSION.txt)"
6 | export GOTOOLCHAIN="go${GOVERSION}"
7 | go get go@${GOVERSION} || true
8 | go get toolchain@none || true
9 | go mod tidy || true
10 |
11 | STATUS=$( git status --porcelain go.mod go.sum )
12 | if [ ! -z "$STATUS" ]; then
13 | echo "Running go mod tidy modified go.mod and/or go.sum"
14 | echo "Please run the following then make a git commit:"
15 | echo "go get go@${GOVERSION}"
16 | echo "go get toolchain@none"
17 | echo "go mod tidy"
18 | echo "export GOTOOLCHAIN=${GOTOOLCHAIN}"
19 | exit 1
20 | fi
21 | exit 0
--------------------------------------------------------------------------------
/.github/workflows/check-init:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -euo pipefail
4 | export GO111MODULE=on
5 | gqlgen_dir=$(pwd)
6 | cd $(mktemp -d)
7 | go mod init inittest
8 | printf '//go:build tools\npackage tools\nimport _ "github.com/99designs/gqlgen"' | gofmt > tools.go
9 | go mod tidy
10 | go mod edit -replace=github.com/99designs/gqlgen="$gqlgen_dir"
11 | go mod tidy
12 |
13 | if ! go run github.com/99designs/gqlgen init ; then
14 | echo "gqlgen init failed"
15 | exit 125
16 | fi
17 |
18 | if ! go run github.com/99designs/gqlgen generate ; then
19 | echo "gqlgen generate failed"
20 | exit 125
21 | fi
22 |
--------------------------------------------------------------------------------
/.github/workflows/check-integration:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -euo pipefail
4 | export GO111MODULE=on
5 | cd integration
6 |
7 | date
8 | go run ./server/cmd/integration/server.go &
9 |
10 | sleep 5
11 | curl -s --connect-timeout 5 \
12 | --max-time 10 \
13 | --retry 5 \
14 | --retry-delay 5 \
15 | --retry-max-time 40 \
16 | --retry-connrefused \
17 | localhost:8080 > /dev/null
18 |
19 |
20 | echo "### validating introspected schema"
21 | npm run gen
22 |
23 | if ! diff <(tail -n +3 src/generated/schema-expected.graphql) <(tail -n +3 src/generated/schema-fetched.graphql) ; then
24 | echo "The expected schema has changed, you need to update schema-expected.graphql with any expected changes"
25 | exit 1
26 | fi
27 |
28 | echo "### running integration spec"
29 | npm run test
30 |
--------------------------------------------------------------------------------
/.github/workflows/gomod-clean.yml:
--------------------------------------------------------------------------------
1 | name: GoModVersion
2 | on:
3 | push:
4 | branches:
5 | - master
6 | pull_request:
7 | types: [ opened, synchronize ]
8 | env:
9 | GOTOOLCHAIN: local
10 | # When a new revision is pushed to a PR, cancel all in-progress CI runs for that
11 | # PR. See https://docs.github.com/en/actions/using-jobs/using-concurrency
12 | concurrency:
13 | group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
14 | cancel-in-progress: true
15 | jobs:
16 | gomodclean:
17 | strategy:
18 | matrix:
19 | go: ["1.23"]
20 | runs-on: ubuntu-latest
21 | steps:
22 | - uses: actions/checkout@v4
23 | - uses: actions/setup-go@v5
24 | with:
25 | go-version: ${{ matrix.go }}
26 | - run: .github/workflows/check-fmt
27 |
--------------------------------------------------------------------------------
/.github/workflows/report.yml:
--------------------------------------------------------------------------------
1 | name: test report
2 | on:
3 | workflow_run:
4 | workflows: ["Test"]
5 | types:
6 | - completed
7 |
8 | permissions:
9 | checks: write
10 |
11 | jobs:
12 | checks:
13 | runs-on: ubuntu-latest
14 | steps:
15 | - name: Download Test Report
16 | uses: dawidd6/action-download-artifact@v10
17 | with:
18 | name: junit-test-results
19 | workflow: ${{ github.event.workflow.id }}
20 | run_id: ${{ github.event.workflow_run.id }}
21 | - name: Publish Test Report
22 | uses: mikepenz/action-junit-report@v5
23 | with:
24 | commit: ${{github.event.workflow_run.head_sha}}
25 | report_paths: '**/*.xml'
26 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /vendor
2 | /docs/public
3 | /docs/.hugo_build.lock
4 | /_examples/chat/node_modules
5 | /integration/node_modules
6 | /integration/schema-fetched.graphql
7 | /_examples/chat/package-lock.json
8 | /_examples/federation/package-lock.json
9 | /_examples/federation/node_modules
10 | /codegen/gen
11 | /gen
12 |
13 | /.vscode
14 | .idea/
15 | *.test
16 | *.out
17 | gqlgen
18 | *.exe
19 |
20 | node_modules
21 |
22 | # generated files
23 | /api/testdata/default/graph/generated.go
24 | /api/testdata/federation2/graph/federation.go
25 | /api/testdata/federation2/graph/generated.go
--------------------------------------------------------------------------------
/RELEASE-CHECKLIST.md:
--------------------------------------------------------------------------------
1 | # When gqlgen gets released, the following things need to happen
2 | Assuming the next version is $NEW_VERSION=v0.16.0 or something like that.
3 |
4 | 1. Run the https://github.com/99designs/gqlgen/blob/master/bin/release:
5 | ```
6 | ./bin/release $NEW_VERSION
7 | ```
8 | 2. git-chglog -o CHANGELOG.md
9 | 3. go generate ./...
10 | 4. git commit and push the CHANGELOG.md
11 | 5. Go to https://github.com/99designs/gqlgen/releases and draft new release, autogenerate the release notes, and Create a discussion for this release
12 | 6. Comment on the release discussion with any really important notes (breaking changes)
13 |
14 | I used https://github.com/git-chglog/git-chglog to automate the changelog maintenance process for now. We could just as easily use go releaser to make the whole thing automated.
15 |
--------------------------------------------------------------------------------
/_examples/chat/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 |
6 | # testing
7 | /coverage
8 | /corpus
9 |
10 | # production
11 | /build
12 |
13 | # misc
14 | .DS_Store
15 | .env.local
16 | .env.development.local
17 | .env.test.local
18 | .env.production.local
19 |
20 | npm-debug.log*
21 | yarn-debug.log*
22 | yarn-error.log*
23 |
--------------------------------------------------------------------------------
/_examples/chat/.gqlgen.yml:
--------------------------------------------------------------------------------
1 | models:
2 | Chatroom:
3 | model: github.com/99designs/gqlgen/_examples/chat.Chatroom
4 |
--------------------------------------------------------------------------------
/_examples/chat/models_gen.go:
--------------------------------------------------------------------------------
1 | // Code generated by github.com/99designs/gqlgen, DO NOT EDIT.
2 |
3 | package chat
4 |
5 | import (
6 | "time"
7 | )
8 |
9 | type Message struct {
10 | ID string `json:"id"`
11 | Text string `json:"text"`
12 | CreatedBy string `json:"createdBy"`
13 | CreatedAt time.Time `json:"createdAt"`
14 | Subscription *Subscription `json:"subscription"`
15 | }
16 |
17 | type Mutation struct {
18 | }
19 |
20 | type Query struct {
21 | }
22 |
23 | type Subscription struct {
24 | }
25 |
--------------------------------------------------------------------------------
/_examples/chat/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | React App
8 |
9 |
10 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/_examples/chat/schema.graphql:
--------------------------------------------------------------------------------
1 | type Chatroom {
2 | name: String!
3 | messages: [Message!]!
4 | subscription: Subscription!
5 | }
6 |
7 | type Message {
8 | id: ID!
9 | text: String!
10 | createdBy: String!
11 | createdAt: Time!
12 | subscription: Subscription!
13 | }
14 |
15 | type Query {
16 | room(name: String!): Chatroom
17 | }
18 |
19 | type Mutation {
20 | post(text: String!, username: String!, roomName: String!): Message!
21 | }
22 |
23 | type Subscription {
24 | messageAdded(roomName: String!): Message!
25 | }
26 |
27 | scalar Time
28 |
29 | directive @user(username: String!) on SUBSCRIPTION
30 |
--------------------------------------------------------------------------------
/_examples/chat/src/react-app-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/_examples/chat/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": [
5 | "dom",
6 | "dom.iterable",
7 | "esnext"
8 | ],
9 | "allowJs": true,
10 | "skipLibCheck": true,
11 | "esModuleInterop": true,
12 | "allowSyntheticDefaultImports": true,
13 | "strict": true,
14 | "forceConsistentCasingInFileNames": true,
15 | "module": "esnext",
16 | "moduleResolution": "node",
17 | "resolveJsonModule": true,
18 | "isolatedModules": true,
19 | "noEmit": true,
20 | "jsx": "preserve"
21 | },
22 | "include": [
23 | "src"
24 | ]
25 | }
26 |
--------------------------------------------------------------------------------
/_examples/config/.gqlgen.yml:
--------------------------------------------------------------------------------
1 | # .gqlgen.yml _examples
2 | #
3 | # Refer to https://gqlgen.com/config/
4 | # for detailed .gqlgen.yml documentation.
5 |
6 | schema: "*.graphql"
7 | exec:
8 | filename: generated.go
9 | model:
10 | filename: models_gen.go
11 | resolver:
12 | type: Resolver
13 | layout: follow-schema
14 | dir: .
15 |
16 | models:
17 | Todo: # Object
18 | fields:
19 | text:
20 | fieldName: Description # Field
21 | NewTodo: # Input
22 | fields:
23 | userId:
24 | fieldName: UserID # Field
25 |
--------------------------------------------------------------------------------
/_examples/config/model.go:
--------------------------------------------------------------------------------
1 | package config
2 |
3 | import "fmt"
4 |
5 | type User struct {
6 | ID string
7 | FirstName, LastName string
8 | Role UserRole
9 | }
10 |
11 | func (user *User) FullName() string {
12 | return fmt.Sprintf("%s %s", user.FirstName, user.LastName)
13 | }
14 |
15 | type UserRole struct {
16 | RoleName string
17 | }
18 |
--------------------------------------------------------------------------------
/_examples/config/models_gen.go:
--------------------------------------------------------------------------------
1 | // Code generated by github.com/99designs/gqlgen, DO NOT EDIT.
2 |
3 | package config
4 |
5 | type Mutation struct {
6 | }
7 |
8 | type NewTodo struct {
9 | Text string `json:"text"`
10 | UserID string `json:"userId"`
11 | }
12 |
13 | type Query struct {
14 | }
15 |
16 | type Todo struct {
17 | ID string `json:"id"`
18 | DatabaseID int `json:"databaseId"`
19 | Description string `json:"text"`
20 | Done bool `json:"done"`
21 | User *User `json:"user"`
22 | Query *Query `json:"query"`
23 | Mutation *Mutation `json:"mutation"`
24 | }
25 |
--------------------------------------------------------------------------------
/_examples/config/resolver.go:
--------------------------------------------------------------------------------
1 | //go:generate go run ../../testdata/gqlgen.go
2 |
3 | package config
4 |
5 | func New() Config {
6 | c := Config{
7 | Resolvers: &Resolver{
8 | todos: []*Todo{
9 | {DatabaseID: 1, Description: "A todo not to forget", Done: false},
10 | {DatabaseID: 2, Description: "This is the most important", Done: false},
11 | {DatabaseID: 3, Description: "Please do this or else", Done: false},
12 | },
13 | nextID: 3,
14 | },
15 | }
16 | return c
17 | }
18 |
19 | type Resolver struct {
20 | todos []*Todo
21 | nextID int
22 | }
23 |
--------------------------------------------------------------------------------
/_examples/config/schema.graphql:
--------------------------------------------------------------------------------
1 | directive @goModel(
2 | model: String
3 | models: [String!]
4 | ) on OBJECT | INPUT_OBJECT | SCALAR | ENUM | INTERFACE | UNION
5 | directive @goField(
6 | forceResolver: Boolean
7 | name: String
8 | omittable: Boolean
9 | type: String
10 | ) on INPUT_FIELD_DEFINITION | FIELD_DEFINITION
11 |
12 | type Query {
13 | todos: [Todo!]!
14 | }
15 |
16 | type Mutation {
17 | createTodo(input: NewTodo!): Todo!
18 | }
19 |
--------------------------------------------------------------------------------
/_examples/config/server/server.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "log"
5 | "net/http"
6 |
7 | todo "github.com/99designs/gqlgen/_examples/config"
8 | "github.com/99designs/gqlgen/graphql/handler"
9 | "github.com/99designs/gqlgen/graphql/handler/transport"
10 | "github.com/99designs/gqlgen/graphql/playground"
11 | )
12 |
13 | func main() {
14 | srv := handler.New(
15 | todo.NewExecutableSchema(todo.New()),
16 | )
17 | srv.AddTransport(transport.GET{})
18 | srv.AddTransport(transport.POST{})
19 |
20 | http.Handle("/", playground.Handler("Todo", "/query"))
21 | http.Handle("/query", srv)
22 | log.Fatal(http.ListenAndServe(":8081", nil))
23 | }
24 |
--------------------------------------------------------------------------------
/_examples/config/todo.graphql:
--------------------------------------------------------------------------------
1 | type Todo {
2 | id: ID! @goField(forceResolver: true)
3 | databaseId: Int!
4 | text: String!
5 | done: Boolean!
6 | user: User!
7 | query: Query!
8 | mutation: Mutation!
9 | }
10 |
11 | input NewTodo {
12 | text: String!
13 | userId: String!
14 | }
15 |
--------------------------------------------------------------------------------
/_examples/config/todo.resolvers.go:
--------------------------------------------------------------------------------
1 | package config
2 |
3 | // This file will be automatically regenerated based on the schema, any resolver implementations
4 | // will be copied through when generating and any unknown code will be moved to the end.
5 | // Code generated by github.com/99designs/gqlgen version v0.17.73-dev
6 |
7 | import (
8 | "context"
9 | "fmt"
10 | )
11 |
12 | // ID is the resolver for the id field.
13 | func (r *todoResolver) ID(ctx context.Context, obj *Todo) (string, error) {
14 | if obj.ID != "" {
15 | return obj.ID, nil
16 | }
17 |
18 | obj.ID = fmt.Sprintf("TODO:%d", obj.DatabaseID)
19 |
20 | return obj.ID, nil
21 | }
22 |
23 | // Todo returns TodoResolver implementation.
24 | func (r *Resolver) Todo() TodoResolver { return &todoResolver{r} }
25 |
26 | type todoResolver struct{ *Resolver }
27 |
--------------------------------------------------------------------------------
/_examples/config/user.graphql:
--------------------------------------------------------------------------------
1 | type User
2 | @goModel(model:"github.com/99designs/gqlgen/_examples/config.User") {
3 | id: ID!
4 | name: String! @goField(name:"FullName")
5 | role: role!
6 | }
7 |
8 | type role
9 | @goModel(model:"github.com/99designs/gqlgen/_examples/config.UserRole") {
10 | name: String!
11 | }
12 |
--------------------------------------------------------------------------------
/_examples/config/user.resolvers.go:
--------------------------------------------------------------------------------
1 | package config
2 |
3 | // This file will be automatically regenerated based on the schema, any resolver implementations
4 | // will be copied through when generating and any unknown code will be moved to the end.
5 | // Code generated by github.com/99designs/gqlgen version v0.17.73-dev
6 |
7 | import (
8 | "context"
9 | )
10 |
11 | // Name is the resolver for the name field.
12 | func (r *roleResolver) Name(ctx context.Context, obj *UserRole) (string, error) {
13 | if obj == nil {
14 | return "", nil
15 | }
16 | return obj.RoleName, nil
17 | }
18 |
19 | // Role returns RoleResolver implementation.
20 | func (r *Resolver) Role() RoleResolver { return &roleResolver{r} }
21 |
22 | type roleResolver struct{ *Resolver }
23 |
--------------------------------------------------------------------------------
/_examples/dataloader/.gqlgen.yml:
--------------------------------------------------------------------------------
1 | models:
2 | Order:
3 | model: github.com/99designs/gqlgen/_examples/dataloader.Order
4 | Customer:
5 | model: github.com/99designs/gqlgen/_examples/dataloader.Customer
6 |
--------------------------------------------------------------------------------
/_examples/dataloader/models_gen.go:
--------------------------------------------------------------------------------
1 | // Code generated by github.com/99designs/gqlgen, DO NOT EDIT.
2 |
3 | package dataloader
4 |
5 | type Address struct {
6 | ID int `json:"id"`
7 | Street string `json:"street"`
8 | Country string `json:"country"`
9 | }
10 |
11 | type Item struct {
12 | Name string `json:"name"`
13 | }
14 |
15 | type Query struct {
16 | }
17 |
--------------------------------------------------------------------------------
/_examples/dataloader/readme.md:
--------------------------------------------------------------------------------
1 | ### dataloader
2 |
3 | This example uses [dataloaden](https://github.com/vektah/dataloaden) to avoiding n+1 queries.
4 |
5 |
6 | There is also [nicksrandall/dataloader](https://github.com/nicksrandall/dataloader) if you wanted to avoid
7 | doing more codegeneration.
8 |
--------------------------------------------------------------------------------
/_examples/dataloader/schema.graphql:
--------------------------------------------------------------------------------
1 | type Query {
2 | customers: [Customer!]
3 |
4 | # these methods are here to test code generation of nested arrays
5 | torture1d(customerIds: [Int!]): [Customer!]
6 | torture2d(customerIds: [[Int!]]): [[Customer!]]
7 | }
8 |
9 | type Customer {
10 | id: Int!
11 | name: String!
12 | address: Address
13 | orders: [Order!]
14 | }
15 |
16 | type Address {
17 | id: Int!
18 | street: String!
19 | country: String!
20 | }
21 |
22 | type Order {
23 | id: Int!
24 | date: Time!
25 | amount: Float!
26 | items: [Item!]
27 | }
28 |
29 | type Item {
30 | name: String!
31 | }
32 | scalar Time
33 |
--------------------------------------------------------------------------------
/_examples/dataloader/server/server.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "log"
5 | "net/http"
6 |
7 | "github.com/99designs/gqlgen/_examples/dataloader"
8 | "github.com/99designs/gqlgen/graphql/handler"
9 | "github.com/99designs/gqlgen/graphql/handler/transport"
10 | "github.com/99designs/gqlgen/graphql/playground"
11 | )
12 |
13 | func main() {
14 | router := http.NewServeMux()
15 |
16 | srv := handler.New(
17 | dataloader.NewExecutableSchema(dataloader.Config{Resolvers: &dataloader.Resolver{}}),
18 | )
19 | srv.AddTransport(transport.GET{})
20 | srv.AddTransport(transport.POST{})
21 |
22 | router.Handle("/", playground.Handler("Dataloader", "/query"))
23 | router.Handle("/query", srv)
24 |
25 | log.Println("connect to http://localhost:8082/ for graphql playground")
26 | log.Fatal(http.ListenAndServe(":8082", dataloader.LoaderMiddleware(router)))
27 | }
28 |
--------------------------------------------------------------------------------
/_examples/deferexample/gqlgen.yml:
--------------------------------------------------------------------------------
1 | schema: "*.graphql"
2 |
3 | exec:
4 | filename: generated.go
5 |
6 | model:
7 | filename: models_gen.go
8 |
9 | resolver:
10 | layout: follow-schema
11 | dir: .
12 | filename_template: "{name}.resolvers.go"
13 |
14 | call_argument_directives_with_null: true
15 |
16 | models:
17 | ID:
18 | model:
19 | - github.com/99designs/gqlgen/graphql.ID
20 | Todo:
21 | fields:
22 | user:
23 | resolver: true
24 | extraFields:
25 | userID:
26 | type: "string"
27 |
--------------------------------------------------------------------------------
/_examples/deferexample/models_gen.go:
--------------------------------------------------------------------------------
1 | // Code generated by github.com/99designs/gqlgen, DO NOT EDIT.
2 |
3 | package deferexample
4 |
5 | type Mutation struct {
6 | }
7 |
8 | type NewTodo struct {
9 | Text string `json:"text"`
10 | UserID string `json:"userId"`
11 | }
12 |
13 | type Query struct {
14 | }
15 |
16 | type Todo struct {
17 | ID string `json:"id"`
18 | Text string `json:"text"`
19 | Done bool `json:"done"`
20 | User *User `json:"user"`
21 | userID string `json:"-"`
22 | }
23 |
24 | type User struct {
25 | ID string `json:"id"`
26 | Name string `json:"name"`
27 | }
28 |
--------------------------------------------------------------------------------
/_examples/deferexample/resolver.go:
--------------------------------------------------------------------------------
1 | package deferexample
2 |
3 | import "sync"
4 |
5 | type Resolver struct {
6 | mu sync.RWMutex
7 | todos []*Todo
8 | }
9 |
--------------------------------------------------------------------------------
/_examples/deferexample/schema.graphql:
--------------------------------------------------------------------------------
1 | # GraphQL schema example
2 | #
3 | # https://gqlgen.com/getting-started/
4 |
5 | type Todo {
6 | id: ID!
7 | text: String!
8 | done: Boolean!
9 | user: User!
10 | }
11 |
12 | type User {
13 | id: ID!
14 | name: String!
15 | }
16 |
17 | type Query {
18 | todos: [Todo!]!
19 | }
20 |
21 | input NewTodo {
22 | text: String!
23 | userId: String!
24 | }
25 |
26 | type Mutation {
27 | createTodo(input: NewTodo!): Todo!
28 | }
29 |
--------------------------------------------------------------------------------
/_examples/embedding/parent.graphqls:
--------------------------------------------------------------------------------
1 | extend type Query {
2 | parentdir: String!
3 | }
4 |
--------------------------------------------------------------------------------
/_examples/embedding/subdir/cfgdir/generate_in_gendir.yml:
--------------------------------------------------------------------------------
1 | schema:
2 | - schemadir/*.graphqls
3 | - ../*.graphqls
4 | - '*.graphqls'
5 | exec:
6 | dir: gendir
7 | filename: gendir/generated.go
8 | package: gendir
9 |
10 | federation:
11 | filename: gendir/federation_gen.go
12 | package: gendir
13 |
14 | model:
15 | filename: gendir/model.go
16 | package: gendir
--------------------------------------------------------------------------------
/_examples/embedding/subdir/cfgdir/generate_in_subdir.yml:
--------------------------------------------------------------------------------
1 | schema:
2 | - schemadir/*.graphqls
3 | - ../*.graphqls
4 | - '*.graphqls'
5 | exec:
6 | layout: follow-schema
7 | dir: .
8 | package: subdir
9 |
10 | federation:
11 | filename: federation_gen.go
12 | package: subdir
13 |
14 | model:
15 | filename: model.go
16 | package: subdir
--------------------------------------------------------------------------------
/_examples/embedding/subdir/federation_gen.go:
--------------------------------------------------------------------------------
1 | // Code generated by github.com/99designs/gqlgen, DO NOT EDIT.
2 |
3 | package subdir
4 |
5 | import (
6 | "context"
7 | "errors"
8 | "strings"
9 |
10 | "github.com/99designs/gqlgen/plugin/federation/fedruntime"
11 | )
12 |
13 | var (
14 | ErrUnknownType = errors.New("unknown type")
15 | ErrTypeNotFound = errors.New("type not found")
16 | )
17 |
18 | func (ec *executionContext) __resolve__service(ctx context.Context) (fedruntime.Service, error) {
19 | if ec.DisableIntrospection {
20 | return fedruntime.Service{}, errors.New("federated introspection disabled")
21 | }
22 |
23 | var sdl []string
24 |
25 | for _, src := range sources {
26 | if src.BuiltIn {
27 | continue
28 | }
29 | sdl = append(sdl, src.Input)
30 | }
31 |
32 | return fedruntime.Service{
33 | SDL: strings.Join(sdl, "\n"),
34 | }, nil
35 | }
36 |
--------------------------------------------------------------------------------
/_examples/embedding/subdir/gendir/federation_gen.go:
--------------------------------------------------------------------------------
1 | // Code generated by github.com/99designs/gqlgen, DO NOT EDIT.
2 |
3 | package gendir
4 |
5 | import (
6 | "context"
7 | "errors"
8 | "strings"
9 |
10 | "github.com/99designs/gqlgen/plugin/federation/fedruntime"
11 | )
12 |
13 | var (
14 | ErrUnknownType = errors.New("unknown type")
15 | ErrTypeNotFound = errors.New("type not found")
16 | )
17 |
18 | func (ec *executionContext) __resolve__service(ctx context.Context) (fedruntime.Service, error) {
19 | if ec.DisableIntrospection {
20 | return fedruntime.Service{}, errors.New("federated introspection disabled")
21 | }
22 |
23 | var sdl []string
24 |
25 | for _, src := range sources {
26 | if src.BuiltIn {
27 | continue
28 | }
29 | sdl = append(sdl, src.Input)
30 | }
31 |
32 | return fedruntime.Service{
33 | SDL: strings.Join(sdl, "\n"),
34 | }, nil
35 | }
36 |
--------------------------------------------------------------------------------
/_examples/embedding/subdir/gendir/model.go:
--------------------------------------------------------------------------------
1 | // Code generated by github.com/99designs/gqlgen, DO NOT EDIT.
2 |
3 | package gendir
4 |
5 | type Query struct {
6 | }
7 |
--------------------------------------------------------------------------------
/_examples/embedding/subdir/model.go:
--------------------------------------------------------------------------------
1 | // Code generated by github.com/99designs/gqlgen, DO NOT EDIT.
2 |
3 | package subdir
4 |
5 | type Query struct {
6 | }
7 |
--------------------------------------------------------------------------------
/_examples/embedding/subdir/schemadir/root.graphqls:
--------------------------------------------------------------------------------
1 | type Query {
2 | inSchemadir: String!
3 | }
4 |
--------------------------------------------------------------------------------
/_examples/embedding/subdir/subdir.graphqls:
--------------------------------------------------------------------------------
1 | extend type Query {
2 | subdir: String!
3 | }
4 |
--------------------------------------------------------------------------------
/_examples/enum/api/model.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | type InPackage bool
4 |
5 | const (
6 | InPackageTrue InPackage = true
7 | InPackageFalse InPackage = false
8 | )
9 |
--------------------------------------------------------------------------------
/_examples/enum/api/resolver.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | // This file will not be regenerated automatically.
4 | //
5 | // It serves as dependency injection for your app, add any dependencies you require here.
6 |
7 | type Resolver struct{}
8 |
--------------------------------------------------------------------------------
/_examples/enum/cmd/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "log"
5 | "net/http"
6 |
7 | "github.com/99designs/gqlgen/_examples/enum/api"
8 | "github.com/99designs/gqlgen/graphql/handler"
9 | "github.com/99designs/gqlgen/graphql/handler/transport"
10 | "github.com/99designs/gqlgen/graphql/playground"
11 | )
12 |
13 | func main() {
14 | srv := handler.New(
15 | api.NewExecutableSchema(api.Config{Resolvers: &api.Resolver{}}),
16 | )
17 |
18 | srv.AddTransport(transport.Options{})
19 | srv.AddTransport(transport.GET{})
20 | srv.AddTransport(transport.POST{})
21 |
22 | http.Handle("/", playground.Handler("Enum", "/query"))
23 | http.Handle("/query", srv)
24 | log.Fatal(http.ListenAndServe(":8081", nil))
25 | }
26 |
--------------------------------------------------------------------------------
/_examples/enum/gen.go:
--------------------------------------------------------------------------------
1 | //go:generate go run ../../testdata/gqlgen.go
2 |
3 | package enum
4 |
--------------------------------------------------------------------------------
/_examples/federation/accounts/graph/model/model.go:
--------------------------------------------------------------------------------
1 | package model
2 |
--------------------------------------------------------------------------------
/_examples/federation/accounts/graph/model/models_gen.go:
--------------------------------------------------------------------------------
1 | // Code generated by github.com/99designs/gqlgen, DO NOT EDIT.
2 |
3 | package model
4 |
5 | type EmailHost struct {
6 | ID string `json:"id"`
7 | Name string `json:"name"`
8 | }
9 |
10 | func (EmailHost) IsEntity() {}
11 |
12 | type Query struct {
13 | }
14 |
15 | type User struct {
16 | ID string `json:"id"`
17 | Host *EmailHost `json:"host"`
18 | Email string `json:"email"`
19 | Username string `json:"username"`
20 | }
21 |
22 | func (User) IsEntity() {}
23 |
--------------------------------------------------------------------------------
/_examples/federation/accounts/graph/resolver.go:
--------------------------------------------------------------------------------
1 | // This file will not be regenerated automatically.
2 | //
3 | // It serves as dependency injection for your app, add any dependencies you require here.
4 | package graph
5 |
6 | import "github.com/99designs/gqlgen/_examples/federation/accounts/graph/model"
7 |
8 | type Resolver struct{}
9 |
10 | func (r *Resolver) HostForUserID(id string) (*model.EmailHost, error) {
11 | return &model.EmailHost{
12 | ID: id,
13 | Name: "Email Host " + id,
14 | }, nil
15 | }
16 |
--------------------------------------------------------------------------------
/_examples/federation/accounts/graph/schema.graphqls:
--------------------------------------------------------------------------------
1 | directive @goField(
2 | forceResolver: Boolean
3 | name: String
4 | omittable: Boolean
5 | type: String
6 | ) on INPUT_FIELD_DEFINITION | FIELD_DEFINITION
7 |
8 | extend type Query {
9 | me: User
10 | }
11 |
12 | type EmailHost @key(fields: "id") {
13 | id: String!
14 | name: String!
15 | }
16 |
17 | type User @key(fields: "id") {
18 | id: ID!
19 | host: EmailHost! @goField(forceResolver: true)
20 | email: String!
21 | username: String!
22 | }
23 |
--------------------------------------------------------------------------------
/_examples/federation/accounts/schema/schema.go:
--------------------------------------------------------------------------------
1 | package server
2 |
3 | import (
4 | "github.com/99designs/gqlgen/_examples/federation/accounts/graph"
5 | )
6 |
7 | const DefaultPort = "4001"
8 |
9 | var Schema = graph.NewExecutableSchema(graph.Config{Resolvers: &graph.Resolver{}})
10 |
--------------------------------------------------------------------------------
/_examples/federation/gateway/index.js:
--------------------------------------------------------------------------------
1 | import { ApolloServer } from '@apollo/server';
2 | import { startStandaloneServer } from '@apollo/server/standalone';
3 | import { ApolloGateway,IntrospectAndCompose } from '@apollo/gateway';
4 |
5 | const gateway = new ApolloGateway({
6 | supergraphSdl: new IntrospectAndCompose({
7 | subgraphs: [
8 | { name: 'accounts', url: 'http://localhost:4001/query' },
9 | { name: 'products', url: 'http://localhost:4002/query' },
10 | { name: 'reviews', url: 'http://localhost:4003/query' }
11 | ],
12 | }),
13 | });
14 |
15 | const server = new ApolloServer({
16 | gateway,
17 | subscriptions: false,
18 | });
19 |
20 | // Note the top-level `await`!
21 | const { url } = await startStandaloneServer(server);
22 | console.log(`🚀 Server ready at ${url}`);
23 |
--------------------------------------------------------------------------------
/_examples/federation/jest.config.js:
--------------------------------------------------------------------------------
1 | export default {
2 | transform: {},
3 | testEnvironment: "node",
4 | testMatch: ["/**/*-test.js"],
5 | testPathIgnorePatterns: ["/node_modules/"],
6 | moduleFileExtensions: ["js"],
7 | modulePaths: ["/node_modules"],
8 | // transform: {
9 | // '^.+\\.jsx?$': 'babel-jest',
10 | // },
11 | };
12 |
--------------------------------------------------------------------------------
/_examples/federation/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "gateway",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "gateway/index.js",
6 | "type": "module",
7 | "scripts": {
8 | "start-gateway": "node gateway/index.js",
9 | "test": "echo \"Error: no test specified\" && exit 1"
10 | },
11 | "author": "",
12 | "license": "ISC",
13 | "dependencies": {
14 | "@apollo/gateway": "^2.7.1",
15 | "@apollo/server": "^4.10.0",
16 | "graphql": "^16.8.1"
17 | },
18 | "devDependencies": {
19 | "@apollo/client": "^3.9.4",
20 | "cross-fetch": "^4.0.0",
21 | "jest": "^29.7.0",
22 | "node-fetch": "^3.3.2"
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/_examples/federation/products/graph/model/model.go:
--------------------------------------------------------------------------------
1 | package model
2 |
--------------------------------------------------------------------------------
/_examples/federation/products/graph/model/models_gen.go:
--------------------------------------------------------------------------------
1 | // Code generated by github.com/99designs/gqlgen, DO NOT EDIT.
2 |
3 | package model
4 |
5 | type Manufacturer struct {
6 | ID string `json:"id"`
7 | Name string `json:"name"`
8 | }
9 |
10 | func (Manufacturer) IsEntity() {}
11 |
12 | type Product struct {
13 | ID string `json:"id"`
14 | Manufacturer *Manufacturer `json:"manufacturer"`
15 | Upc string `json:"upc"`
16 | Name string `json:"name"`
17 | Price int `json:"price"`
18 | }
19 |
20 | func (Product) IsEntity() {}
21 |
22 | type Query struct {
23 | }
24 |
--------------------------------------------------------------------------------
/_examples/federation/products/graph/products.go:
--------------------------------------------------------------------------------
1 | package graph
2 |
3 | import "github.com/99designs/gqlgen/_examples/federation/products/graph/model"
4 |
5 | var hats = []*model.Product{
6 | {
7 | ID: "111",
8 | Manufacturer: &model.Manufacturer{
9 | ID: "1234",
10 | Name: "Millinery 1234",
11 | },
12 | Upc: "top-1",
13 | Name: "Trilby",
14 | Price: 11,
15 | },
16 | {
17 | ID: "222",
18 | Manufacturer: &model.Manufacturer{
19 | ID: "2345",
20 | Name: "Millinery 2345",
21 | },
22 | Upc: "top-2",
23 | Name: "Fedora",
24 | Price: 22,
25 | },
26 | {
27 | ID: "333",
28 | Manufacturer: &model.Manufacturer{
29 | ID: "2345",
30 | Name: "Millinery 2345",
31 | },
32 | Upc: "top-3",
33 | Name: "Boater",
34 | Price: 33,
35 | },
36 | }
37 |
--------------------------------------------------------------------------------
/_examples/federation/products/graph/resolver.go:
--------------------------------------------------------------------------------
1 | // This file will not be regenerated automatically.
2 | //
3 | // It serves as dependency injection for your app, add any dependencies you require here.
4 | package graph
5 |
6 | type Resolver struct{}
7 |
--------------------------------------------------------------------------------
/_examples/federation/products/graph/schema.graphqls:
--------------------------------------------------------------------------------
1 | extend type Query {
2 | topProducts(first: Int = 5): [Product]
3 | }
4 |
5 | type Manufacturer @key(fields: "id") {
6 | id: String!
7 | name: String!
8 | }
9 |
10 | type Product @key(fields: "manufacturer { id } id") @key(fields: "upc") {
11 | id: String!
12 | manufacturer: Manufacturer!
13 | upc: String!
14 | name: String!
15 | price: Int!
16 | }
17 |
--------------------------------------------------------------------------------
/_examples/federation/products/graph/schema.resolvers.go:
--------------------------------------------------------------------------------
1 | package graph
2 |
3 | // This file will be automatically regenerated based on the schema, any resolver implementations
4 | // will be copied through when generating and any unknown code will be moved to the end.
5 | // Code generated by github.com/99designs/gqlgen version v0.17.73-dev
6 |
7 | import (
8 | "context"
9 |
10 | "github.com/99designs/gqlgen/_examples/federation/products/graph/model"
11 | )
12 |
13 | // TopProducts is the resolver for the topProducts field.
14 | func (r *queryResolver) TopProducts(ctx context.Context, first *int) ([]*model.Product, error) {
15 | return hats, nil
16 | }
17 |
18 | // Query returns QueryResolver implementation.
19 | func (r *Resolver) Query() QueryResolver { return &queryResolver{r} }
20 |
21 | type queryResolver struct{ *Resolver }
22 |
--------------------------------------------------------------------------------
/_examples/federation/products/schema/schema.go:
--------------------------------------------------------------------------------
1 | package schema
2 |
3 | import (
4 | "github.com/99designs/gqlgen/_examples/federation/products/graph"
5 | )
6 |
7 | const DefaultPort = "4002"
8 |
9 | var Schema = graph.NewExecutableSchema(graph.Config{Resolvers: &graph.Resolver{}})
10 |
--------------------------------------------------------------------------------
/_examples/federation/readme.md:
--------------------------------------------------------------------------------
1 | ### Federation
2 |
3 | [Read the docs](https://gqlgen.com/recipes/federation/)
4 |
5 | ## Testing
6 |
7 | If you want to set breakpoints and debug the federation example, you can first run the subgraphs using:
8 |
9 | $ go run ./all/main.go
10 |
11 | Then start the gateway using
12 | $ npm run start-gateway
13 |
14 | You can then connect your preferred Golang debugger to the Go process as you make requests to the router.
15 |
--------------------------------------------------------------------------------
/_examples/federation/reviews/graph/model/models.go:
--------------------------------------------------------------------------------
1 | package model
2 |
3 | type Product struct {
4 | ID string `json:"id"`
5 | Manufacturer *Manufacturer `json:"manufacturer"`
6 | Reviews []*Review `json:"reviews"`
7 | }
8 |
9 | func (Product) IsEntity() {}
10 |
11 | type Review struct {
12 | Body string
13 | Author *User
14 | Product *Product
15 | HostIDEmail string
16 | }
17 |
18 | type User struct {
19 | ID string `json:"id"`
20 | Host *EmailHost `json:"host"`
21 | Email string `json:"email"`
22 | }
23 |
24 | func (User) IsEntity() {}
25 |
--------------------------------------------------------------------------------
/_examples/federation/reviews/graph/model/models_gen.go:
--------------------------------------------------------------------------------
1 | // Code generated by github.com/99designs/gqlgen, DO NOT EDIT.
2 |
3 | package model
4 |
5 | type EmailHost struct {
6 | ID string `json:"id"`
7 | }
8 |
9 | func (EmailHost) IsEntity() {}
10 |
11 | type Manufacturer struct {
12 | ID string `json:"id"`
13 | }
14 |
15 | func (Manufacturer) IsEntity() {}
16 |
17 | type ProductByManufacturerIDAndIDsInput struct {
18 | ManufacturerID string `json:"ManufacturerID"`
19 | ID string `json:"ID"`
20 | }
21 |
22 | type Query struct {
23 | }
24 |
--------------------------------------------------------------------------------
/_examples/federation/reviews/graph/reviews.go:
--------------------------------------------------------------------------------
1 | package graph
2 |
3 | import "github.com/99designs/gqlgen/_examples/federation/reviews/graph/model"
4 |
5 | var reviews = []*model.Review{
6 | {
7 | Body: "A highly effective form of birth control.",
8 | Product: &model.Product{ID: "111", Manufacturer: &model.Manufacturer{ID: "1234"}},
9 | Author: &model.User{ID: "1234"},
10 | },
11 | {
12 | Body: "Fedoras are one of the most fashionable hats around and can look great with a variety of outfits.",
13 | Product: &model.Product{ID: "222", Manufacturer: &model.Manufacturer{ID: "2345"}},
14 | Author: &model.User{ID: "1234"},
15 | },
16 | {
17 | Body: "This is the last straw. Hat you will wear. 11/10",
18 | Product: &model.Product{ID: "333", Manufacturer: &model.Manufacturer{ID: "2345"}},
19 | Author: &model.User{ID: "7777"},
20 | },
21 | }
22 |
--------------------------------------------------------------------------------
/_examples/federation/reviews/schema/schema.go:
--------------------------------------------------------------------------------
1 | package schema
2 |
3 | import (
4 | "github.com/99designs/gqlgen/_examples/federation/reviews/graph"
5 | )
6 |
7 | const DefaultPort = "4003"
8 |
9 | var Schema = graph.NewExecutableSchema(graph.Config{Resolvers: &graph.Resolver{}})
10 |
--------------------------------------------------------------------------------
/_examples/federation/start.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | function cleanup {
4 | kill "$ACCOUNTS_PID"
5 | kill "$PRODUCTS_PID"
6 | kill "$REVIEWS_PID"
7 | }
8 | trap cleanup EXIT
9 |
10 | go build -o /tmp/srv-accounts ./accounts
11 | go build -o /tmp/srv-products ./products
12 | go build -o /tmp/srv-reviews ./reviews
13 |
14 | /tmp/srv-accounts &
15 | ACCOUNTS_PID=$!
16 |
17 | /tmp/srv-products &
18 | PRODUCTS_PID=$!
19 |
20 | /tmp/srv-reviews &
21 | REVIEWS_PID=$!
22 |
23 | sleep 1
24 |
25 | node gateway/index.js
26 |
--------------------------------------------------------------------------------
/_examples/fileupload/.gqlgen.yml:
--------------------------------------------------------------------------------
1 | model:
2 | filename: model/generated.go
3 |
--------------------------------------------------------------------------------
/_examples/fileupload/model/generated.go:
--------------------------------------------------------------------------------
1 | // Code generated by github.com/99designs/gqlgen, DO NOT EDIT.
2 |
3 | package model
4 |
5 | import (
6 | "github.com/99designs/gqlgen/graphql"
7 | )
8 |
9 | // The `File` type, represents the response of uploading a file.
10 | type File struct {
11 | ID int `json:"id"`
12 | Name string `json:"name"`
13 | Content string `json:"content"`
14 | ContentType string `json:"contentType"`
15 | }
16 |
17 | // The `Mutation` type, represents all updates we can make to our data.
18 | type Mutation struct {
19 | }
20 |
21 | // The `Query` type, represents all of the entry points into our object graph.
22 | type Query struct {
23 | }
24 |
25 | // The `UploadFile` type, represents the request for uploading a file with certain payload.
26 | type UploadFile struct {
27 | ID int `json:"id"`
28 | File graphql.Upload `json:"file"`
29 | }
30 |
--------------------------------------------------------------------------------
/_examples/fileupload/testfiles/a.txt:
--------------------------------------------------------------------------------
1 | Alpha file content
2 |
--------------------------------------------------------------------------------
/_examples/fileupload/testfiles/b.txt:
--------------------------------------------------------------------------------
1 | Bravo file content
2 |
--------------------------------------------------------------------------------
/_examples/fileupload/testfiles/c.txt:
--------------------------------------------------------------------------------
1 | Charlie file content
2 |
--------------------------------------------------------------------------------
/_examples/large-project-structure/integration/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/99designs/gqlgen/_examples/large-project-structure/integration
2 |
3 | go 1.24.1
4 |
5 | require github.com/99designs/gqlgen/_examples/large-project-structure/main v0.0.0
6 |
7 | replace github.com/99designs/gqlgen/_examples/large-project-structure/main => ../main
8 |
9 | replace github.com/99designs/gqlgen/_examples/large-project-structure/shared => ../shared
10 |
11 | require (
12 | github.com/99designs/gqlgen v0.17.70 // indirect
13 | github.com/agnivade/levenshtein v1.2.1 // indirect
14 | github.com/google/uuid v1.6.0 // indirect
15 | github.com/sosodev/duration v1.3.1 // indirect
16 | github.com/vektah/gqlparser/v2 v2.5.23 // indirect
17 | )
18 |
--------------------------------------------------------------------------------
/_examples/large-project-structure/integration/schema.graphqls:
--------------------------------------------------------------------------------
1 | type Test {
2 | id: ID!
3 | }
4 |
5 | type CustomZeekIntel implements ZeekIntel{
6 | id: ID!
7 | name: String!
8 |
9 | extraField: String!
10 | }
11 |
12 | input CustomInput {
13 | limit: Int
14 | error: Boolean
15 | }
16 |
17 | extend type Query {
18 | tezz: Test!
19 | getYaSome(input: CustomInput): [CustomZeekIntel!]!
20 | }
21 |
22 | type Indicator {
23 | id: ID!
24 | indicator: String!
25 | indicatorType: String!
26 | metaSource: String!
27 | }
28 |
29 | input IndicatorInput {
30 | indicator: String!
31 | indicatorType: String!
32 | metaSource: String!
33 | }
34 |
35 | extend type Mutation {
36 | addIndicator(input: IndicatorInput!): Indicator!
37 | }
--------------------------------------------------------------------------------
/_examples/large-project-structure/main/graph/resolver.go:
--------------------------------------------------------------------------------
1 | package graph
2 |
3 | import (
4 | "context"
5 |
6 | "github.com/99designs/gqlgen/_examples/large-project-structure/main/graph/model"
7 | )
8 |
9 | // This file will not be regenerated automatically.
10 | //
11 | // It serves as dependency injection for your app, add any dependencies you require here.
12 |
13 | // Define an interface for each resolver method
14 | type ExternalQueryResolver interface {
15 | // Example query resolver
16 | Tezz(ctx context.Context) (*model.Test, error)
17 | // Example query resolver with args
18 | GetYaSome(context.Context, *model.CustomInput) ([]*model.CustomZeekIntel, error)
19 |
20 | // Example mutation resolver with args
21 | AddIndicator(context.Context, model.IndicatorInput) (*model.Indicator, error)
22 | }
23 |
24 | type Resolver struct {
25 | ExternalQueryResolver
26 | }
27 |
--------------------------------------------------------------------------------
/_examples/large-project-structure/main/graph/schema.graphqls:
--------------------------------------------------------------------------------
1 | # GraphQL schema example
2 | #
3 | # https://gqlgen.com/getting-started/
4 |
5 | type Todo {
6 | id: ID!
7 | text: String!
8 | done: Boolean!
9 | user: User!
10 | }
11 |
12 | type User {
13 | id: ID!
14 | name: String!
15 | }
16 |
17 | type Query {
18 | todos: [Todo!]!
19 | }
20 |
21 | input NewTodo {
22 | text: String!
23 | userId: String!
24 | }
25 |
26 | type Mutation {
27 | createTodo(input: NewTodo!): Todo!
28 | }
29 |
--------------------------------------------------------------------------------
/_examples/large-project-structure/main/tools.go:
--------------------------------------------------------------------------------
1 | //go:build tools
2 |
3 | package tools
4 |
5 | import (
6 | _ "github.com/99designs/gqlgen"
7 | )
8 |
--------------------------------------------------------------------------------
/_examples/large-project-structure/shared/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/99designs/gqlgen/_examples/large-project-structure/shared
2 |
3 | go 1.24.1
4 |
--------------------------------------------------------------------------------
/_examples/large-project-structure/shared/go.sum:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/99designs/gqlgen/0fce010415029b53fc75b00c6dc85394f44402db/_examples/large-project-structure/shared/go.sum
--------------------------------------------------------------------------------
/_examples/large-project-structure/shared/schema.graphqls:
--------------------------------------------------------------------------------
1 | # GraphQL schema example
2 | #
3 | # https://gqlgen.com/getting-started/
4 |
5 | interface ZeekIntel {
6 | id: ID!
7 | name: String!
8 | }
9 |
--------------------------------------------------------------------------------
/_examples/large-project-structure/shared/shared.go:
--------------------------------------------------------------------------------
1 | package shared
2 |
3 | import "embed"
4 |
5 | //go:embed "schema.graphqls"
6 | var sourcesFS embed.FS
7 |
--------------------------------------------------------------------------------
/_examples/mini-habr-with-subscriptions/.env:
--------------------------------------------------------------------------------
1 | TIMEOUT=4s
2 | IDLE_TIMEOUT=60s
3 | SERVER_PORT=8080
4 | DB_PROTOCOL=postgres
5 | DB_USER=mini
6 | DB_PASSWORD=mini_passwd
7 | DB_NAME=mini_habr
8 | DB_HOST=db
9 | DB_PORT=5432
10 | DB_OPTIONS=sslmode=disable
11 | REDIS_PORT1=6379
12 | REDIS_PORT2=6379
13 | REDIS_PASSWORD=redis_passwd
14 | REDIS_DB=0
15 |
--------------------------------------------------------------------------------
/_examples/mini-habr-with-subscriptions/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM golang:alpine
2 |
3 | WORKDIR /app
4 |
5 | COPY . .
6 |
7 | RUN go build -o main ./cmd/main.go
8 |
9 | EXPOSE 8080
10 |
11 | CMD ["./main"]
--------------------------------------------------------------------------------
/_examples/mini-habr-with-subscriptions/internal/handlers/comment_mutation/interface.go:
--------------------------------------------------------------------------------
1 | package commentmutation
2 |
3 | import (
4 | "github.com/gqlgen/_examples/mini-habr-with-subscriptions/internal/model"
5 | )
6 |
7 | type CommentMutationImp interface {
8 | AddComment(postID int64, newComment *model.NewComment) (*model.Comment, error)
9 | }
10 |
--------------------------------------------------------------------------------
/_examples/mini-habr-with-subscriptions/internal/handlers/comment_query/interface.go:
--------------------------------------------------------------------------------
1 | package commentquery
2 |
3 | import (
4 | "github.com/gqlgen/_examples/mini-habr-with-subscriptions/internal/model"
5 | )
6 |
7 | type CommentQueryImp interface {
8 | GetCommentsBranch(postID int64, path string) ([]*model.Comment, error)
9 | GetCommentPath(parentID int64) (string, error)
10 | }
11 |
--------------------------------------------------------------------------------
/_examples/mini-habr-with-subscriptions/internal/handlers/post_mutation/interface.go:
--------------------------------------------------------------------------------
1 | package postmutation
2 |
3 | import (
4 | "github.com/google/uuid"
5 | "github.com/gqlgen/_examples/mini-habr-with-subscriptions/internal/model"
6 | )
7 |
8 | type PostMutImp interface {
9 | AddPost(newPost *model.NewPost) (*model.Post, error)
10 | UpdateEnableCommentToPost(postID int64, authorID uuid.UUID, commentsEnabled bool) (*model.Post, error)
11 | }
12 |
--------------------------------------------------------------------------------
/_examples/mini-habr-with-subscriptions/internal/handlers/post_query/interface.go:
--------------------------------------------------------------------------------
1 | package postquery
2 |
3 | import (
4 | "github.com/gqlgen/_examples/mini-habr-with-subscriptions/internal/model"
5 | )
6 |
7 | type PostQueryImp interface {
8 | GetAllPosts() ([]*model.Post, error)
9 | GetPost(postID int64) (*model.Post, error)
10 | }
11 |
--------------------------------------------------------------------------------
/_examples/mini-habr-with-subscriptions/internal/pkg/errs/errors.go:
--------------------------------------------------------------------------------
1 | package errs
2 |
3 | import (
4 | "errors"
5 | )
6 |
7 | var (
8 | ErrPostNotExist = errors.New("post not exist")
9 | ErrUnauthorizedAccess = errors.New("user doesn't have access rights")
10 | ErrPostsNotExist = errors.New("no posts have been created yet")
11 | ErrCommentsNotExist = errors.New("no comments have been created yet")
12 | ErrPostNotCached = errors.New("post not cached yet")
13 | ErrPathNotExist = errors.New("path not exist")
14 | ErrParentCommentNotExist = errors.New("parent comment not exist yet")
15 | ErrIncorrectCommentLength = errors.New("incorrect comment length")
16 | ErrCommentsNotEnabled = errors.New("сomments on the post are not allowed")
17 | )
18 |
--------------------------------------------------------------------------------
/_examples/mini-habr-with-subscriptions/internal/storage/interface.go:
--------------------------------------------------------------------------------
1 | package storage
2 |
3 | import (
4 | "github.com/google/uuid"
5 | "github.com/gqlgen/_examples/mini-habr-with-subscriptions/internal/model"
6 | )
7 |
8 | type StorageImp interface {
9 | AddPost(newPost *model.NewPost) (*model.Post, error)
10 | AddComment(postID int64, newComment *model.NewComment) (*model.Comment, error)
11 | UpdateEnableCommentToPost(postID int64, authorID uuid.UUID, commentsEnabled bool) (*model.Post, error)
12 | GetAllPosts() ([]*model.Post, error)
13 | GetPost(postID int64) (*model.Post, error)
14 | GetCommentsBranch(postID int64, path string) ([]*model.Comment, error)
15 | GetCommentPath(parentID int64) (string, error)
16 | }
17 |
--------------------------------------------------------------------------------
/_examples/mini-habr-with-subscriptions/tools/tools.go:
--------------------------------------------------------------------------------
1 | package tools
2 |
3 | import (
4 | _ "github.com/99designs/gqlgen"
5 | _ "github.com/99designs/gqlgen/graphql/introspection"
6 | )
7 |
--------------------------------------------------------------------------------
/_examples/readme.md:
--------------------------------------------------------------------------------
1 | ### examples
2 |
3 | - todo: A simple todo checklist. A good place to get the basics down
4 | - starwars: A starwars movie database. It has examples of advanced graphql features
5 | - dataloader: How to avoid n+1 database query problems
6 |
--------------------------------------------------------------------------------
/_examples/scalars/.gqlgen.yml:
--------------------------------------------------------------------------------
1 | model:
2 | filename: model/generated.go
3 |
4 | models:
5 | User:
6 | model: github.com/99designs/gqlgen/_examples/scalars/model.User
7 | Timestamp:
8 | model: github.com/99designs/gqlgen/_examples/scalars/model.Timestamp
9 | SearchArgs:
10 | model: github.com/99designs/gqlgen/_examples/scalars/model.SearchArgs
11 | Point:
12 | model: github.com/99designs/gqlgen/_examples/scalars/model.Point
13 | ID:
14 | model: github.com/99designs/gqlgen/_examples/scalars/model.ID
15 | Tier:
16 | model: github.com/99designs/gqlgen/_examples/scalars/model.Tier
17 | Banned:
18 | model: github.com/99designs/gqlgen/_examples/scalars/model.Banned
19 | DarkMode:
20 | model: github.com/99designs/gqlgen/_examples/scalars/model.Preferences
21 |
--------------------------------------------------------------------------------
/_examples/scalars/external/model.go:
--------------------------------------------------------------------------------
1 | package external
2 |
3 | type ObjectID int
4 |
--------------------------------------------------------------------------------
/_examples/scalars/model/generated.go:
--------------------------------------------------------------------------------
1 | // Code generated by github.com/99designs/gqlgen, DO NOT EDIT.
2 |
3 | package model
4 |
5 | import (
6 | "github.com/99designs/gqlgen/_examples/scalars/external"
7 | )
8 |
9 | type Address struct {
10 | ID external.ObjectID `json:"id"`
11 | Location *Point `json:"location,omitempty"`
12 | }
13 |
14 | type Query struct {
15 | }
16 |
--------------------------------------------------------------------------------
/_examples/scalars/server/server.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "log"
5 | "net/http"
6 |
7 | "github.com/99designs/gqlgen/_examples/scalars"
8 | "github.com/99designs/gqlgen/graphql/handler"
9 | "github.com/99designs/gqlgen/graphql/handler/transport"
10 | "github.com/99designs/gqlgen/graphql/playground"
11 | )
12 |
13 | func main() {
14 | srv := handler.New(
15 | scalars.NewExecutableSchema(scalars.Config{Resolvers: &scalars.Resolver{}}),
16 | )
17 | srv.AddTransport(transport.GET{})
18 | srv.AddTransport(transport.POST{})
19 |
20 | http.Handle("/", playground.Handler("Starwars", "/query"))
21 | http.Handle("/query", srv)
22 |
23 | log.Fatal(http.ListenAndServe(":8084", nil))
24 | }
25 |
--------------------------------------------------------------------------------
/_examples/selection/.gqlgen.yml:
--------------------------------------------------------------------------------
1 | schema: schema.graphql
2 | model:
3 | filename: models_gen.go
4 | exec:
5 | filename: generated.go
6 |
--------------------------------------------------------------------------------
/_examples/selection/readme.md:
--------------------------------------------------------------------------------
1 | ### selection app
2 |
3 | This is the simplest example of a graphql server.
4 |
5 | to run this server
6 | ```bash
7 | go run ./server/server.go
8 | ```
9 |
10 | and open http://localhost:8086 in your browser
11 |
--------------------------------------------------------------------------------
/_examples/selection/schema.graphql:
--------------------------------------------------------------------------------
1 | interface Event {
2 | selection: [String!]
3 | collected: [String!]
4 | }
5 |
6 | type Post implements Event {
7 | message: String!
8 | sent: Time!
9 | selection: [String!]
10 | collected: [String!]
11 | }
12 |
13 | type Like implements Event {
14 | reaction: String!
15 | sent: Time!
16 | selection: [String!]
17 | collected: [String!]
18 | }
19 |
20 | type Query {
21 | events: [Event!]
22 | }
23 |
24 | scalar Time
25 |
--------------------------------------------------------------------------------
/_examples/selection/server/server.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "log"
5 | "net/http"
6 |
7 | "github.com/99designs/gqlgen/_examples/selection"
8 | "github.com/99designs/gqlgen/graphql/handler"
9 | "github.com/99designs/gqlgen/graphql/handler/transport"
10 | "github.com/99designs/gqlgen/graphql/playground"
11 | )
12 |
13 | func main() {
14 | srv := handler.New(
15 | selection.NewExecutableSchema(selection.Config{Resolvers: &selection.Resolver{}}),
16 | )
17 | srv.AddTransport(transport.GET{})
18 | srv.AddTransport(transport.POST{})
19 |
20 | http.Handle("/", playground.Handler("Selection Demo", "/query"))
21 | http.Handle("/query", srv)
22 | log.Fatal(http.ListenAndServe(":8086", nil))
23 | }
24 |
--------------------------------------------------------------------------------
/_examples/starwars/.gqlgen.yml:
--------------------------------------------------------------------------------
1 | exec:
2 | filename: generated/exec.go
3 | model:
4 | filename: models/generated.go
5 | package: models
6 |
7 | autobind:
8 | - github.com/99designs/gqlgen/_examples/starwars/models
9 |
10 | models:
11 | ReviewInput:
12 | model: models.Review
13 | Starship:
14 | fields:
15 | length:
16 | resolver: true
17 |
--------------------------------------------------------------------------------
/_examples/starwars/readme.md:
--------------------------------------------------------------------------------
1 | ### starwars example
2 |
3 | This server demonstrates a few advanced features of graphql:
4 | - connections
5 | - unions
6 | - interfaces
7 | - enums
8 |
9 | to run this server
10 | ```bash
11 | go run ./server/server.go
12 | ```
13 |
14 | and open http://localhost:8080 in your browser
15 |
--------------------------------------------------------------------------------
/_examples/todo/gqlgen.yml:
--------------------------------------------------------------------------------
1 | models:
2 | Todo:
3 | model: github.com/99designs/gqlgen/_examples/todo.Todo
4 | ID:
5 | model: # override the default id marshaller to use ints
6 | - github.com/99designs/gqlgen/graphql.IntID
7 | - github.com/99designs/gqlgen/graphql.ID
8 |
--------------------------------------------------------------------------------
/_examples/todo/models.go:
--------------------------------------------------------------------------------
1 | package todo
2 |
3 | import (
4 | "context"
5 | "fmt"
6 | "io"
7 |
8 | "github.com/99designs/gqlgen/graphql"
9 | )
10 |
11 | type Ownable interface {
12 | Owner() *User
13 | }
14 |
15 | type Todo struct {
16 | ID int
17 | Text string
18 | Done bool
19 | owner *User
20 | }
21 |
22 | func (t Todo) Owner() *User {
23 | return t.owner
24 | }
25 |
26 | type User struct {
27 | ID int
28 | Name string
29 | }
30 |
31 | type Number int
32 |
33 | func (e *Number) UnmarshalGQLContext(ctx context.Context, v any) error {
34 | num, err := graphql.UnmarshalInt(v)
35 | if err != nil {
36 | return err
37 | }
38 | *e = Number(num)
39 | return nil
40 | }
41 |
42 | func (e Number) MarshalGQLContext(_ context.Context, w io.Writer) error {
43 | fmt.Fprint(w, e)
44 | return nil
45 | }
46 |
--------------------------------------------------------------------------------
/_examples/todo/readme.md:
--------------------------------------------------------------------------------
1 | ### todo app
2 |
3 | This is the simplest example of a graphql server.
4 |
5 | to run this server
6 | ```bash
7 | go run ./server/server.go
8 | ```
9 |
10 | and open http://localhost:8081 in your browser
11 |
--------------------------------------------------------------------------------
/_examples/tools.go:
--------------------------------------------------------------------------------
1 | //go:build tools
2 |
3 | package main
4 |
5 | import (
6 | _ "github.com/vektah/dataloaden"
7 | _ "golang.org/x/text"
8 | )
9 |
--------------------------------------------------------------------------------
/_examples/type-system-extension/README.md:
--------------------------------------------------------------------------------
1 | # Type System Extension example
2 |
3 | https://graphql.github.io/graphql-spec/draft/#sec-Type-System-Extensions
4 |
5 | ```
6 | $ go run ./server/server.go
7 | 2018/10/25 12:46:45 connect to http://localhost:8080/ for GraphQL playground
8 |
9 | $ curl -X POST 'http://localhost:8080/query' --data-binary '{"query":"{ todos { id text state verified } }"}'
10 | {"data":{"todos":[{"id":"Todo:1","text":"Buy a cat food","state":"NOT_YET","verified":false},{"id":"Todo:2","text":"Check cat water","state":"DONE","verified":true},{"id":"Todo:3","text":"Check cat meal","state":"DONE","verified":true}]}}
11 | ```
12 |
--------------------------------------------------------------------------------
/_examples/type-system-extension/gqlgen.yml:
--------------------------------------------------------------------------------
1 | # .gqlgen.yml example
2 | #
3 | # Refer to https://gqlgen.com/config/
4 | # for detailed .gqlgen.yml documentation.
5 |
6 | schema:
7 | - ./schemas/*.graphql
8 |
9 | exec:
10 | filename: generated.go
11 | model:
12 | filename: models_gen.go
13 |
--------------------------------------------------------------------------------
/_examples/type-system-extension/schemas/enum-extension.graphql:
--------------------------------------------------------------------------------
1 | directive @enumLogging on ENUM
2 |
3 | extend enum State @enumLogging
4 |
--------------------------------------------------------------------------------
/_examples/type-system-extension/schemas/input-object-extension.graphql:
--------------------------------------------------------------------------------
1 | directive @inputLogging on INPUT_OBJECT
2 |
3 | extend input TodoInput @inputLogging
4 |
--------------------------------------------------------------------------------
/_examples/type-system-extension/schemas/interface-extension.graphql:
--------------------------------------------------------------------------------
1 | directive @interfaceLogging on INTERFACE
2 |
3 | extend interface Node @interfaceLogging
4 |
--------------------------------------------------------------------------------
/_examples/type-system-extension/schemas/object-extension.graphql:
--------------------------------------------------------------------------------
1 | directive @objectLogging on OBJECT
2 |
3 | extend type Todo @objectLogging
4 |
--------------------------------------------------------------------------------
/_examples/type-system-extension/schemas/scalar-extension.graphql:
--------------------------------------------------------------------------------
1 | directive @scalarLogging on SCALAR
2 |
3 | extend scalar ID @scalarLogging
4 |
--------------------------------------------------------------------------------
/_examples/type-system-extension/schemas/schema-extension.graphql:
--------------------------------------------------------------------------------
1 | extend schema {
2 | mutation: MyMutation
3 | }
4 |
5 | extend type MyQuery {
6 | todo(id: ID!): Todo
7 | }
8 |
9 | type MyMutation {
10 | createTodo(todo: TodoInput!): Todo!
11 | }
12 |
13 | input TodoInput {
14 | text: String!
15 | }
16 |
--------------------------------------------------------------------------------
/_examples/type-system-extension/schemas/schema.graphql:
--------------------------------------------------------------------------------
1 | # GraphQL schema example
2 | #
3 | # https://gqlgen.com/getting-started/
4 |
5 | schema {
6 | query: MyQuery
7 | }
8 |
9 | interface Node {
10 | id: ID!
11 | }
12 |
13 | type Todo implements Node {
14 | id: ID!
15 | text: String!
16 | state: State!
17 | }
18 |
19 | type MyQuery {
20 | todos: [Todo!]!
21 | }
22 |
23 | union Data = Todo
24 |
25 | enum State {
26 | NOT_YET
27 | DONE
28 | }
29 |
--------------------------------------------------------------------------------
/_examples/type-system-extension/schemas/type-extension.graphql:
--------------------------------------------------------------------------------
1 | directive @fieldLogging on FIELD_DEFINITION
2 |
3 | extend type Todo {
4 | verified: Boolean! @fieldLogging
5 | }
6 |
--------------------------------------------------------------------------------
/_examples/type-system-extension/schemas/union-extension.graphql:
--------------------------------------------------------------------------------
1 | directive @unionLogging on UNION
2 |
3 | extend union Data @unionLogging
4 |
--------------------------------------------------------------------------------
/_examples/uuid/graph/model/models_gen.go:
--------------------------------------------------------------------------------
1 | // Code generated by github.com/99designs/gqlgen, DO NOT EDIT.
2 |
3 | package model
4 |
5 | import (
6 | "github.com/google/uuid"
7 | )
8 |
9 | type Mutation struct {
10 | }
11 |
12 | type NewTodo struct {
13 | Text string `json:"text"`
14 | UserID string `json:"userId"`
15 | UID uuid.UUID `json:"uid"`
16 | }
17 |
18 | type Query struct {
19 | }
20 |
21 | type Todo struct {
22 | ID string `json:"id"`
23 | Text string `json:"text"`
24 | Done bool `json:"done"`
25 | UID uuid.UUID `json:"uid"`
26 | }
27 |
--------------------------------------------------------------------------------
/_examples/uuid/graph/resolver.go:
--------------------------------------------------------------------------------
1 | package graph
2 |
3 | // This file will not be regenerated automatically.
4 | //
5 | // It serves as dependency injection for your app, add any dependencies you require here.
6 |
7 | type Resolver struct{}
8 |
--------------------------------------------------------------------------------
/_examples/uuid/graph/schema.graphqls:
--------------------------------------------------------------------------------
1 | # GraphQL schema example
2 | #
3 | # https://gqlgen.com/getting-started/
4 |
5 | type Todo {
6 | id: ID!
7 | text: String!
8 | done: Boolean!
9 | uid: UUID!
10 | }
11 |
12 |
13 | type Query {
14 | todos: [Todo!]!
15 | }
16 |
17 | input NewTodo {
18 | text: String!
19 | userId: String!
20 | uid: UUID!
21 | }
22 |
23 | type Mutation {
24 | createTodo(input: NewTodo!): Todo!
25 | }
26 |
27 | scalar UUID
28 |
--------------------------------------------------------------------------------
/_examples/websocket-initfunc/graph/model/models_gen.go:
--------------------------------------------------------------------------------
1 | // Code generated by github.com/99designs/gqlgen, DO NOT EDIT.
2 |
3 | package model
4 |
5 | type Query struct {
6 | }
7 |
--------------------------------------------------------------------------------
/_examples/websocket-initfunc/graph/resolver.go:
--------------------------------------------------------------------------------
1 | package graph
2 |
3 | // This file will not be regenerated automatically.
4 | //
5 | // It serves as dependency injection for your app, add any dependencies you require here.
6 |
7 | type Resolver struct{}
8 |
--------------------------------------------------------------------------------
/_examples/websocket-initfunc/server/Makefile:
--------------------------------------------------------------------------------
1 | bin_name=server
2 |
3 | build:
4 | @echo "building binary..."
5 | # go generate gives missing go sum entry for module errors
6 | # https://github.com/99designs/gqlgen/issues/1483
7 | # you will need to first do a go get -u github.com/99designs/gqlgen
8 | go run -mod=mod github.com/99designs/gqlgen generate .
9 | go build -o ${bin_name} server.go
10 |
--------------------------------------------------------------------------------
/_examples/websocket-initfunc/server/graph/model/models_gen.go:
--------------------------------------------------------------------------------
1 | // Code generated by github.com/99designs/gqlgen, DO NOT EDIT.
2 |
3 | package model
4 |
5 | type Dummy struct {
6 | ID string `json:"id"`
7 | Text string `json:"text"`
8 | Done bool `json:"done"`
9 | }
10 |
--------------------------------------------------------------------------------
/_examples/websocket-initfunc/server/graph/resolver.go:
--------------------------------------------------------------------------------
1 | package graph
2 |
3 | // This file will not be regenerated automatically.
4 | //
5 | // It serves as dependency injection for your app, add any dependencies you require here.
6 |
7 | type Resolver struct{}
8 |
--------------------------------------------------------------------------------
/_examples/websocket-initfunc/server/graph/schema.graphqls:
--------------------------------------------------------------------------------
1 | # GraphQL schema example
2 | #
3 |
4 | type Dummy {
5 | id: ID!
6 | text: String!
7 | done: Boolean!
8 | }
9 |
10 | type Mutation {
11 | postMessageTo(subscriber: String!, content: String!): ID!
12 | }
13 |
14 | type Subscription {
15 | subscribe(subscriber: String!): String!
16 | }
17 |
--------------------------------------------------------------------------------
/_examples/websocket-initfunc/server/readme.md:
--------------------------------------------------------------------------------
1 | # WebSocket Init App
2 |
3 | Example server app using websocket `InitFunc`.
4 |
5 | ## Build and Run the server app
6 |
7 | First get an update from gqlgen:
8 | ```bash
9 | go mod tidy
10 | go get -u github.com/99designs/gqlgen
11 | ```
12 |
13 | Next just make the build:
14 | ```bash
15 | make build
16 | ```
17 |
18 | Run the server:
19 | ```bash
20 | ./server
21 | 2022/07/07 16:49:46 connect to http://localhost:8080/ for GraphQL playground
22 | ```
23 |
24 | You may now implement a websocket client to subscribe for websocket messages.
--------------------------------------------------------------------------------
/api/testdata/default/graph/model/doc.go:
--------------------------------------------------------------------------------
1 | package model
2 |
--------------------------------------------------------------------------------
/api/testdata/default/graph/schema.graphqls:
--------------------------------------------------------------------------------
1 | # GraphQL schema example
2 | #
3 | # https://gqlgen.com/getting-started/
4 |
5 | type Todo {
6 | id: ID!
7 | text: String!
8 | done: Boolean!
9 | user: User!
10 | }
11 |
12 | type User {
13 | id: ID!
14 | name: String!
15 | }
16 |
17 | type Query {
18 | todos: [Todo!]!
19 | }
20 |
21 | input NewTodo {
22 | text: String!
23 | userId: String!
24 | }
25 |
26 | type Mutation {
27 | createTodo(input: NewTodo!): Todo!
28 | }
29 |
--------------------------------------------------------------------------------
/api/testdata/federation2/graph/model/doc.go:
--------------------------------------------------------------------------------
1 | package model
2 |
--------------------------------------------------------------------------------
/api/testdata/federation2/graph/schema.graphqls:
--------------------------------------------------------------------------------
1 | # GraphQL schema example
2 | #
3 | # https://gqlgen.com/getting-started/
4 | extend schema
5 | @link(url: "https://specs.apollo.dev/federation/v2.7",
6 | import: ["@key", "@shareable", "@provides", "@external", "@tag", "@extends", "@override", "@inaccessible"])
7 |
8 | type Todo {
9 | id: ID!
10 | text: String!
11 | done: Boolean!
12 | user: User!
13 | }
14 |
15 | type User {
16 | id: ID!
17 | name: String!
18 | }
19 |
20 | type Query {
21 | todos: [Todo!]!
22 | }
23 |
24 | input NewTodo {
25 | text: String!
26 | userId: String!
27 | }
28 |
29 | type Mutation {
30 | createTodo(input: NewTodo!): Todo!
31 | }
32 |
--------------------------------------------------------------------------------
/api/testdata/workerlimit/graph/model/doc.go:
--------------------------------------------------------------------------------
1 | package model
2 |
--------------------------------------------------------------------------------
/api/testdata/workerlimit/graph/schema.graphqls:
--------------------------------------------------------------------------------
1 | # GraphQL schema example
2 | #
3 | # https://gqlgen.com/getting-started/
4 |
5 | type Todo {
6 | id: ID!
7 | text: String!
8 | done: Boolean!
9 | user: User!
10 | }
11 |
12 | type User {
13 | id: ID!
14 | name: String!
15 | }
16 |
17 | type Query {
18 | todos: [Todo!]!
19 | }
20 |
21 | input NewTodo {
22 | text: String!
23 | userId: String!
24 | }
25 |
26 | type Mutation {
27 | createTodo(input: NewTodo!): Todo!
28 | }
29 |
--------------------------------------------------------------------------------
/client/errors.go:
--------------------------------------------------------------------------------
1 | package client
2 |
3 | import "encoding/json"
4 |
5 | // RawJsonError is a json formatted error from a GraphQL server.
6 | type RawJsonError struct {
7 | json.RawMessage
8 | }
9 |
10 | func (r RawJsonError) Error() string {
11 | return string(r.RawMessage)
12 | }
13 |
--------------------------------------------------------------------------------
/client/readme.md:
--------------------------------------------------------------------------------
1 | This client is used internally for testing. I wanted a simple graphql client sent user specified queries.
2 |
3 | You might want to look at:
4 | - https://github.com/shurcooL/graphql: Uses reflection to build queries from structs.
5 | - https://github.com/machinebox/graphql: Probably would have been a perfect fit, but it uses form encoding instead of json...
6 | - [Khan/genqlient](https://github.com/Khan/genqlient) - Generate go GraphQL client from GraphQL query
7 | - [infiotinc/gqlgenc](https://github.com/infiotinc/gqlgenc) - Generate go GraphQL client from GraphQL query
8 | - [Yamashou/gqlgenc](https://github.com/Yamashou/gqlgenc) - Generate go GraphQL client from GraphQL query
9 |
--------------------------------------------------------------------------------
/codegen/complexity.go:
--------------------------------------------------------------------------------
1 | package codegen
2 |
3 | func (o *Object) UniqueFields() map[string][]*Field {
4 | m := map[string][]*Field{}
5 |
6 | for _, f := range o.Fields {
7 | m[f.GoFieldName] = append(m[f.GoFieldName], f)
8 | }
9 |
10 | return m
11 | }
12 |
--------------------------------------------------------------------------------
/codegen/config/testdata/autobinding/chat/model.go:
--------------------------------------------------------------------------------
1 | package chat
2 |
3 | import (
4 | "time"
5 | )
6 |
7 | type Message struct {
8 | ID string `json:"id"`
9 | Text string `json:"text"`
10 | CreatedBy string `json:"createdBy"`
11 | CreatedAt time.Time `json:"createdAt"`
12 | }
13 |
14 | type ProductSku string
15 |
16 | const (
17 | ProductSkuTrial ProductSku = "Trial"
18 | )
19 |
20 | type ChatAPI struct {
21 | ID string `json:"id"`
22 | }
23 |
--------------------------------------------------------------------------------
/codegen/config/testdata/autobinding/scalars/model/model.go:
--------------------------------------------------------------------------------
1 | package model
2 |
3 | import (
4 | "fmt"
5 | "io"
6 | "strings"
7 | )
8 |
9 | type Banned bool
10 |
11 | func (b Banned) MarshalGQL(w io.Writer) {
12 | if b {
13 | w.Write([]byte("true"))
14 | } else {
15 | w.Write([]byte("false"))
16 | }
17 | }
18 |
19 | func (b *Banned) UnmarshalGQL(v any) error {
20 | switch v := v.(type) {
21 | case string:
22 | *b = strings.ToLower(v) == "true"
23 | return nil
24 | case bool:
25 | *b = Banned(v)
26 | return nil
27 | default:
28 | return fmt.Errorf("%T is not a bool", v)
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/codegen/config/testdata/binding/model.go:
--------------------------------------------------------------------------------
1 | package binding
2 |
3 | import (
4 | "context"
5 | "fmt"
6 | "io"
7 |
8 | "github.com/99designs/gqlgen/graphql"
9 | )
10 |
11 | type Number int
12 |
13 | func (e *Number) UnmarshalGQL(v any) error {
14 | num, err := graphql.UnmarshalInt(v)
15 | if err != nil {
16 | return err
17 | }
18 | *e = Number(num)
19 | return nil
20 | }
21 |
22 | func (e Number) MarshalGQL(w io.Writer) error {
23 | fmt.Fprint(w, e)
24 | return nil
25 | }
26 |
27 | type ContextNumber int
28 |
29 | func (e *ContextNumber) UnmarshalGQLContext(ctx context.Context, v any) error {
30 | num, err := graphql.UnmarshalInt(v)
31 | if err != nil {
32 | return err
33 | }
34 | *e = Number(num)
35 | return nil
36 | }
37 |
38 | func (e ContextNumber) MarshalGQLContext(_ context.Context, w io.Writer) error {
39 | fmt.Fprint(w, e)
40 | return nil
41 | }
42 |
--------------------------------------------------------------------------------
/codegen/config/testdata/cfg/glob.yml:
--------------------------------------------------------------------------------
1 | schema:
2 | - testdata/cfg/glob/**/*.graphql
3 | exec:
4 | filename: generated.go
5 | model:
6 | filename: models_gen.go
7 | resolver:
8 | filename: resolver.go
9 | type: Resolver
10 |
--------------------------------------------------------------------------------
/codegen/config/testdata/cfg/glob/bar/bar with spaces.graphql:
--------------------------------------------------------------------------------
1 | type Query {
2 | todos: [Todo!]!
3 | }
4 |
5 | input NewTodo {
6 | text: String!
7 | userId: String!
8 | }
9 |
10 | type Mutation {
11 | createTodo(input: NewTodo!): Todo!
12 | }
13 |
--------------------------------------------------------------------------------
/codegen/config/testdata/cfg/glob/foo/foo.graphql:
--------------------------------------------------------------------------------
1 | type Todo {
2 | id: ID!
3 | text: String!
4 | done: Boolean!
5 | user: User!
6 | }
7 |
8 | type User {
9 | id: ID!
10 | name: String!
11 | }
12 |
--------------------------------------------------------------------------------
/codegen/config/testdata/cfg/goInitialisms.yml:
--------------------------------------------------------------------------------
1 | go_initialisms:
2 | replace_defaults: true
3 | initialisms:
4 | - 'CC'
5 | - 'BCC'
6 |
--------------------------------------------------------------------------------
/codegen/config/testdata/cfg/gqlgen.yml:
--------------------------------------------------------------------------------
1 | schema: outer
2 |
--------------------------------------------------------------------------------
/codegen/config/testdata/cfg/malformedconfig.yml:
--------------------------------------------------------------------------------
1 | asdf
2 |
--------------------------------------------------------------------------------
/codegen/config/testdata/cfg/otherdir/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/99designs/gqlgen/0fce010415029b53fc75b00c6dc85394f44402db/codegen/config/testdata/cfg/otherdir/.gitkeep
--------------------------------------------------------------------------------
/codegen/config/testdata/cfg/outer:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/99designs/gqlgen/0fce010415029b53fc75b00c6dc85394f44402db/codegen/config/testdata/cfg/outer
--------------------------------------------------------------------------------
/codegen/config/testdata/cfg/subdir/gqlgen.yaml:
--------------------------------------------------------------------------------
1 | schema: inner
2 |
--------------------------------------------------------------------------------
/codegen/config/testdata/cfg/subdir/inner:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/99designs/gqlgen/0fce010415029b53fc75b00c6dc85394f44402db/codegen/config/testdata/cfg/subdir/inner
--------------------------------------------------------------------------------
/codegen/config/testdata/cfg/unknownkeys.yml:
--------------------------------------------------------------------------------
1 | schema: outer
2 | unknown: foo
3 |
--------------------------------------------------------------------------------
/codegen/config/testdata/cfg/unwalkable.yml:
--------------------------------------------------------------------------------
1 | schema:
2 | - not_walkable/**/*.graphql
3 | exec:
4 | filename: generated.go
5 | model:
6 | filename: models_gen.go
7 | resolver:
8 | filename: resolver.go
9 | type: Resolver
10 |
--------------------------------------------------------------------------------
/codegen/config/testdata/defaultconfig/schema.graphql:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/99designs/gqlgen/0fce010415029b53fc75b00c6dc85394f44402db/codegen/config/testdata/defaultconfig/schema.graphql
--------------------------------------------------------------------------------
/codegen/config/testdata/enum/model.go:
--------------------------------------------------------------------------------
1 | package enum
2 |
3 | type Bar int
4 |
5 | const (
6 | BarOne Bar = iota + 1
7 | BarTwo
8 | )
9 |
10 | const (
11 | BazOne = iota + 1
12 | BazTwo
13 | )
14 |
--------------------------------------------------------------------------------
/codegen/config/testdata/example.go:
--------------------------------------------------------------------------------
1 | package config_test_data
2 |
--------------------------------------------------------------------------------
/codegen/templates/test.gotpl:
--------------------------------------------------------------------------------
1 | this is my test package
2 |
--------------------------------------------------------------------------------
/codegen/templates/test_.gotpl:
--------------------------------------------------------------------------------
1 | this will not be included
2 |
--------------------------------------------------------------------------------
/codegen/templates/testdata/a/bar/bar.go:
--------------------------------------------------------------------------------
1 | package bar
2 |
--------------------------------------------------------------------------------
/codegen/templates/testdata/b/bar/bar.go:
--------------------------------------------------------------------------------
1 | package bar
2 |
--------------------------------------------------------------------------------
/codegen/templates/testdata/pkg_mismatch/turtles.go:
--------------------------------------------------------------------------------
1 | package turtles
2 |
--------------------------------------------------------------------------------
/codegen/testserver/compliant-int/generated-compliant-strict/models.go:
--------------------------------------------------------------------------------
1 | // Code generated by github.com/99designs/gqlgen, DO NOT EDIT.
2 |
3 | package generated
4 |
5 | type Input struct {
6 | N *int32 `json:"n,omitempty"`
7 | }
8 |
9 | type Input64 struct {
10 | N *int `json:"n,omitempty"`
11 | }
12 |
13 | type Query struct {
14 | }
15 |
16 | type Result struct {
17 | N int32 `json:"n"`
18 | }
19 |
20 | type Result64 struct {
21 | N int `json:"n"`
22 | }
23 |
--------------------------------------------------------------------------------
/codegen/testserver/compliant-int/generated-default/models.go:
--------------------------------------------------------------------------------
1 | // Code generated by github.com/99designs/gqlgen, DO NOT EDIT.
2 |
3 | package generated
4 |
5 | type Input struct {
6 | N *int `json:"n,omitempty"`
7 | }
8 |
9 | type Input64 struct {
10 | N *int `json:"n,omitempty"`
11 | }
12 |
13 | type Query struct {
14 | }
15 |
16 | type Result struct {
17 | N int `json:"n"`
18 | }
19 |
20 | type Result64 struct {
21 | N int `json:"n"`
22 | }
23 |
--------------------------------------------------------------------------------
/codegen/testserver/compliant-int/gqlgen_compliant_strict.yml:
--------------------------------------------------------------------------------
1 | schema:
2 | - "*.graphql"
3 | skip_validation: true
4 | exec:
5 | package: generated
6 | filename: generated-compliant-strict/schema.go
7 | model:
8 | package: generated
9 | filename: generated-compliant-strict/models.go
10 | resolver:
11 | package: generated
12 | filename: generated-compliant-strict/resolver.go
13 |
14 | models:
15 | Int:
16 | model:
17 | - github.com/99designs/gqlgen/graphql.Int32
18 | Int64:
19 | model:
20 | - github.com/99designs/gqlgen/graphql.Int
21 | - github.com/99designs/gqlgen/graphql.Int64
22 |
--------------------------------------------------------------------------------
/codegen/testserver/compliant-int/gqlgen_default.yml:
--------------------------------------------------------------------------------
1 | schema:
2 | - "*.graphql"
3 | skip_validation: true
4 | exec:
5 | package: generated
6 | filename: generated-default/schema.go
7 | model:
8 | package: generated
9 | filename: generated-default/models.go
10 | resolver:
11 | package: generated
12 | filename: generated-default/resolver.go
13 |
--------------------------------------------------------------------------------
/codegen/testserver/compliant-int/schema.graphql:
--------------------------------------------------------------------------------
1 | scalar Int64
2 |
3 | input Input {
4 | n: Int
5 | }
6 |
7 | input Input64 {
8 | n: Int64
9 | }
10 |
11 | type Result {
12 | n: Int!
13 | }
14 |
15 | type Result64 {
16 | n: Int64!
17 | }
18 |
19 | type Query {
20 | echoIntToInt(n: Int): Int!
21 | echoInt64ToInt64(n: Int64): Int64!
22 | echoIntInputToIntObject(input: Input!): Result
23 | echoInt64InputToInt64Object(input: Input64!): Result64
24 | }
25 |
--------------------------------------------------------------------------------
/codegen/testserver/empty.go:
--------------------------------------------------------------------------------
1 | package testserver
2 |
3 | // Empty file to silence go build error complaining that codegen/testserver/ has no non-test Go source files.
4 |
--------------------------------------------------------------------------------
/codegen/testserver/followschema/builtinscalar.graphql:
--------------------------------------------------------------------------------
1 |
2 | """
3 | Since gqlgen defines default implementation for a Map scalar, this tests that the builtin is _not_
4 | added to the TypeMap
5 | """
6 | type Map {
7 | id: ID!
8 | }
9 |
--------------------------------------------------------------------------------
/codegen/testserver/followschema/bytes.go:
--------------------------------------------------------------------------------
1 | package followschema
2 |
3 | import (
4 | "fmt"
5 | "io"
6 |
7 | "github.com/99designs/gqlgen/graphql"
8 | )
9 |
10 | func MarshalBytes(b []byte) graphql.Marshaler {
11 | return graphql.WriterFunc(func(w io.Writer) {
12 | _, _ = fmt.Fprintf(w, "%q", string(b))
13 | })
14 | }
15 |
16 | func UnmarshalBytes(v any) ([]byte, error) {
17 | switch v := v.(type) {
18 | case string:
19 | return []byte(v), nil
20 | case *string:
21 | return []byte(*v), nil
22 | case []byte:
23 | return v, nil
24 | default:
25 | return nil, fmt.Errorf("%T is not []byte", v)
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/codegen/testserver/followschema/complexity.graphql:
--------------------------------------------------------------------------------
1 | extend type Query {
2 | overlapping: OverlappingFields
3 | }
4 |
5 | type OverlappingFields {
6 | oneFoo: Int! @goField(name: "foo")
7 | twoFoo: Int! @goField(name: "foo")
8 | oldFoo: Int! @goField(name: "foo", forceResolver: true)
9 | newFoo: Int!
10 | new_foo: Int!
11 | }
12 |
--------------------------------------------------------------------------------
/codegen/testserver/followschema/defaults.graphql:
--------------------------------------------------------------------------------
1 | extend type Query {
2 | defaultParameters(
3 | falsyBoolean: Boolean = false
4 | truthyBoolean: Boolean = true
5 | ): DefaultParametersMirror!
6 | }
7 |
8 | extend type Mutation {
9 | defaultInput(input: DefaultInput!): DefaultParametersMirror!
10 | }
11 |
12 | input DefaultInput {
13 | falsyBoolean: Boolean = false
14 | truthyBoolean: Boolean = true
15 | }
16 |
17 | type DefaultParametersMirror {
18 | falsyBoolean: Boolean
19 | truthyBoolean: Boolean
20 | }
21 |
--------------------------------------------------------------------------------
/codegen/testserver/followschema/defer.graphql:
--------------------------------------------------------------------------------
1 | extend type Query {
2 | deferSingle: DeferModel
3 | deferMultiple: [DeferModel!]
4 | }
5 |
6 | type DeferModel {
7 | id: ID!
8 | name: String!
9 | values: [String!]! @goField(forceResolver: true)
10 | }
11 |
--------------------------------------------------------------------------------
/codegen/testserver/followschema/embedded.graphql:
--------------------------------------------------------------------------------
1 | extend type Query {
2 | embeddedCase1: EmbeddedCase1
3 | embeddedCase2: EmbeddedCase2
4 | embeddedCase3: EmbeddedCase3
5 | }
6 |
7 | type EmbeddedCase1 @goModel(model:"followschema.EmbeddedCase1") {
8 | exportedEmbeddedPointerExportedMethod: String!
9 | }
10 |
11 | type EmbeddedCase2 @goModel(model:"followschema.EmbeddedCase2") {
12 | unexportedEmbeddedPointerExportedMethod: String!
13 | }
14 |
15 | type EmbeddedCase3 @goModel(model:"followschema.EmbeddedCase3") {
16 | unexportedEmbeddedInterfaceExportedMethod: String!
17 | }
18 |
--------------------------------------------------------------------------------
/codegen/testserver/followschema/enum.graphql:
--------------------------------------------------------------------------------
1 | enum EnumTest {
2 | OK
3 | NG
4 | }
5 |
6 | input InputWithEnumValue {
7 | enum: EnumTest!
8 | }
9 |
10 | extend type Query {
11 | enumInInput(input: InputWithEnumValue): EnumTest!
12 | }
13 |
--------------------------------------------------------------------------------
/codegen/testserver/followschema/fields_order.go:
--------------------------------------------------------------------------------
1 | package followschema
2 |
3 | type FieldsOrderInput struct {
4 | FirstField *string `json:"firstField"`
5 | }
6 |
--------------------------------------------------------------------------------
/codegen/testserver/followschema/fields_order.graphql:
--------------------------------------------------------------------------------
1 | type FieldsOrderPayload {
2 | firstFieldValue: String
3 | }
4 |
5 | input FieldsOrderInput {
6 | firstField: String
7 | overrideFirstField: String
8 | }
9 |
10 | extend type Mutation {
11 | overrideValueViaInput(input: FieldsOrderInput!): FieldsOrderPayload!
12 | }
13 |
--------------------------------------------------------------------------------
/codegen/testserver/followschema/gqlgen.yml:
--------------------------------------------------------------------------------
1 | schema:
2 | - "*.graphql"
3 | skip_validation: true
4 | exec:
5 | layout: follow-schema
6 | dir: .
7 | package: followschema
8 | model:
9 | filename: models-gen.go
10 | package: followschema
11 | resolver:
12 | filename: resolver.go
13 | package: followschema
14 | type: Resolver
15 |
16 | autobind:
17 | - "github.com/99designs/gqlgen/codegen/testserver"
18 | - "github.com/99designs/gqlgen/codegen/testserver/followschema"
19 | - "github.com/99designs/gqlgen/codegen/testserver/followschema/introspection"
20 | - "github.com/99designs/gqlgen/codegen/testserver/followschema/invalid-packagename"
21 |
22 | models:
23 | Email:
24 | model: "github.com/99designs/gqlgen/codegen/testserver/followschema.Email"
25 | StringFromContextFunction:
26 | model: "github.com/99designs/gqlgen/codegen/testserver/followschema.StringFromContextFunction"
27 |
--------------------------------------------------------------------------------
/codegen/testserver/followschema/introspection/it.go:
--------------------------------------------------------------------------------
1 | package introspection
2 |
3 | type It struct {
4 | ID string
5 | }
6 |
--------------------------------------------------------------------------------
/codegen/testserver/followschema/invalid-packagename/invalid-identifier.go:
--------------------------------------------------------------------------------
1 | package invalid_packagename
2 |
3 | type InvalidIdentifier struct {
4 | ID int
5 | }
6 |
--------------------------------------------------------------------------------
/codegen/testserver/followschema/issue896.graphql:
--------------------------------------------------------------------------------
1 | # This example should build stable output. If the file content starts
2 | # alternating nondeterministically between two outputs, then see
3 | # https://github.com/99designs/gqlgen/issues/896.
4 |
5 | extend schema {
6 | query: Query
7 | subscription: Subscription
8 | }
9 |
10 | type CheckIssue896 {id: Int}
11 |
12 | extend type Query {
13 | issue896a: [CheckIssue896!] # Note the "!" or lack thereof.
14 | }
15 |
16 | extend type Subscription {
17 | issue896b: [CheckIssue896] # Note the "!" or lack thereof.
18 | }
19 |
--------------------------------------------------------------------------------
/codegen/testserver/followschema/loops.graphql:
--------------------------------------------------------------------------------
1 | type LoopA {
2 | b: LoopB!
3 | }
4 |
5 | type LoopB {
6 | a: LoopA!
7 | }
8 |
--------------------------------------------------------------------------------
/codegen/testserver/followschema/maps.go:
--------------------------------------------------------------------------------
1 | package followschema
2 |
3 | import (
4 | "io"
5 | "strconv"
6 | )
7 |
8 | type MapNested struct {
9 | Value CustomScalar
10 | }
11 |
12 | type CustomScalar struct {
13 | value int64
14 | }
15 |
16 | func (s *CustomScalar) UnmarshalGQL(v any) (err error) {
17 | switch v := v.(type) {
18 | case string:
19 | s.value, err = strconv.ParseInt(v, 10, 64)
20 | case int64:
21 | s.value = v
22 | }
23 | return
24 | }
25 |
26 | func (s CustomScalar) MarshalGQL(w io.Writer) {
27 | _, _ = w.Write([]byte(strconv.Quote(strconv.FormatInt(s.value, 10))))
28 | }
29 |
--------------------------------------------------------------------------------
/codegen/testserver/followschema/mutation_with_custom_scalar.go:
--------------------------------------------------------------------------------
1 | package followschema
2 |
3 | import (
4 | "encoding/json"
5 | "errors"
6 | "io"
7 | "regexp"
8 | )
9 |
10 | var re = regexp.MustCompile("^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$")
11 |
12 | type Email string
13 |
14 | func (value *Email) UnmarshalGQL(v any) error {
15 | input, ok := v.(string)
16 | if !ok {
17 | return errors.New("email expects a string value")
18 | }
19 | if !re.MatchString(input) {
20 | return errors.New("invalid email format")
21 | }
22 | *value = Email(input)
23 | return nil
24 | }
25 |
26 | func (value Email) MarshalGQL(w io.Writer) {
27 | output, _ := json.Marshal(string(value))
28 | w.Write(output)
29 | }
30 |
--------------------------------------------------------------------------------
/codegen/testserver/followschema/mutation_with_custom_scalar.graphql:
--------------------------------------------------------------------------------
1 | extend type Mutation {
2 | updateSomething(input: SpecialInput!): String!
3 | }
4 |
5 | scalar Email
6 |
7 | input SpecialInput {
8 | nesting: NestedInput!
9 | }
10 |
11 | input NestedInput {
12 | field: Email!
13 | }
14 |
--------------------------------------------------------------------------------
/codegen/testserver/followschema/nulls.graphql:
--------------------------------------------------------------------------------
1 | extend type Query {
2 | errorBubble: Error
3 | errorBubbleList: [Error!]
4 | errorList: [Error]
5 | errors: Errors
6 | valid: String!
7 | invalid: String!
8 | }
9 |
10 | extend type Subscription {
11 | errorRequired: Error!
12 | }
13 |
14 | type Errors {
15 | a: Error!
16 | b: Error!
17 | c: Error!
18 | d: Error!
19 | e: Error!
20 | }
21 |
22 | type Error {
23 | id: ID!
24 | errorOnNonRequiredField: String
25 | errorOnRequiredField: String!
26 | nilOnRequiredField: String!
27 | }
28 |
--------------------------------------------------------------------------------
/codegen/testserver/followschema/otherpkg/model.go:
--------------------------------------------------------------------------------
1 | package otherpkg
2 |
3 | type (
4 | Scalar string
5 | Map map[string]string
6 | Slice []string
7 | )
8 |
9 | type Struct struct {
10 | Name Scalar
11 | Desc *Scalar
12 | }
13 |
--------------------------------------------------------------------------------
/codegen/testserver/followschema/panics.graphql:
--------------------------------------------------------------------------------
1 | extend type Query {
2 | panics: Panics
3 | }
4 |
5 | type Panics {
6 | fieldScalarMarshal: [MarshalPanic!]!
7 | fieldFuncMarshal(u: [MarshalPanic!]!): [MarshalPanic!]!
8 | argUnmarshal(u: [MarshalPanic!]!): Boolean!
9 |
10 | }
11 |
12 | scalar MarshalPanic
13 |
--------------------------------------------------------------------------------
/codegen/testserver/followschema/primitive_objects.graphql:
--------------------------------------------------------------------------------
1 | extend type Query {
2 | primitiveObject: [Primitive!]!
3 | primitiveStringObject: [PrimitiveString!]!
4 | }
5 |
6 | type Primitive {
7 | value: Int!
8 | squared: Int!
9 | }
10 |
11 | type PrimitiveString {
12 | value: String!
13 | doubled: String!
14 | len: Int!
15 | }
16 |
--------------------------------------------------------------------------------
/codegen/testserver/followschema/ptr_to_any.go:
--------------------------------------------------------------------------------
1 | package followschema
2 |
3 | type PtrToAnyContainer struct {
4 | PtrToAny *any
5 | }
6 |
7 | func (c *PtrToAnyContainer) Binding() *any {
8 | return c.PtrToAny
9 | }
10 |
--------------------------------------------------------------------------------
/codegen/testserver/followschema/ptr_to_any.graphql:
--------------------------------------------------------------------------------
1 | scalar Any
2 |
3 | type PtrToAnyContainer {
4 | ptrToAny: Any
5 | binding: Any
6 | }
7 |
8 | extend type Query {
9 | ptrToAnyContainer: PtrToAnyContainer!
10 | }
11 |
--------------------------------------------------------------------------------
/codegen/testserver/followschema/ptr_to_ptr_input.go:
--------------------------------------------------------------------------------
1 | package followschema
2 |
3 | type PtrToPtrOuter struct {
4 | Name string
5 | Inner *PtrToPtrInner
6 | StupidInner *******PtrToPtrInner
7 | }
8 |
9 | type PtrToPtrInner struct {
10 | Key string
11 | Value string
12 | }
13 |
14 | type UpdatePtrToPtrOuter struct {
15 | Name *string
16 | Inner **UpdatePtrToPtrInner
17 | StupidInner ********UpdatePtrToPtrInner
18 | }
19 |
20 | type UpdatePtrToPtrInner struct {
21 | Key *string
22 | Value *string
23 | }
24 |
--------------------------------------------------------------------------------
/codegen/testserver/followschema/ptr_to_ptr_input.graphql:
--------------------------------------------------------------------------------
1 | type PtrToPtrOuter {
2 | name: String!
3 | inner: PtrToPtrInner
4 | stupidInner: PtrToPtrInner
5 | }
6 |
7 | type PtrToPtrInner {
8 | key: String!
9 | value: String!
10 | }
11 |
12 | input UpdatePtrToPtrOuter {
13 | name: String
14 | inner: UpdatePtrToPtrInner
15 | stupidInner: UpdatePtrToPtrInner
16 | }
17 |
18 | input UpdatePtrToPtrInner {
19 | key: String
20 | value: String
21 | }
22 |
23 | extend type Mutation {
24 | updatePtrToPtr(input: UpdatePtrToPtrOuter!): PtrToPtrOuter!
25 | }
26 |
--------------------------------------------------------------------------------
/codegen/testserver/followschema/ptr_to_slice.go:
--------------------------------------------------------------------------------
1 | package followschema
2 |
3 | type PtrToSliceContainer struct {
4 | PtrToSlice *[]string
5 | }
6 |
--------------------------------------------------------------------------------
/codegen/testserver/followschema/ptr_to_slice.graphql:
--------------------------------------------------------------------------------
1 | type PtrToSliceContainer {
2 | ptrToSlice: [String!]
3 | }
4 |
5 | extend type Query {
6 | ptrToSliceContainer: PtrToSliceContainer!
7 | }
8 |
--------------------------------------------------------------------------------
/codegen/testserver/followschema/recursive.go:
--------------------------------------------------------------------------------
1 | package followschema
2 |
3 | type RecursiveInputSlice struct {
4 | Self []RecursiveInputSlice
5 | }
6 |
--------------------------------------------------------------------------------
/codegen/testserver/followschema/scalar_context.graphql:
--------------------------------------------------------------------------------
1 | extend type Query {
2 | infinity: Float!
3 | stringFromContextInterface: StringFromContextInterface!
4 | stringFromContextFunction: StringFromContextFunction!
5 | }
6 |
7 | scalar StringFromContextInterface
8 | scalar StringFromContextFunction
9 |
--------------------------------------------------------------------------------
/codegen/testserver/followschema/scalar_default.graphql:
--------------------------------------------------------------------------------
1 | extend type Query {
2 | defaultScalar(arg: DefaultScalarImplementation! = "default"): DefaultScalarImplementation!
3 | }
4 |
5 | """ This doesnt have an implementation in the typemap, so it should act like a string """
6 | scalar DefaultScalarImplementation
7 |
8 | type EmbeddedDefaultScalar {
9 | value: DefaultScalarImplementation
10 | }
11 |
--------------------------------------------------------------------------------
/codegen/testserver/followschema/skip-include.graphql:
--------------------------------------------------------------------------------
1 | extend type Query {
2 | skipInclude: SkipIncludeTestType
3 | }
4 |
5 | type SkipIncludeTestType {
6 | a: String
7 | b: String
8 | }
9 |
--------------------------------------------------------------------------------
/codegen/testserver/followschema/slices.graphql:
--------------------------------------------------------------------------------
1 | extend type Query {
2 | slices: Slices
3 | scalarSlice: Bytes!
4 | }
5 |
6 | type Slices {
7 | test1: [String]
8 | test2: [String!]
9 | test3: [String]!
10 | test4: [String!]!
11 | }
12 |
13 | scalar Bytes
14 |
--------------------------------------------------------------------------------
/codegen/testserver/followschema/thirdparty.go:
--------------------------------------------------------------------------------
1 | package followschema
2 |
3 | import (
4 | "fmt"
5 | "io"
6 | "strconv"
7 |
8 | "github.com/99designs/gqlgen/graphql"
9 | )
10 |
11 | type ThirdParty struct {
12 | str string
13 | }
14 |
15 | func MarshalThirdParty(tp ThirdParty) graphql.Marshaler {
16 | return graphql.WriterFunc(func(w io.Writer) {
17 | _, err := io.WriteString(w, strconv.Quote(tp.str))
18 | if err != nil {
19 | panic(err)
20 | }
21 | })
22 | }
23 |
24 | func UnmarshalThirdParty(input any) (ThirdParty, error) {
25 | switch input := input.(type) {
26 | case string:
27 | return ThirdParty{str: input}, nil
28 | default:
29 | return ThirdParty{}, fmt.Errorf("unknown type for input: %s", input)
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/codegen/testserver/followschema/typefallback.graphql:
--------------------------------------------------------------------------------
1 | extend type Query {
2 | fallback(arg: FallbackToStringEncoding!): FallbackToStringEncoding!
3 | }
4 |
5 | enum FallbackToStringEncoding {
6 | A
7 | B
8 | C
9 | }
10 |
--------------------------------------------------------------------------------
/codegen/testserver/followschema/useptr.graphql:
--------------------------------------------------------------------------------
1 | type A {
2 | id: ID!
3 | }
4 |
5 | type B {
6 | id: ID!
7 | }
8 |
9 | union TestUnion = A | B
10 |
11 | extend type Query {
12 | optionalUnion: TestUnion
13 | }
14 |
--------------------------------------------------------------------------------
/codegen/testserver/followschema/useptr_test.go:
--------------------------------------------------------------------------------
1 | package followschema
2 |
3 | import (
4 | "reflect"
5 | "testing"
6 |
7 | "github.com/stretchr/testify/require"
8 | )
9 |
10 | func TestUserPtr(t *testing.T) {
11 | s := &Stub{}
12 | r := reflect.TypeOf(s.QueryResolver.OptionalUnion)
13 | require.Equal(t, reflect.Interface, r.Out(0).Kind())
14 | }
15 |
--------------------------------------------------------------------------------
/codegen/testserver/followschema/v-ok.go:
--------------------------------------------------------------------------------
1 | package followschema
2 |
3 | // VOkCaseValue model
4 | type VOkCaseValue struct{}
5 |
6 | func (v VOkCaseValue) Value() (string, bool) {
7 | return "hi", true
8 | }
9 |
10 | // VOkCaseNil model
11 | type VOkCaseNil struct{}
12 |
13 | func (v VOkCaseNil) Value() (string, bool) {
14 | return "", false
15 | }
16 |
--------------------------------------------------------------------------------
/codegen/testserver/followschema/v-ok.graphql:
--------------------------------------------------------------------------------
1 | extend type Query {
2 | vOkCaseValue: VOkCaseValue
3 | vOkCaseNil: VOkCaseNil
4 | }
5 |
6 | type VOkCaseValue @goModel(model:"followschema.VOkCaseValue") {
7 | value: String
8 | }
9 |
10 | type VOkCaseNil @goModel(model:"followschema.VOkCaseNil") {
11 | value: String
12 | }
13 |
--------------------------------------------------------------------------------
/codegen/testserver/followschema/variadic.go:
--------------------------------------------------------------------------------
1 | package followschema
2 |
3 | import (
4 | "context"
5 | "strconv"
6 | )
7 |
8 | type VariadicModel struct{}
9 |
10 | type VariadicModelOption func(*VariadicModel)
11 |
12 | func (v VariadicModel) Value(ctx context.Context, rank int, opts ...VariadicModelOption) (string, error) {
13 | return strconv.Itoa(rank), nil
14 | }
15 |
--------------------------------------------------------------------------------
/codegen/testserver/followschema/variadic.graphql:
--------------------------------------------------------------------------------
1 | extend type Query {
2 | variadicModel: VariadicModel
3 | }
4 |
5 | type VariadicModel {
6 | value(rank: Int!): String
7 | }
8 |
--------------------------------------------------------------------------------
/codegen/testserver/followschema/weird_type_cases.graphql:
--------------------------------------------------------------------------------
1 | # regression test for https://github.com/99designs/gqlgen/issues/583
2 |
3 | type asdfIt { id: ID! }
4 | type iIt { id: ID! }
5 | type AIt { id: ID! }
6 | type XXIt { id: ID! }
7 | type AbIt { id: ID! }
8 | type XxIt { id: ID! }
9 |
--------------------------------------------------------------------------------
/codegen/testserver/followschema/wrapped_type.go:
--------------------------------------------------------------------------------
1 | package followschema
2 |
3 | import "github.com/99designs/gqlgen/codegen/testserver/followschema/otherpkg"
4 |
5 | type (
6 | WrappedScalar = otherpkg.Scalar
7 | WrappedStruct otherpkg.Struct
8 | WrappedMap otherpkg.Map
9 | WrappedSlice otherpkg.Slice
10 | )
11 |
--------------------------------------------------------------------------------
/codegen/testserver/followschema/wrapped_type.graphql:
--------------------------------------------------------------------------------
1 | # regression test for https://github.com/99designs/gqlgen/issues/721
2 |
3 | extend type Query {
4 | wrappedStruct: WrappedStruct!
5 | wrappedScalar: WrappedScalar!
6 | wrappedMap: WrappedMap!
7 | wrappedSlice: WrappedSlice!
8 | }
9 |
10 | type WrappedStruct { name: WrappedScalar!, desc: WrappedScalar }
11 | scalar WrappedScalar
12 | type WrappedMap { get(key: String!): String! }
13 | type WrappedSlice { get(idx: Int!): String! }
14 |
--------------------------------------------------------------------------------
/codegen/testserver/nullabledirectives/directive.graphql:
--------------------------------------------------------------------------------
1 | directive @populate(value: String!) on ARGUMENT_DEFINITION
2 | directive @noop on ARGUMENT_DEFINITION
3 |
4 | type Query {
5 | directiveSingleNullableArg(
6 | arg1: String @populate(value: "test") @noop,
7 | ): String
8 | }
9 |
--------------------------------------------------------------------------------
/codegen/testserver/nullabledirectives/generated/models/models-gen.go:
--------------------------------------------------------------------------------
1 | // Code generated by github.com/99designs/gqlgen, DO NOT EDIT.
2 |
3 | package models
4 |
5 | type Query struct {
6 | }
7 |
--------------------------------------------------------------------------------
/codegen/testserver/nullabledirectives/gqlgen.yml:
--------------------------------------------------------------------------------
1 | schema:
2 | - "*.graphql"
3 | skip_validation: true
4 | exec:
5 | layout: follow-schema
6 | dir: generated
7 | package: generated
8 | model:
9 | filename: generated/models/models-gen.go
10 | package: models
11 | resolver:
12 | filename: generated/resolvers/resolver.go
13 | package: resolver
14 | type: Resolver
15 |
16 | call_argument_directives_with_null: true
17 |
--------------------------------------------------------------------------------
/codegen/testserver/nullabledirectives/stub.go:
--------------------------------------------------------------------------------
1 | // Code generated by github.com/99designs/gqlgen, DO NOT EDIT.
2 |
3 | package followschema
4 |
5 | import (
6 | "context"
7 |
8 | "github.com/99designs/gqlgen/codegen/testserver/nullabledirectives/generated"
9 | )
10 |
11 | type Stub struct {
12 | QueryResolver struct {
13 | DirectiveSingleNullableArg func(ctx context.Context, arg1 *string) (*string, error)
14 | }
15 | }
16 |
17 | func (r *Stub) Query() generated.QueryResolver {
18 | return &stubQuery{r}
19 | }
20 |
21 | type stubQuery struct{ *Stub }
22 |
23 | func (r *stubQuery) DirectiveSingleNullableArg(ctx context.Context, arg1 *string) (*string, error) {
24 | return r.QueryResolver.DirectiveSingleNullableArg(ctx, arg1)
25 | }
26 |
--------------------------------------------------------------------------------
/codegen/testserver/singlefile/builtinscalar.graphql:
--------------------------------------------------------------------------------
1 |
2 | """
3 | Since gqlgen defines default implementation for a Map scalar, this tests that the builtin is _not_
4 | added to the TypeMap
5 | """
6 | type Map {
7 | id: ID!
8 | }
9 |
--------------------------------------------------------------------------------
/codegen/testserver/singlefile/bytes.go:
--------------------------------------------------------------------------------
1 | package singlefile
2 |
3 | import (
4 | "fmt"
5 | "io"
6 |
7 | "github.com/99designs/gqlgen/graphql"
8 | )
9 |
10 | func MarshalBytes(b []byte) graphql.Marshaler {
11 | return graphql.WriterFunc(func(w io.Writer) {
12 | _, _ = fmt.Fprintf(w, "%q", string(b))
13 | })
14 | }
15 |
16 | func UnmarshalBytes(v any) ([]byte, error) {
17 | switch v := v.(type) {
18 | case string:
19 | return []byte(v), nil
20 | case *string:
21 | return []byte(*v), nil
22 | case []byte:
23 | return v, nil
24 | default:
25 | return nil, fmt.Errorf("%T is not []byte", v)
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/codegen/testserver/singlefile/complexity.graphql:
--------------------------------------------------------------------------------
1 | extend type Query {
2 | overlapping: OverlappingFields
3 | }
4 |
5 | type OverlappingFields {
6 | oneFoo: Int! @goField(name: "foo")
7 | twoFoo: Int! @goField(name: "foo")
8 | oldFoo: Int! @goField(name: "foo", forceResolver: true)
9 | newFoo: Int!
10 | new_foo: Int!
11 | }
12 |
--------------------------------------------------------------------------------
/codegen/testserver/singlefile/defaults.graphql:
--------------------------------------------------------------------------------
1 | extend type Query {
2 | defaultParameters(
3 | falsyBoolean: Boolean = false
4 | truthyBoolean: Boolean = true
5 | ): DefaultParametersMirror!
6 | }
7 |
8 | extend type Mutation {
9 | defaultInput(input: DefaultInput!): DefaultParametersMirror!
10 | }
11 |
12 | input DefaultInput {
13 | falsyBoolean: Boolean = false
14 | truthyBoolean: Boolean = true
15 | }
16 |
17 | type DefaultParametersMirror {
18 | falsyBoolean: Boolean
19 | truthyBoolean: Boolean
20 | }
21 |
--------------------------------------------------------------------------------
/codegen/testserver/singlefile/defer.graphql:
--------------------------------------------------------------------------------
1 | extend type Query {
2 | deferSingle: DeferModel
3 | deferMultiple: [DeferModel!]
4 | }
5 |
6 | type DeferModel {
7 | id: ID!
8 | name: String!
9 | values: [String!]! @goField(forceResolver: true)
10 | }
11 |
--------------------------------------------------------------------------------
/codegen/testserver/singlefile/embedded.graphql:
--------------------------------------------------------------------------------
1 | extend type Query {
2 | embeddedCase1: EmbeddedCase1
3 | embeddedCase2: EmbeddedCase2
4 | embeddedCase3: EmbeddedCase3
5 | }
6 |
7 | type EmbeddedCase1 @goModel(model:"singlefile.EmbeddedCase1") {
8 | exportedEmbeddedPointerExportedMethod: String!
9 | }
10 |
11 | type EmbeddedCase2 @goModel(model:"singlefile.EmbeddedCase2") {
12 | unexportedEmbeddedPointerExportedMethod: String!
13 | }
14 |
15 | type EmbeddedCase3 @goModel(model:"singlefile.EmbeddedCase3") {
16 | unexportedEmbeddedInterfaceExportedMethod: String!
17 | }
18 |
--------------------------------------------------------------------------------
/codegen/testserver/singlefile/enum.graphql:
--------------------------------------------------------------------------------
1 | enum EnumTest {
2 | OK
3 | NG
4 | }
5 |
6 | input InputWithEnumValue {
7 | enum: EnumTest!
8 | }
9 |
10 | extend type Query {
11 | enumInInput(input: InputWithEnumValue): EnumTest!
12 | }
13 |
--------------------------------------------------------------------------------
/codegen/testserver/singlefile/fields_order.go:
--------------------------------------------------------------------------------
1 | package singlefile
2 |
3 | type FieldsOrderInput struct {
4 | FirstField *string `json:"firstField"`
5 | }
6 |
--------------------------------------------------------------------------------
/codegen/testserver/singlefile/fields_order.graphql:
--------------------------------------------------------------------------------
1 | type FieldsOrderPayload {
2 | firstFieldValue: String
3 | }
4 |
5 | input FieldsOrderInput {
6 | firstField: String
7 | overrideFirstField: String
8 | }
9 |
10 | extend type Mutation {
11 | overrideValueViaInput(input: FieldsOrderInput!): FieldsOrderPayload!
12 | }
13 |
--------------------------------------------------------------------------------
/codegen/testserver/singlefile/gqlgen.yml:
--------------------------------------------------------------------------------
1 | schema:
2 | - "*.graphql"
3 | skip_validation: true
4 | exec:
5 | filename: generated.go
6 | package: singlefile
7 | model:
8 | filename: models-gen.go
9 | package: singlefile
10 | resolver:
11 | filename: resolver.go
12 | package: singlefile
13 | type: Resolver
14 |
15 | autobind:
16 | - "github.com/99designs/gqlgen/codegen/testserver"
17 | - "github.com/99designs/gqlgen/codegen/testserver/singlefile"
18 | - "github.com/99designs/gqlgen/codegen/testserver/singlefile/introspection"
19 | - "github.com/99designs/gqlgen/codegen/testserver/singlefile/invalid-packagename"
20 |
21 | models:
22 | Email:
23 | model: "github.com/99designs/gqlgen/codegen/testserver/singlefile.Email"
24 | StringFromContextFunction:
25 | model: "github.com/99designs/gqlgen/codegen/testserver/singlefile.StringFromContextFunction"
26 |
--------------------------------------------------------------------------------
/codegen/testserver/singlefile/introspection/it.go:
--------------------------------------------------------------------------------
1 | package introspection
2 |
3 | type It struct {
4 | ID string
5 | }
6 |
--------------------------------------------------------------------------------
/codegen/testserver/singlefile/invalid-packagename/invalid-identifier.go:
--------------------------------------------------------------------------------
1 | package invalid_packagename
2 |
3 | type InvalidIdentifier struct {
4 | ID int
5 | }
6 |
--------------------------------------------------------------------------------
/codegen/testserver/singlefile/issue896.graphql:
--------------------------------------------------------------------------------
1 | # This example should build stable output. If the file content starts
2 | # alternating nondeterministically between two outputs, then see
3 | # https://github.com/99designs/gqlgen/issues/896.
4 |
5 | extend schema {
6 | query: Query
7 | subscription: Subscription
8 | }
9 |
10 | type CheckIssue896 {id: Int}
11 |
12 | extend type Query {
13 | issue896a: [CheckIssue896!] # Note the "!" or lack thereof.
14 | }
15 |
16 | extend type Subscription {
17 | issue896b: [CheckIssue896] # Note the "!" or lack thereof.
18 | }
19 |
--------------------------------------------------------------------------------
/codegen/testserver/singlefile/loops.graphql:
--------------------------------------------------------------------------------
1 | type LoopA {
2 | b: LoopB!
3 | }
4 |
5 | type LoopB {
6 | a: LoopA!
7 | }
8 |
--------------------------------------------------------------------------------
/codegen/testserver/singlefile/maps.go:
--------------------------------------------------------------------------------
1 | package singlefile
2 |
3 | import (
4 | "io"
5 | "strconv"
6 | )
7 |
8 | type MapNested struct {
9 | Value CustomScalar
10 | }
11 |
12 | type CustomScalar struct {
13 | value int64
14 | }
15 |
16 | func (s *CustomScalar) UnmarshalGQL(v any) (err error) {
17 | switch v := v.(type) {
18 | case string:
19 | s.value, err = strconv.ParseInt(v, 10, 64)
20 | case int64:
21 | s.value = v
22 | }
23 | return
24 | }
25 |
26 | func (s CustomScalar) MarshalGQL(w io.Writer) {
27 | _, _ = w.Write([]byte(strconv.Quote(strconv.FormatInt(s.value, 10))))
28 | }
29 |
--------------------------------------------------------------------------------
/codegen/testserver/singlefile/mutation_with_custom_scalar.go:
--------------------------------------------------------------------------------
1 | package singlefile
2 |
3 | import (
4 | "encoding/json"
5 | "errors"
6 | "io"
7 | "regexp"
8 | )
9 |
10 | var re = regexp.MustCompile("^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$")
11 |
12 | type Email string
13 |
14 | func (value *Email) UnmarshalGQL(v any) error {
15 | input, ok := v.(string)
16 | if !ok {
17 | return errors.New("email expects a string value")
18 | }
19 | if !re.MatchString(input) {
20 | return errors.New("invalid email format")
21 | }
22 | *value = Email(input)
23 | return nil
24 | }
25 |
26 | func (value Email) MarshalGQL(w io.Writer) {
27 | output, _ := json.Marshal(string(value))
28 | w.Write(output)
29 | }
30 |
--------------------------------------------------------------------------------
/codegen/testserver/singlefile/mutation_with_custom_scalar.graphql:
--------------------------------------------------------------------------------
1 | extend type Mutation {
2 | updateSomething(input: SpecialInput!): String!
3 | }
4 |
5 | scalar Email
6 |
7 | input SpecialInput {
8 | nesting: NestedInput!
9 | }
10 |
11 | input NestedInput {
12 | field: Email!
13 | }
14 |
--------------------------------------------------------------------------------
/codegen/testserver/singlefile/nulls.graphql:
--------------------------------------------------------------------------------
1 | extend type Query {
2 | errorBubble: Error
3 | errorBubbleList: [Error!]
4 | errorList: [Error]
5 | errors: Errors
6 | valid: String!
7 | invalid: String!
8 | }
9 |
10 | extend type Subscription {
11 | errorRequired: Error!
12 | }
13 |
14 | type Errors {
15 | a: Error!
16 | b: Error!
17 | c: Error!
18 | d: Error!
19 | e: Error!
20 | }
21 |
22 | type Error {
23 | id: ID!
24 | errorOnNonRequiredField: String
25 | errorOnRequiredField: String!
26 | nilOnRequiredField: String!
27 | }
28 |
--------------------------------------------------------------------------------
/codegen/testserver/singlefile/otherpkg/model.go:
--------------------------------------------------------------------------------
1 | package otherpkg
2 |
3 | type (
4 | Scalar string
5 | Map map[string]string
6 | Slice []string
7 | )
8 |
9 | type Struct struct {
10 | Name Scalar
11 | Desc *Scalar
12 | }
13 |
--------------------------------------------------------------------------------
/codegen/testserver/singlefile/panics.graphql:
--------------------------------------------------------------------------------
1 | extend type Query {
2 | panics: Panics
3 | }
4 |
5 | type Panics {
6 | fieldScalarMarshal: [MarshalPanic!]!
7 | fieldFuncMarshal(u: [MarshalPanic!]!): [MarshalPanic!]!
8 | argUnmarshal(u: [MarshalPanic!]!): Boolean!
9 |
10 | }
11 |
12 | scalar MarshalPanic
13 |
--------------------------------------------------------------------------------
/codegen/testserver/singlefile/primitive_objects.graphql:
--------------------------------------------------------------------------------
1 | extend type Query {
2 | primitiveObject: [Primitive!]!
3 | primitiveStringObject: [PrimitiveString!]!
4 | }
5 |
6 | type Primitive {
7 | value: Int!
8 | squared: Int!
9 | }
10 |
11 | type PrimitiveString {
12 | value: String!
13 | doubled: String!
14 | len: Int!
15 | }
16 |
--------------------------------------------------------------------------------
/codegen/testserver/singlefile/ptr_to_any.go:
--------------------------------------------------------------------------------
1 | package singlefile
2 |
3 | type PtrToAnyContainer struct {
4 | PtrToAny *any
5 | }
6 |
7 | func (c *PtrToAnyContainer) Binding() *any {
8 | return c.PtrToAny
9 | }
10 |
--------------------------------------------------------------------------------
/codegen/testserver/singlefile/ptr_to_any.graphql:
--------------------------------------------------------------------------------
1 | scalar Any
2 |
3 | type PtrToAnyContainer {
4 | ptrToAny: Any
5 | binding: Any
6 | }
7 |
8 | extend type Query {
9 | ptrToAnyContainer: PtrToAnyContainer!
10 | }
11 |
--------------------------------------------------------------------------------
/codegen/testserver/singlefile/ptr_to_ptr_input.go:
--------------------------------------------------------------------------------
1 | package singlefile
2 |
3 | type PtrToPtrOuter struct {
4 | Name string
5 | Inner *PtrToPtrInner
6 | StupidInner *******PtrToPtrInner
7 | }
8 |
9 | type PtrToPtrInner struct {
10 | Key string
11 | Value string
12 | }
13 |
14 | type UpdatePtrToPtrOuter struct {
15 | Name *string
16 | Inner **UpdatePtrToPtrInner
17 | StupidInner ********UpdatePtrToPtrInner
18 | }
19 |
20 | type UpdatePtrToPtrInner struct {
21 | Key *string
22 | Value *string
23 | }
24 |
--------------------------------------------------------------------------------
/codegen/testserver/singlefile/ptr_to_ptr_input.graphql:
--------------------------------------------------------------------------------
1 | type PtrToPtrOuter {
2 | name: String!
3 | inner: PtrToPtrInner
4 | stupidInner: PtrToPtrInner
5 | }
6 |
7 | type PtrToPtrInner {
8 | key: String!
9 | value: String!
10 | }
11 |
12 | input UpdatePtrToPtrOuter {
13 | name: String
14 | inner: UpdatePtrToPtrInner
15 | stupidInner: UpdatePtrToPtrInner
16 | }
17 |
18 | input UpdatePtrToPtrInner {
19 | key: String
20 | value: String
21 | }
22 |
23 | extend type Mutation {
24 | updatePtrToPtr(input: UpdatePtrToPtrOuter!): PtrToPtrOuter!
25 | }
26 |
--------------------------------------------------------------------------------
/codegen/testserver/singlefile/ptr_to_slice.go:
--------------------------------------------------------------------------------
1 | package singlefile
2 |
3 | type PtrToSliceContainer struct {
4 | PtrToSlice *[]string
5 | }
6 |
--------------------------------------------------------------------------------
/codegen/testserver/singlefile/ptr_to_slice.graphql:
--------------------------------------------------------------------------------
1 | type PtrToSliceContainer {
2 | ptrToSlice: [String!]
3 | }
4 |
5 | extend type Query {
6 | ptrToSliceContainer: PtrToSliceContainer!
7 | }
8 |
--------------------------------------------------------------------------------
/codegen/testserver/singlefile/recursive.go:
--------------------------------------------------------------------------------
1 | package singlefile
2 |
3 | type RecursiveInputSlice struct {
4 | Self []RecursiveInputSlice
5 | }
6 |
--------------------------------------------------------------------------------
/codegen/testserver/singlefile/scalar_context.graphql:
--------------------------------------------------------------------------------
1 | extend type Query {
2 | infinity: Float!
3 | stringFromContextInterface: StringFromContextInterface!
4 | stringFromContextFunction: StringFromContextFunction!
5 | }
6 |
7 | scalar StringFromContextInterface
8 | scalar StringFromContextFunction
9 |
--------------------------------------------------------------------------------
/codegen/testserver/singlefile/scalar_default.graphql:
--------------------------------------------------------------------------------
1 | extend type Query {
2 | defaultScalar(arg: DefaultScalarImplementation! = "default"): DefaultScalarImplementation!
3 | }
4 |
5 | """ This doesnt have an implementation in the typemap, so it should act like a string """
6 | scalar DefaultScalarImplementation
7 |
8 | type EmbeddedDefaultScalar {
9 | value: DefaultScalarImplementation
10 | }
11 |
--------------------------------------------------------------------------------
/codegen/testserver/singlefile/skip-include.graphql:
--------------------------------------------------------------------------------
1 | extend type Query {
2 | skipInclude: SkipIncludeTestType
3 | }
4 |
5 | type SkipIncludeTestType {
6 | a: String
7 | b: String
8 | }
9 |
--------------------------------------------------------------------------------
/codegen/testserver/singlefile/slices.graphql:
--------------------------------------------------------------------------------
1 | extend type Query {
2 | slices: Slices
3 | scalarSlice: Bytes!
4 | }
5 |
6 | type Slices {
7 | test1: [String]
8 | test2: [String!]
9 | test3: [String]!
10 | test4: [String!]!
11 | }
12 |
13 | scalar Bytes
14 |
--------------------------------------------------------------------------------
/codegen/testserver/singlefile/thirdparty.go:
--------------------------------------------------------------------------------
1 | package singlefile
2 |
3 | import (
4 | "fmt"
5 | "io"
6 | "strconv"
7 |
8 | "github.com/99designs/gqlgen/graphql"
9 | )
10 |
11 | type ThirdParty struct {
12 | str string
13 | }
14 |
15 | func MarshalThirdParty(tp ThirdParty) graphql.Marshaler {
16 | return graphql.WriterFunc(func(w io.Writer) {
17 | _, err := io.WriteString(w, strconv.Quote(tp.str))
18 | if err != nil {
19 | panic(err)
20 | }
21 | })
22 | }
23 |
24 | func UnmarshalThirdParty(input any) (ThirdParty, error) {
25 | switch input := input.(type) {
26 | case string:
27 | return ThirdParty{str: input}, nil
28 | default:
29 | return ThirdParty{}, fmt.Errorf("unknown type for input: %s", input)
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/codegen/testserver/singlefile/typefallback.graphql:
--------------------------------------------------------------------------------
1 | extend type Query {
2 | fallback(arg: FallbackToStringEncoding!): FallbackToStringEncoding!
3 | }
4 |
5 | enum FallbackToStringEncoding {
6 | A
7 | B
8 | C
9 | }
10 |
--------------------------------------------------------------------------------
/codegen/testserver/singlefile/useptr.graphql:
--------------------------------------------------------------------------------
1 | type A {
2 | id: ID!
3 | }
4 |
5 | type B {
6 | id: ID!
7 | }
8 |
9 | union TestUnion = A | B
10 |
11 | extend type Query {
12 | optionalUnion: TestUnion
13 | }
14 |
--------------------------------------------------------------------------------
/codegen/testserver/singlefile/useptr_test.go:
--------------------------------------------------------------------------------
1 | package singlefile
2 |
3 | import (
4 | "reflect"
5 | "testing"
6 |
7 | "github.com/stretchr/testify/require"
8 | )
9 |
10 | func TestUserPtr(t *testing.T) {
11 | s := &Stub{}
12 | r := reflect.TypeOf(s.QueryResolver.OptionalUnion)
13 | require.Equal(t, reflect.Interface, r.Out(0).Kind())
14 | }
15 |
--------------------------------------------------------------------------------
/codegen/testserver/singlefile/v-ok.go:
--------------------------------------------------------------------------------
1 | package singlefile
2 |
3 | // VOkCaseValue model
4 | type VOkCaseValue struct{}
5 |
6 | func (v VOkCaseValue) Value() (string, bool) {
7 | return "hi", true
8 | }
9 |
10 | // VOkCaseNil model
11 | type VOkCaseNil struct{}
12 |
13 | func (v VOkCaseNil) Value() (string, bool) {
14 | return "", false
15 | }
16 |
--------------------------------------------------------------------------------
/codegen/testserver/singlefile/v-ok.graphql:
--------------------------------------------------------------------------------
1 | extend type Query {
2 | vOkCaseValue: VOkCaseValue
3 | vOkCaseNil: VOkCaseNil
4 | }
5 |
6 | type VOkCaseValue @goModel(model:"singlefile.VOkCaseValue") {
7 | value: String
8 | }
9 |
10 | type VOkCaseNil @goModel(model:"singlefile.VOkCaseNil") {
11 | value: String
12 | }
13 |
--------------------------------------------------------------------------------
/codegen/testserver/singlefile/variadic.go:
--------------------------------------------------------------------------------
1 | package singlefile
2 |
3 | import (
4 | "context"
5 | "strconv"
6 | )
7 |
8 | type VariadicModel struct{}
9 |
10 | type VariadicModelOption func(*VariadicModel)
11 |
12 | func (v VariadicModel) Value(ctx context.Context, rank int, opts ...VariadicModelOption) (string, error) {
13 | return strconv.Itoa(rank), nil
14 | }
15 |
--------------------------------------------------------------------------------
/codegen/testserver/singlefile/variadic.graphql:
--------------------------------------------------------------------------------
1 | extend type Query {
2 | variadicModel: VariadicModel
3 | }
4 |
5 | type VariadicModel {
6 | value(rank: Int!): String
7 | }
8 |
--------------------------------------------------------------------------------
/codegen/testserver/singlefile/weird_type_cases.graphql:
--------------------------------------------------------------------------------
1 | # regression test for https://github.com/99designs/gqlgen/issues/583
2 |
3 | type asdfIt { id: ID! }
4 | type iIt { id: ID! }
5 | type AIt { id: ID! }
6 | type XXIt { id: ID! }
7 | type AbIt { id: ID! }
8 | type XxIt { id: ID! }
9 |
--------------------------------------------------------------------------------
/codegen/testserver/singlefile/wrapped_type.go:
--------------------------------------------------------------------------------
1 | package singlefile
2 |
3 | import "github.com/99designs/gqlgen/codegen/testserver/singlefile/otherpkg"
4 |
5 | type (
6 | WrappedScalar = otherpkg.Scalar
7 | WrappedStruct otherpkg.Struct
8 | WrappedMap otherpkg.Map
9 | WrappedSlice otherpkg.Slice
10 | )
11 |
--------------------------------------------------------------------------------
/codegen/testserver/singlefile/wrapped_type.graphql:
--------------------------------------------------------------------------------
1 | # regression test for https://github.com/99designs/gqlgen/issues/721
2 |
3 | extend type Query {
4 | wrappedStruct: WrappedStruct!
5 | wrappedScalar: WrappedScalar!
6 | wrappedMap: WrappedMap!
7 | wrappedSlice: WrappedSlice!
8 | }
9 |
10 | type WrappedStruct { name: WrappedScalar!, desc: WrappedScalar }
11 | scalar WrappedScalar
12 | type WrappedMap { get(key: String!): String! }
13 | type WrappedSlice { get(idx: Int!): String! }
14 |
--------------------------------------------------------------------------------
/codegen/testserver/usefunctionsyntaxforexecutioncontext/directive.go:
--------------------------------------------------------------------------------
1 | package usefunctionsyntaxforexecutioncontext
2 |
3 | import (
4 | "context"
5 | "log"
6 |
7 | "github.com/99designs/gqlgen/graphql"
8 | )
9 |
10 | // LogDirective implementation
11 | func LogDirective(ctx context.Context, obj any, next graphql.Resolver, message *string) (res any, err error) {
12 | log.Printf("Log Directive: %s", *message)
13 |
14 | // Proceed with the next resolver in the chain
15 | return next(ctx)
16 | }
17 |
--------------------------------------------------------------------------------
/codegen/testserver/usefunctionsyntaxforexecutioncontext/gqlgen.yml:
--------------------------------------------------------------------------------
1 | schema:
2 | - "*.graphql"
3 | skip_validation: true
4 | use_function_syntax_for_execution_context: true
5 | exec:
6 | filename: generated.go
7 | package: usefunctionsyntaxforexecutioncontext
8 | model:
9 | filename: models-gen.go
10 | package: usefunctionsyntaxforexecutioncontext
11 | resolver:
12 | filename: resolver.go
13 | package: usefunctionsyntaxforexecutioncontext
14 | type: Resolver
15 |
16 | autobind:
17 | - "github.com/99designs/gqlgen/codegen/testserver"
18 | - "github.com/99designs/gqlgen/codegen/testserver/usefunctionsyntaxforexecutioncontext"
19 |
20 | models:
21 | Email:
22 | model: "github.com/99designs/gqlgen/codegen/testserver/singlefile.Email"
23 | StringFromContextFunction:
24 | model: "github.com/99designs/gqlgen/codegen/testserver/singlefile.StringFromContextFunction"
25 |
--------------------------------------------------------------------------------
/docs/config.yml:
--------------------------------------------------------------------------------
1 | baseurl: https://gqlgen.com/
2 | metadataformat: yaml
3 | title: gqlgen
4 | enableGitInfo: true
5 | pygmentsCodeFences: true
6 | pygmentsUseClasses: true
7 | canonifyURLs: true
8 |
9 | params:
10 | name: gqlgen
11 | description: graphql servers the easy way
12 |
13 | menu:
14 | main:
15 | - name: Introduction
16 | url: /
17 | weight: -10
18 | - name: Reference
19 | identifier: reference
20 | weight: 5
21 | - name: Recipes
22 | identifier: recipes
23 | weight: 10
24 | - name: pkg.go.dev →
25 | parent: reference
26 | url: https://pkg.go.dev/github.com/99designs/gqlgen
27 |
28 | security:
29 | funcs:
30 | getenv:
31 | - '^HUGO_'
32 | - 'VERSIONS'
33 | - 'CURRENT_VERSION'
34 |
35 | go_initialisms:
36 | replace_defaults: false
37 | initialisms:
38 | - 'CC'
39 | - 'BCC'
40 |
--------------------------------------------------------------------------------
/docs/content/_introduction.md:
--------------------------------------------------------------------------------
1 | ../../README.md
--------------------------------------------------------------------------------
/docs/content/introduction.md:
--------------------------------------------------------------------------------
1 | ---
2 | linkTitle: Introduction
3 | title: Type-safe GraphQL for Go
4 | type: homepage
5 | date: 2018-03-17T13:06:47+11:00
6 | ---
7 |
--------------------------------------------------------------------------------
/docs/layouts/404.html:
--------------------------------------------------------------------------------
1 | {{ define "main" }}
2 | Page not found
3 |
4 | I'm sorry, but the requested page wasn’t found on the server.
5 | {{ end }}
--------------------------------------------------------------------------------
/docs/layouts/_default/single.html:
--------------------------------------------------------------------------------
1 | {{ define "main" }}
2 |
3 |
4 |
{{ .LinkTitle }}
5 |
{{ .Title }}
6 |
11 |
12 |
13 |
14 |
15 |
16 | {{partial "version-banner"}}
17 | {{ .Content }}
18 |
19 |
20 | {{ end }}
21 |
--------------------------------------------------------------------------------
/docs/layouts/index.html:
--------------------------------------------------------------------------------
1 | {{ define "main" }}
2 | {{ range where .Site.Pages "Type" "homepage" }}
3 |
4 | {{ .Description }}
5 |
6 |
{{ .LinkTitle }}
7 |
{{ .Title }}
8 |
9 |
10 |
11 |
12 |
13 | {{partial "version-banner"}}
14 | {{ .Content }}
15 | {{.Scratch.Set "intro" (readFile "content/_introduction.md")}}
16 | {{.Scratch.Set "intro" (split (.Scratch.Get "intro") "\n")}}
17 | {{.Scratch.Set "intro" (after 2 (.Scratch.Get "intro"))}}
18 | {{.Scratch.Set "intro" (delimit (.Scratch.Get "intro") "\n")}}
19 | {{.Scratch.Get "intro"|markdownify}}
20 |
21 |
22 | {{ end }}
23 | {{ end }}
24 |
--------------------------------------------------------------------------------
/docs/layouts/partials/version-banner.html:
--------------------------------------------------------------------------------
1 | {{ $currentVersion := getenv "CURRENT_VERSION" }}
2 | {{ $versionString := getenv "VERSIONS" }}
3 | {{ $versions := split $versionString "," }}
4 | {{ $latestVersion := index $versions 0 }}
5 |
6 | {{ if (eq $currentVersion "master") }}
7 |
8 | You are looking at the docs for the unreleased
master
branch. The latest version is
{{ $latestVersion }}.
9 |
10 | {{ else if not (eq $latestVersion $currentVersion) }}
11 |
12 | You are looking at the docs for an older version ({{ $currentVersion }}). The latest version is
{{ $latestVersion }}.
13 |
14 | {{ end }}
15 |
--------------------------------------------------------------------------------
/docs/layouts/partials/version-switcher.html:
--------------------------------------------------------------------------------
1 | {{ $VersionString := getenv "VERSIONS" }}
2 | {{ $Versions := split $VersionString "," }}
3 | {{ $currentVersion := getenv "CURRENT_VERSION" }}
4 |
5 |
6 |
{{ $currentVersion }}
7 |
8 |
{{$currentVersion}}
9 | {{ range $i, $version := $Versions }}
10 | {{ if not (eq $currentVersion $version) }}
11 |
{{$version}}
12 | {{ end }}
13 | {{ end }}
14 |
15 |
16 |
--------------------------------------------------------------------------------
/docs/layouts/sitemap.xml:
--------------------------------------------------------------------------------
1 |
2 | {{ range .Data.Pages }}
3 | {{ if or .Description (eq .Kind "home") }}
4 |
5 | {{ .Permalink }}
6 | {{ if not .Lastmod.IsZero }}{{ safeHTML ( .Lastmod.Format "2006-01-02T15:04:05-07:00" ) }}{{ end }}
7 | {{ with .Sitemap.ChangeFreq }}{{ . }}{{ end }}
8 | {{ if ge .Sitemap.Priority 0.0 }}{{ .Sitemap.Priority }}{{ end }}
9 |
10 | {{ end }}
11 | {{ end }}
12 |
13 |
14 |
--------------------------------------------------------------------------------
/docs/readme.md:
--------------------------------------------------------------------------------
1 | Documentation
2 | ====
3 |
4 | This directory contains the markdown source files for the static doc site hosted at [gqlgen.com](https://gqlgen.com)
5 |
6 |
7 | ## Install hugo
8 |
9 | Before working with these docs you will need to install hugo, see [Quickstart](https://gohugo.io/getting-started/quick-start/) for instructions.
10 |
11 |
12 | ## Editing docs
13 |
14 | When editing docs run `hugo serve` and a live reload server will start, then navigate to http://localhost:1313 in your browser. Any changes made will be updated in the browser.
15 |
16 |
17 | ## Publishing docs
18 |
19 | Docs are hosted using [render.com](https://render.com/) and will be automatically deployed when merging to master.
20 |
21 |
--------------------------------------------------------------------------------
/docs/static/external-link-alt.svg:
--------------------------------------------------------------------------------
1 |
2 |
6 |
--------------------------------------------------------------------------------
/docs/static/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/99designs/gqlgen/0fce010415029b53fc75b00c6dc85394f44402db/docs/static/favicon.ico
--------------------------------------------------------------------------------
/docs/static/request_anatomy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/99designs/gqlgen/0fce010415029b53fc75b00c6dc85394f44402db/docs/static/request_anatomy.png
--------------------------------------------------------------------------------
/docs/static/schema_layout.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/99designs/gqlgen/0fce010415029b53fc75b00c6dc85394f44402db/docs/static/schema_layout.png
--------------------------------------------------------------------------------
/graphql/any.go:
--------------------------------------------------------------------------------
1 | package graphql
2 |
3 | import (
4 | "encoding/json"
5 | "io"
6 | )
7 |
8 | func MarshalAny(v any) Marshaler {
9 | return WriterFunc(func(w io.Writer) {
10 | err := json.NewEncoder(w).Encode(v)
11 | if err != nil {
12 | panic(err)
13 | }
14 | })
15 | }
16 |
17 | func UnmarshalAny(v any) (any, error) {
18 | return v, nil
19 | }
20 |
--------------------------------------------------------------------------------
/graphql/bool.go:
--------------------------------------------------------------------------------
1 | package graphql
2 |
3 | import (
4 | "fmt"
5 | "io"
6 | "strconv"
7 | "strings"
8 | )
9 |
10 | func MarshalBoolean(b bool) Marshaler {
11 | str := strconv.FormatBool(b)
12 | return WriterFunc(func(w io.Writer) { w.Write([]byte(str)) })
13 | }
14 |
15 | func UnmarshalBoolean(v any) (bool, error) {
16 | switch v := v.(type) {
17 | case string:
18 | return strings.EqualFold(v, "true"), nil
19 | case int:
20 | return v != 0, nil
21 | case bool:
22 | return v, nil
23 | case nil:
24 | return false, nil
25 | default:
26 | return false, fmt.Errorf("%T is not a bool", v)
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/graphql/bool_test.go:
--------------------------------------------------------------------------------
1 | package graphql
2 |
3 | import (
4 | "bytes"
5 | "testing"
6 |
7 | "github.com/stretchr/testify/assert"
8 | )
9 |
10 | func TestBoolean(t *testing.T) {
11 | assert.Equal(t, "true", doBooleanMarshal(true))
12 | assert.Equal(t, "false", doBooleanMarshal(false))
13 | }
14 |
15 | func doBooleanMarshal(b bool) string {
16 | var buf bytes.Buffer
17 | MarshalBoolean(b).MarshalGQL(&buf)
18 | return buf.String()
19 | }
20 |
--------------------------------------------------------------------------------
/graphql/context_field_test.go:
--------------------------------------------------------------------------------
1 | package graphql
2 |
3 | import (
4 | "context"
5 | "testing"
6 |
7 | "github.com/stretchr/testify/require"
8 | "github.com/vektah/gqlparser/v2/ast"
9 | )
10 |
11 | func TestGetResolverContext(t *testing.T) {
12 | require.Nil(t, GetFieldContext(context.Background()))
13 |
14 | rc := &FieldContext{}
15 | require.Equal(t, rc, GetFieldContext(WithFieldContext(context.Background(), rc)))
16 | }
17 |
18 | func testContext(sel ast.SelectionSet) context.Context {
19 | ctx := context.Background()
20 |
21 | rqCtx := &OperationContext{}
22 | ctx = WithOperationContext(ctx, rqCtx)
23 |
24 | root := &FieldContext{
25 | Field: CollectedField{
26 | Selections: sel,
27 | },
28 | }
29 | ctx = WithFieldContext(ctx, root)
30 |
31 | return ctx
32 | }
33 |
--------------------------------------------------------------------------------
/graphql/context_path_test.go:
--------------------------------------------------------------------------------
1 | package graphql
2 |
3 | import (
4 | "context"
5 | "testing"
6 |
7 | "github.com/stretchr/testify/require"
8 | )
9 |
10 | func TestGetFieldInputContext(t *testing.T) {
11 | require.Nil(t, GetFieldContext(context.Background()))
12 |
13 | rc := &PathContext{}
14 | require.Equal(t, rc, GetPathContext(WithPathContext(context.Background(), rc)))
15 | }
16 |
--------------------------------------------------------------------------------
/graphql/context_root_field.go:
--------------------------------------------------------------------------------
1 | package graphql
2 |
3 | import (
4 | "context"
5 | )
6 |
7 | const rootResolverCtx key = "root_resolver_context"
8 |
9 | type RootFieldContext struct {
10 | // The name of the type this field belongs to
11 | Object string
12 | // The raw field
13 | Field CollectedField
14 | }
15 |
16 | func GetRootFieldContext(ctx context.Context) *RootFieldContext {
17 | if val, ok := ctx.Value(rootResolverCtx).(*RootFieldContext); ok {
18 | return val
19 | }
20 | return nil
21 | }
22 |
23 | func WithRootFieldContext(ctx context.Context, rc *RootFieldContext) context.Context {
24 | return context.WithValue(ctx, rootResolverCtx, rc)
25 | }
26 |
--------------------------------------------------------------------------------
/graphql/context_root_field_test.go:
--------------------------------------------------------------------------------
1 | package graphql
2 |
3 | import (
4 | "context"
5 | "testing"
6 |
7 | "github.com/stretchr/testify/require"
8 | )
9 |
10 | func TestGetRootFieldContext(t *testing.T) {
11 | require.Nil(t, GetRootFieldContext(context.Background()))
12 |
13 | rc := &RootFieldContext{}
14 | require.Equal(t, rc, GetRootFieldContext(WithRootFieldContext(context.Background(), rc)))
15 | }
16 |
--------------------------------------------------------------------------------
/graphql/deferred.go:
--------------------------------------------------------------------------------
1 | package graphql
2 |
3 | import (
4 | "context"
5 |
6 | "github.com/vektah/gqlparser/v2/ast"
7 | "github.com/vektah/gqlparser/v2/gqlerror"
8 | )
9 |
10 | type Deferrable struct {
11 | Label string
12 | }
13 |
14 | type DeferredGroup struct {
15 | Path ast.Path
16 | Label string
17 | FieldSet *FieldSet
18 | Context context.Context
19 | }
20 |
21 | type DeferredResult struct {
22 | Path ast.Path
23 | Label string
24 | Result Marshaler
25 | Errors gqlerror.List
26 | }
27 |
--------------------------------------------------------------------------------
/graphql/duration.go:
--------------------------------------------------------------------------------
1 | package graphql
2 |
3 | import (
4 | "errors"
5 | "time"
6 |
7 | dur "github.com/sosodev/duration"
8 | )
9 |
10 | // UnmarshalDuration returns the duration from a string in ISO8601 format
11 | func UnmarshalDuration(v any) (time.Duration, error) {
12 | input, ok := v.(string)
13 | if !ok {
14 | return 0, errors.New("input must be a string")
15 | }
16 |
17 | d2, err := dur.Parse(input)
18 | if err != nil {
19 | return 0, err
20 | }
21 | return d2.ToTimeDuration(), nil
22 | }
23 |
24 | // MarshalDuration returns the duration on ISO8601 format
25 | func MarshalDuration(d time.Duration) Marshaler {
26 | return MarshalString(dur.Format(d))
27 | }
28 |
--------------------------------------------------------------------------------
/graphql/duration_test.go:
--------------------------------------------------------------------------------
1 | package graphql
2 |
3 | import (
4 | "bytes"
5 | "testing"
6 | "time"
7 |
8 | "github.com/stretchr/testify/assert"
9 | "github.com/stretchr/testify/require"
10 | )
11 |
12 | func TestDurationMarshaling(t *testing.T) {
13 | t.Run("UnmarshalDuration", func(t *testing.T) {
14 | d, err := UnmarshalDuration("P2Y")
15 | require.NoError(t, err)
16 |
17 | assert.InEpsilon(t, float64(365*24*2), d.Hours(), 0.02)
18 | })
19 | t.Run("MarshalDuration", func(t *testing.T) {
20 | m := MarshalDuration(time.Hour * 365 * 24 * 2)
21 |
22 | buf := new(bytes.Buffer)
23 | m.MarshalGQL(buf)
24 |
25 | assert.Equal(t, "\"P2Y\"", buf.String())
26 | })
27 | }
28 |
--------------------------------------------------------------------------------
/graphql/fieldset_test.go:
--------------------------------------------------------------------------------
1 | package graphql
2 |
3 | import (
4 | "bytes"
5 | "testing"
6 |
7 | "github.com/stretchr/testify/assert"
8 | "github.com/vektah/gqlparser/v2/ast"
9 | )
10 |
11 | func TestFieldSet_MarshalGQL(t *testing.T) {
12 | t.Run("Should_Deduplicate_Keys", func(t *testing.T) {
13 | fs := NewFieldSet([]CollectedField{
14 | {Field: &ast.Field{Alias: "__typename"}},
15 | {Field: &ast.Field{Alias: "__typename"}},
16 | })
17 | fs.Values[0] = MarshalString("A")
18 | fs.Values[1] = MarshalString("A")
19 |
20 | b := bytes.NewBuffer(nil)
21 | fs.MarshalGQL(b)
22 |
23 | assert.JSONEq(t, "{\"__typename\":\"A\"}", b.String())
24 | })
25 | }
26 |
--------------------------------------------------------------------------------
/graphql/float_test.go:
--------------------------------------------------------------------------------
1 | package graphql
2 |
3 | import (
4 | "bytes"
5 | "testing"
6 |
7 | "github.com/stretchr/testify/assert"
8 | )
9 |
10 | func TestFloat(t *testing.T) {
11 | assert.Equal(t, "123", m2s(MarshalFloat(123)))
12 | assert.Equal(t, "1.2345678901", m2s(MarshalFloat(1.2345678901)))
13 | assert.Equal(t, "1.2345678901234567", m2s(MarshalFloat(1.234567890123456789)))
14 | assert.Equal(t, "1.2e+20", m2s(MarshalFloat(1.2e+20)))
15 | assert.Equal(t, "1.2e-20", m2s(MarshalFloat(1.2e-20)))
16 | }
17 |
18 | func m2s(m Marshaler) string {
19 | var b bytes.Buffer
20 | m.MarshalGQL(&b)
21 | return b.String()
22 | }
23 |
--------------------------------------------------------------------------------
/graphql/handler/apollofederatedtracingv1/logger/logger.go:
--------------------------------------------------------------------------------
1 | package logger
2 |
3 | import "log"
4 |
5 | // Logger is an interface that can be implemented to log errors that occur during the tracing process
6 | // This can use the default Go logger or a custom logger (e.g. logrus or zap)
7 | type Logger interface {
8 | Print(args any)
9 | Println(args any)
10 | Printf(format string, args any)
11 | }
12 |
13 | func NewNoopLogger() *NoopLogger {
14 | return &NoopLogger{
15 | log.New(NullWriter(1), "", log.LstdFlags),
16 | }
17 | }
18 |
19 | type NullWriter int
20 |
21 | func (NullWriter) Write([]byte) (int, error) { return 0, nil }
22 |
23 | type NoopLogger struct {
24 | *log.Logger
25 | }
26 |
27 | func (l *NoopLogger) Print(args any) {}
28 |
29 | func (l *NoopLogger) Printf(format string, args any) {}
30 |
31 | func (l *NoopLogger) Println(v any) {}
32 |
--------------------------------------------------------------------------------
/graphql/handler/apollofederatedtracingv1/logger/logger_test.go:
--------------------------------------------------------------------------------
1 | package logger_test
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/99designs/gqlgen/graphql/handler/apollofederatedtracingv1/logger"
7 | "github.com/stretchr/testify/assert"
8 | )
9 |
10 | func TestNoopLogger_Print(t *testing.T) {
11 | l := logger.NewNoopLogger()
12 | assert.NotPanics(t, func() {
13 | l.Print("test")
14 | })
15 | }
16 |
17 | func TestNoopLogger_Printf(t *testing.T) {
18 | l := logger.NewNoopLogger()
19 | assert.NotPanics(t, func() {
20 | l.Printf("test %s", "formatted")
21 | })
22 | }
23 |
24 | func TestNoopLogger_Println(t *testing.T) {
25 | l := logger.NewNoopLogger()
26 | assert.NotPanics(t, func() {
27 | l.Println("test")
28 | })
29 | }
30 |
--------------------------------------------------------------------------------
/graphql/handler/extension/introspection.go:
--------------------------------------------------------------------------------
1 | package extension
2 |
3 | import (
4 | "context"
5 |
6 | "github.com/vektah/gqlparser/v2/gqlerror"
7 |
8 | "github.com/99designs/gqlgen/graphql"
9 | )
10 |
11 | // EnableIntrospection enables clients to reflect all of the types available on the graph.
12 | type Introspection struct{}
13 |
14 | var _ interface {
15 | graphql.OperationContextMutator
16 | graphql.HandlerExtension
17 | } = Introspection{}
18 |
19 | func (c Introspection) ExtensionName() string {
20 | return "Introspection"
21 | }
22 |
23 | func (c Introspection) Validate(schema graphql.ExecutableSchema) error {
24 | return nil
25 | }
26 |
27 | func (c Introspection) MutateOperationContext(ctx context.Context, opCtx *graphql.OperationContext) *gqlerror.Error {
28 | opCtx.DisableIntrospection = false
29 | return nil
30 | }
31 |
--------------------------------------------------------------------------------
/graphql/handler/extension/introspection_test.go:
--------------------------------------------------------------------------------
1 | package extension
2 |
3 | import (
4 | "context"
5 | "testing"
6 |
7 | "github.com/stretchr/testify/require"
8 | "github.com/vektah/gqlparser/v2/gqlerror"
9 |
10 | "github.com/99designs/gqlgen/graphql"
11 | )
12 |
13 | func TestIntrospection(t *testing.T) {
14 | opCtx := &graphql.OperationContext{
15 | DisableIntrospection: true,
16 | }
17 | err := Introspection{}.MutateOperationContext(context.Background(), opCtx)
18 | require.Equal(t, (*gqlerror.Error)(nil), err)
19 | require.False(t, opCtx.DisableIntrospection)
20 | }
21 |
--------------------------------------------------------------------------------
/graphql/handler/lru/lru.go:
--------------------------------------------------------------------------------
1 | package lru
2 |
3 | import (
4 | "context"
5 |
6 | lru "github.com/hashicorp/golang-lru/v2"
7 |
8 | "github.com/99designs/gqlgen/graphql"
9 | )
10 |
11 | type LRU[T any] struct {
12 | lru *lru.Cache[string, T]
13 | }
14 |
15 | var _ graphql.Cache[any] = &LRU[any]{}
16 |
17 | func New[T any](size int) *LRU[T] {
18 | cache, err := lru.New[string, T](size)
19 | if err != nil {
20 | // An error is only returned for non-positive cache size
21 | // and we already checked for that.
22 | panic("unexpected error creating cache: " + err.Error())
23 | }
24 | return &LRU[T]{cache}
25 | }
26 |
27 | func (l LRU[T]) Get(ctx context.Context, key string) (value T, ok bool) {
28 | return l.lru.Get(key)
29 | }
30 |
31 | func (l LRU[T]) Add(ctx context.Context, key string, value T) {
32 | l.lru.Add(key, value)
33 | }
34 |
--------------------------------------------------------------------------------
/graphql/handler/transport/error.go:
--------------------------------------------------------------------------------
1 | package transport
2 |
3 | import (
4 | "encoding/json"
5 | "fmt"
6 | "net/http"
7 |
8 | "github.com/vektah/gqlparser/v2/gqlerror"
9 |
10 | "github.com/99designs/gqlgen/graphql"
11 | )
12 |
13 | // SendError sends a best effort error to a raw response writer. It assumes the client can understand the standard
14 | // json error response
15 | func SendError(w http.ResponseWriter, code int, errors ...*gqlerror.Error) {
16 | w.WriteHeader(code)
17 | b, err := json.Marshal(&graphql.Response{Errors: errors})
18 | if err != nil {
19 | panic(err)
20 | }
21 | _, _ = w.Write(b)
22 | }
23 |
24 | // SendErrorf wraps SendError to add formatted messages
25 | func SendErrorf(w http.ResponseWriter, code int, format string, args ...any) {
26 | SendError(w, code, &gqlerror.Error{Message: fmt.Sprintf(format, args...)})
27 | }
28 |
--------------------------------------------------------------------------------
/graphql/handler/transport/util.go:
--------------------------------------------------------------------------------
1 | package transport
2 |
3 | import (
4 | "encoding/json"
5 | "fmt"
6 | "io"
7 |
8 | "github.com/vektah/gqlparser/v2/gqlerror"
9 |
10 | "github.com/99designs/gqlgen/graphql"
11 | )
12 |
13 | func writeJson(w io.Writer, response *graphql.Response) {
14 | b, err := json.Marshal(response)
15 | if err != nil {
16 | panic(fmt.Errorf("unable to marshal %s: %w", string(response.Data), err))
17 | }
18 | w.Write(b)
19 | }
20 |
21 | func writeJsonError(w io.Writer, msg string) {
22 | writeJson(w, &graphql.Response{Errors: gqlerror.List{{Message: msg}}})
23 | }
24 |
25 | func writeJsonErrorf(w io.Writer, format string, args ...any) {
26 | writeJson(w, &graphql.Response{Errors: gqlerror.List{{Message: fmt.Sprintf(format, args...)}}})
27 | }
28 |
29 | func writeJsonGraphqlError(w io.Writer, err ...*gqlerror.Error) {
30 | writeJson(w, &graphql.Response{Errors: err})
31 | }
32 |
--------------------------------------------------------------------------------
/graphql/handler/transport/websocket_close_reason.go:
--------------------------------------------------------------------------------
1 | package transport
2 |
3 | import (
4 | "context"
5 | )
6 |
7 | // A private key for context that only this package can access. This is important
8 | // to prevent collisions between different context uses
9 | var closeReasonCtxKey = &wsCloseReasonContextKey{"close-reason"}
10 |
11 | type wsCloseReasonContextKey struct {
12 | name string
13 | }
14 |
15 | func AppendCloseReason(ctx context.Context, reason string) context.Context {
16 | return context.WithValue(ctx, closeReasonCtxKey, reason)
17 | }
18 |
19 | func closeReasonForContext(ctx context.Context) string {
20 | reason, _ := ctx.Value(closeReasonCtxKey).(string)
21 | return reason
22 | }
23 |
--------------------------------------------------------------------------------
/graphql/map.go:
--------------------------------------------------------------------------------
1 | package graphql
2 |
3 | import (
4 | "encoding/json"
5 | "fmt"
6 | "io"
7 | )
8 |
9 | func MarshalMap(val map[string]any) Marshaler {
10 | return WriterFunc(func(w io.Writer) {
11 | err := json.NewEncoder(w).Encode(val)
12 | if err != nil {
13 | panic(err)
14 | }
15 | })
16 | }
17 |
18 | func UnmarshalMap(v any) (map[string]any, error) {
19 | if m, ok := v.(map[string]any); ok {
20 | return m, nil
21 | }
22 |
23 | return nil, fmt.Errorf("%T is not a map", v)
24 | }
25 |
--------------------------------------------------------------------------------
/graphql/oneshot.go:
--------------------------------------------------------------------------------
1 | package graphql
2 |
3 | import "context"
4 |
5 | func OneShot(resp *Response) ResponseHandler {
6 | var oneshot bool
7 |
8 | return func(context context.Context) *Response {
9 | if oneshot {
10 | return nil
11 | }
12 | oneshot = true
13 |
14 | return resp
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/graphql/playground/altair_playground_test.go:
--------------------------------------------------------------------------------
1 | package playground
2 |
3 | import (
4 | "net/http"
5 | "testing"
6 | )
7 |
8 | func TestAltairHandler_Integrity(t *testing.T) {
9 | testResourceIntegrity(t, func(title, endpoint string) http.HandlerFunc { return AltairHandler(title, endpoint, nil) })
10 | }
11 |
--------------------------------------------------------------------------------
/graphql/playground/apollo_sandbox_playground_test.go:
--------------------------------------------------------------------------------
1 | package playground
2 |
3 | import (
4 | "net/http"
5 | "testing"
6 | )
7 |
8 | func TestApolloSandboxHandler_Integrity(t *testing.T) {
9 | testResourceIntegrity(t, func(title, endpoint string) http.HandlerFunc {
10 | return ApolloSandboxHandler(title, endpoint)
11 | })
12 | }
13 |
--------------------------------------------------------------------------------
/graphql/recovery.go:
--------------------------------------------------------------------------------
1 | package graphql
2 |
3 | import (
4 | "context"
5 | "fmt"
6 | "os"
7 | "runtime/debug"
8 |
9 | "github.com/vektah/gqlparser/v2/gqlerror"
10 | )
11 |
12 | type RecoverFunc func(ctx context.Context, err any) (userMessage error)
13 |
14 | func DefaultRecover(ctx context.Context, err any) error {
15 | fmt.Fprintln(os.Stderr, err)
16 | fmt.Fprintln(os.Stderr)
17 | debug.PrintStack()
18 |
19 | return gqlerror.Errorf("internal system error")
20 | }
21 |
--------------------------------------------------------------------------------
/graphql/root.go:
--------------------------------------------------------------------------------
1 | package graphql
2 |
3 | type Query struct{}
4 |
5 | type Mutation struct{}
6 |
7 | type Subscription struct{}
8 |
--------------------------------------------------------------------------------
/graphql/time.go:
--------------------------------------------------------------------------------
1 | package graphql
2 |
3 | import (
4 | "errors"
5 | "io"
6 | "strconv"
7 | "time"
8 | )
9 |
10 | func MarshalTime(t time.Time) Marshaler {
11 | if t.IsZero() {
12 | return Null
13 | }
14 |
15 | return WriterFunc(func(w io.Writer) {
16 | io.WriteString(w, strconv.Quote(t.Format(time.RFC3339Nano)))
17 | })
18 | }
19 |
20 | func UnmarshalTime(v any) (time.Time, error) {
21 | if tmpStr, ok := v.(string); ok {
22 | return time.Parse(time.RFC3339Nano, tmpStr)
23 | }
24 | return time.Time{}, errors.New("time should be RFC3339Nano formatted string")
25 | }
26 |
--------------------------------------------------------------------------------
/graphql/time_test.go:
--------------------------------------------------------------------------------
1 | package graphql
2 |
3 | import (
4 | "bytes"
5 | "strconv"
6 | "testing"
7 | "time"
8 |
9 | "github.com/stretchr/testify/require"
10 | )
11 |
12 | func TestTime(t *testing.T) {
13 | t.Run("symmetry", func(t *testing.T) {
14 | initialTime := time.Now()
15 | buf := bytes.NewBuffer([]byte{})
16 | MarshalTime(initialTime).MarshalGQL(buf)
17 |
18 | str, err := strconv.Unquote(buf.String())
19 | require.NoError(t, err)
20 | newTime, err := UnmarshalTime(str)
21 | require.NoError(t, err)
22 |
23 | require.True(t, initialTime.Equal(newTime), "expected times %v and %v to equal", initialTime, newTime)
24 | })
25 | }
26 |
--------------------------------------------------------------------------------
/graphql/upload.go:
--------------------------------------------------------------------------------
1 | package graphql
2 |
3 | import (
4 | "fmt"
5 | "io"
6 | )
7 |
8 | type Upload struct {
9 | File io.ReadSeeker
10 | Filename string
11 | Size int64
12 | ContentType string
13 | }
14 |
15 | func MarshalUpload(f Upload) Marshaler {
16 | return WriterFunc(func(w io.Writer) {
17 | io.Copy(w, f.File)
18 | })
19 | }
20 |
21 | func UnmarshalUpload(v any) (Upload, error) {
22 | upload, ok := v.(Upload)
23 | if !ok {
24 | return Upload{}, fmt.Errorf("%T is not an Upload", v)
25 | }
26 | return upload, nil
27 | }
28 |
--------------------------------------------------------------------------------
/graphql/uuid.go:
--------------------------------------------------------------------------------
1 | package graphql
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/google/uuid"
7 | )
8 |
9 | func MarshalUUID(id uuid.UUID) Marshaler {
10 | if id == uuid.Nil {
11 | return Null
12 | }
13 | return MarshalString(id.String())
14 | }
15 |
16 | func UnmarshalUUID(v any) (uuid.UUID, error) {
17 | switch v := v.(type) {
18 | case string:
19 | return uuid.Parse(v)
20 | case []byte:
21 | return uuid.ParseBytes(v)
22 | default:
23 | return uuid.Nil, fmt.Errorf("%T is not a uuid", v)
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/graphql/version.go:
--------------------------------------------------------------------------------
1 | package graphql
2 |
3 | const Version = "v0.17.73-dev"
4 |
--------------------------------------------------------------------------------
/init-templates/schema.graphqls:
--------------------------------------------------------------------------------
1 | # GraphQL schema example
2 | #
3 | # https://gqlgen.com/getting-started/
4 |
5 | type Todo {
6 | id: ID!
7 | text: String!
8 | done: Boolean!
9 | user: User!
10 | }
11 |
12 | type User {
13 | id: ID!
14 | name: String!
15 | }
16 |
17 | type Query {
18 | todos: [Todo!]!
19 | }
20 |
21 | input NewTodo {
22 | text: String!
23 | userId: String!
24 | }
25 |
26 | type Mutation {
27 | createTodo(input: NewTodo!): Todo!
28 | }
29 |
--------------------------------------------------------------------------------
/integration/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/integration/README.md:
--------------------------------------------------------------------------------
1 | # Integration tests
2 |
3 | These tests run a gqlgen server against the apollo client to test real world connectivity.
4 |
5 | First start the go server
6 | ```bash
7 | go run server/cmd/integration/server.go
8 | ```
9 |
10 | And in another terminal:
11 | ```bash
12 | cd integration
13 | npm ci
14 | npm run test
15 | ```
16 |
--------------------------------------------------------------------------------
/integration/codegen.ts:
--------------------------------------------------------------------------------
1 | import type { CodegenConfig } from '@graphql-codegen/cli';
2 |
3 | const config: CodegenConfig = {
4 | overwrite: true,
5 | schema: process.env.VITE_SERVER_URL ?? 'http://localhost:8080/query',
6 | documents: 'src/**/*.graphql',
7 | generates: {
8 | 'src/generated/': {
9 | preset: 'client-preset'
10 | },
11 | 'src/generated/schema-fetched.graphql': {
12 | plugins: ['schema-ast'],
13 | },
14 | 'src/generated/schema-introspection.json': {
15 | plugins: ['introspection'],
16 | }
17 | },
18 | };
19 |
20 | export default config;
21 |
--------------------------------------------------------------------------------
/integration/graphql.config.yml:
--------------------------------------------------------------------------------
1 | name: Schema
2 | schema: src/generated/schema-expected.graphql
3 | extensions:
4 | endpoints:
5 | dev:
6 | url: http://localhost:8080/query
7 | introspect: true
8 |
--------------------------------------------------------------------------------
/integration/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "integration",
3 | "private": true,
4 | "version": "0.0.0",
5 | "type": "module",
6 | "scripts": {
7 | "test": "vitest",
8 | "gen": "graphql-codegen --config codegen.ts"
9 | },
10 | "devDependencies": {
11 | "@apollo/client": "^3.13.8",
12 | "@graphql-codegen/cli": "^5.0.6",
13 | "@graphql-codegen/client-preset": "^4.8.0",
14 | "@graphql-codegen/introspection": "^4.0.3",
15 | "@graphql-codegen/schema-ast": "^4.1.0",
16 | "cross-fetch": "^4.1.0",
17 | "graphql": "^16.11.0",
18 | "graphql-codegen": "^0.4.0",
19 | "graphql-sse": "^2.5.4",
20 | "graphql-ws": "^6.0.5",
21 | "typescript": "^5.8.3",
22 | "urql": "^4.2.2",
23 | "vite": "^6.3.5",
24 | "vitest": "^3.1.4"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/integration/server/gqlgen.yml:
--------------------------------------------------------------------------------
1 | schema:
2 | - schema/**/*.graphql
3 |
4 | exec:
5 | filename: generated.go
6 | model:
7 | filename: models-go/generated.go
8 |
9 | struct_tag: json
10 |
11 | autobind:
12 | - "github.com/99designs/gqlgen/integration/server/testomitempty"
13 |
14 | models:
15 | Element:
16 | model: github.com/99designs/gqlgen/integration/server/models-go.Element
17 | Viewer:
18 | model: github.com/99designs/gqlgen/integration/server/models-go.Viewer
19 | User:
20 | model: github.com/99designs/gqlgen/integration/server/remote_api.User
21 | fields:
22 | likes:
23 | resolver: true
24 |
--------------------------------------------------------------------------------
/integration/server/models-go/element.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | type Element struct {
4 | ID int
5 | }
6 |
7 | func (e *Element) Mismatched() []Element {
8 | return []Element{*e}
9 | }
10 |
--------------------------------------------------------------------------------
/integration/server/models-go/viewer.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | import "github.com/99designs/gqlgen/integration/server/remote_api"
4 |
5 | type Viewer struct {
6 | User *remote_api.User
7 | }
8 |
--------------------------------------------------------------------------------
/integration/server/remote_api/user.go:
--------------------------------------------------------------------------------
1 | package remote_api
2 |
3 | type User struct {
4 | Name string
5 | Likes []string
6 | PhoneNumber string
7 | }
8 |
--------------------------------------------------------------------------------
/integration/server/schema/testomitempty.graphql:
--------------------------------------------------------------------------------
1 | type RemoteModelWithOmitempty {
2 | newDesc: String
3 | }
4 |
--------------------------------------------------------------------------------
/integration/server/schema/user.graphql:
--------------------------------------------------------------------------------
1 | type User {
2 | name: String!
3 | likes: [String!]!
4 | phoneNumber: String @deprecated
5 | query: Query!
6 | }
7 |
--------------------------------------------------------------------------------
/integration/server/testomitempty/testmodel.go:
--------------------------------------------------------------------------------
1 | package testomitempty
2 |
3 | type RemoteModelWithOmitempty struct {
4 | Description string `json:"newDesc,omitempty"`
5 | }
6 |
--------------------------------------------------------------------------------
/integration/src/generated/.gitignore:
--------------------------------------------------------------------------------
1 | schema-fetched.graphql
2 | schema-introspection.json
3 |
--------------------------------------------------------------------------------
/integration/src/generated/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./fragment-masking";
2 | export * from "./gql";
--------------------------------------------------------------------------------
/integration/src/queries/coercion.graphql:
--------------------------------------------------------------------------------
1 | query coercion($value: [ListCoercion!]){
2 | coercion(value: $value )
3 | }
4 |
--------------------------------------------------------------------------------
/integration/src/queries/complexity.graphql:
--------------------------------------------------------------------------------
1 | query complexity($value: Int!) {
2 | complexity(value: $value)
3 | }
4 |
--------------------------------------------------------------------------------
/integration/src/queries/date.graphql:
--------------------------------------------------------------------------------
1 | query date($filter: DateFilter!) {
2 | date(filter: $filter)
3 | }
4 |
--------------------------------------------------------------------------------
/integration/src/queries/error.graphql:
--------------------------------------------------------------------------------
1 | query error($type: ErrorType) {
2 | error(type: $type)
3 | }
4 |
--------------------------------------------------------------------------------
/integration/src/queries/jsonEncoding.graphql:
--------------------------------------------------------------------------------
1 | query jsonEncoding {
2 | jsonEncoding
3 | }
4 |
--------------------------------------------------------------------------------
/integration/src/queries/path.graphql:
--------------------------------------------------------------------------------
1 | query path {
2 | path {
3 | cc:child {
4 | error
5 | }
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/integration/src/queries/viewer.graphql:
--------------------------------------------------------------------------------
1 | query viewer {
2 | viewer {
3 | user {
4 | name
5 | phoneNumber
6 | query {
7 | jsonEncoding
8 | }
9 | ...userFragment @defer
10 | }
11 | }
12 | }
13 |
14 | fragment userFragment on User {
15 | likes
16 | }
17 |
--------------------------------------------------------------------------------
/integration/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2020",
4 | "useDefineForClassFields": true,
5 | "module": "ESNext",
6 | "lib": ["ES2020", "DOM", "DOM.Iterable"],
7 | "skipLibCheck": true,
8 |
9 | /* Bundler mode */
10 | "moduleResolution": "bundler",
11 | "allowImportingTsExtensions": true,
12 | "resolveJsonModule": true,
13 | "isolatedModules": true,
14 | "noEmit": true,
15 |
16 | /* Linting */
17 | "strict": true,
18 | "noUnusedLocals": true,
19 | "noUnusedParameters": true,
20 | "noFallthroughCasesInSwitch": true
21 | },
22 | "include": ["src"]
23 | }
24 |
--------------------------------------------------------------------------------
/internal/code/testdata/a/a.go:
--------------------------------------------------------------------------------
1 | package a
2 |
3 | var A = "A"
4 |
--------------------------------------------------------------------------------
/internal/code/testdata/b/b.go:
--------------------------------------------------------------------------------
1 | package b
2 |
3 | import "github.com/99designs/gqlgen/internal/code/testdata/a"
4 |
5 | var B = a.A + " B"
6 |
--------------------------------------------------------------------------------
/internal/code/testdata/c/c.go:
--------------------------------------------------------------------------------
1 | package c
2 |
3 | import (
4 | "github.com/99designs/gqlgen/internal/code/testdata/b"
5 | )
6 |
7 | var C = b.B + " C"
8 |
--------------------------------------------------------------------------------
/internal/code/testdata/p/p.go:
--------------------------------------------------------------------------------
1 | //go:build private
2 |
3 | // This file is excluded from the build unless the "private" build tag is set.
4 | // This is used to test loading private packages.
5 | // See internal/code/packages_test.go for more details.
6 | package p
7 |
8 | import (
9 | "github.com/99designs/gqlgen/internal/code/testdata/b"
10 | )
11 |
12 | var P = b.C + " P"
13 |
--------------------------------------------------------------------------------
/internal/code/util_test.go:
--------------------------------------------------------------------------------
1 | package code
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/require"
7 | )
8 |
9 | func TestNormalizeVendor(t *testing.T) {
10 | require.Equal(t, "bar/baz", NormalizeVendor("foo/vendor/bar/baz"))
11 | require.Equal(t, "[]bar/baz", NormalizeVendor("[]foo/vendor/bar/baz"))
12 | require.Equal(t, "*bar/baz", NormalizeVendor("*foo/vendor/bar/baz"))
13 | require.Equal(t, "*[]*bar/baz", NormalizeVendor("*[]*foo/vendor/bar/baz"))
14 | require.Equal(t, "[]*bar/baz", NormalizeVendor("[]*foo/vendor/bar/baz"))
15 | }
16 |
--------------------------------------------------------------------------------
/internal/imports/prune_test.go:
--------------------------------------------------------------------------------
1 | package imports
2 |
3 | import (
4 | "os"
5 | "strings"
6 | "testing"
7 |
8 | "github.com/stretchr/testify/require"
9 |
10 | "github.com/99designs/gqlgen/internal/code"
11 | )
12 |
13 | func TestPrune(t *testing.T) {
14 | // prime the packages cache so that it's not considered uninitialized
15 |
16 | b, err := Prune("testdata/unused.go", mustReadFile("testdata/unused.go"), code.NewPackages())
17 | require.NoError(t, err)
18 | require.Equal(t, strings.ReplaceAll(string(mustReadFile("testdata/unused.expected.go")), "\r\n", "\n"), string(b))
19 | }
20 |
21 | func mustReadFile(filename string) []byte {
22 | b, err := os.ReadFile(filename)
23 | if err != nil {
24 | panic(err)
25 | }
26 | return b
27 | }
28 |
--------------------------------------------------------------------------------
/internal/imports/testdata/unused.expected.go:
--------------------------------------------------------------------------------
1 | package testdata
2 |
3 | import (
4 | a "fmt"
5 | "time"
6 |
7 | _ "underscore"
8 | )
9 |
10 | type foo struct {
11 | Time time.Time `json:"text"`
12 | }
13 |
14 | func fn() {
15 | a.Println("hello")
16 | }
17 |
18 | type Message struct {
19 | ID string `json:"id"`
20 | Text string `json:"text"`
21 | CreatedBy string `json:"createdBy"`
22 | CreatedAt time.Time `json:"createdAt"`
23 | }
24 |
--------------------------------------------------------------------------------
/internal/imports/testdata/unused.go:
--------------------------------------------------------------------------------
1 | package testdata
2 |
3 | import (
4 | a "fmt"
5 | "time"
6 |
7 | _ "underscore"
8 | )
9 |
10 | type foo struct {
11 | Time time.Time `json:"text"`
12 | }
13 |
14 | func fn() {
15 | a.Println("hello")
16 | }
17 |
18 | type Message struct {
19 | ID string `json:"id"`
20 | Text string `json:"text"`
21 | CreatedBy string `json:"createdBy"`
22 | CreatedAt time.Time `json:"createdAt"`
23 | }
24 |
--------------------------------------------------------------------------------
/internal/rewrite/testdata/example.go:
--------------------------------------------------------------------------------
1 | package testdata
2 |
3 | import (
4 | lol "bytes"
5 | "fmt"
6 | )
7 |
8 | type Foo struct {
9 | Field int
10 | }
11 |
12 | func (m *Foo) Method(arg int) {
13 | // leading comment
14 |
15 | // field comment
16 | m.Field++
17 |
18 | // trailing comment
19 | }
20 |
21 | func (m *Foo) String() string {
22 | var buf lol.Buffer
23 | buf.WriteString(fmt.Sprintf("%d", m.Field))
24 | return buf.String()
25 | }
26 |
--------------------------------------------------------------------------------
/internal/tools.go:
--------------------------------------------------------------------------------
1 | //go:build tools
2 |
3 | package main
4 |
5 | import (
6 | _ "github.com/matryer/moq"
7 | )
8 |
--------------------------------------------------------------------------------
/plugin/federation/fedruntime/runtime.go:
--------------------------------------------------------------------------------
1 | package fedruntime
2 |
3 | // Service is the service object that the
4 | // generated.go file will return for the _service
5 | // query
6 | type Service struct {
7 | SDL string `json:"sdl"`
8 | }
9 |
10 | // Everything with a @key implements this
11 | type Entity interface {
12 | IsEntity()
13 | }
14 |
15 | // Used for the Link directive
16 | type Link any
17 |
--------------------------------------------------------------------------------
/plugin/federation/requires.gotpl:
--------------------------------------------------------------------------------
1 | {{ range .ExistingImports }}
2 | {{ if ne .Alias "" }}
3 | {{ reserveImport .ImportPath .Alias }}
4 | {{ else }}
5 | {{ reserveImport .ImportPath }}
6 | {{ end }}
7 | {{ end }}
8 |
9 | {{ range .Populators -}}
10 | {{ if .Comment -}}
11 | // {{.Comment}}
12 | {{- else -}}
13 | // {{.FuncName}} is the requires populator for the {{.Entity.Def.Name}} entity.
14 | {{- end }}
15 | func (ec *executionContext) {{.FuncName}}(ctx context.Context, entity *{{.Entity.GetTypeInfo}}, reps map[string]any) error {
16 | {{.Implementation}}
17 | }
18 | {{ end }}
19 |
20 | {{ .OriginalSource }}
21 |
--------------------------------------------------------------------------------
/plugin/federation/test_data/model2/federation.go:
--------------------------------------------------------------------------------
1 | package model2
2 |
3 | type FieldSet string
4 |
5 | type Hello struct {
6 | Name string
7 | Secondary string
8 | }
9 |
10 | func (Hello) IsEntity() {}
11 |
12 | type World struct {
13 | Foo string
14 | Bar int
15 | }
16 |
17 | func (World) IsEntity() {}
18 |
19 | type ExternalExtension struct {
20 | UPC string
21 | Reviews []*World
22 | }
23 |
24 | func (ExternalExtension) IsEntity() {}
25 |
26 | type NestedKey struct {
27 | ID string
28 | Hello *Hello
29 | }
30 |
31 | func (NestedKey) IsEntity() {}
32 |
33 | type MoreNesting struct {
34 | ID string
35 | World *World
36 | }
37 |
38 | func (MoreNesting) IsEntity() {}
39 |
40 | type VeryNestedKey struct {
41 | ID string
42 | Hello *Hello
43 | World *World
44 | Nested *NestedKey
45 | More *MoreNesting
46 | }
47 |
48 | func (VeryNestedKey) IsEntity() {}
49 |
--------------------------------------------------------------------------------
/plugin/federation/testdata/allthethings/gqlgen.yml:
--------------------------------------------------------------------------------
1 | schema:
2 | - "testdata/allthethings/schema.graphql"
3 | exec:
4 | filename: testdata/allthethings/generated/exec.go
5 | federation:
6 | filename: testdata/allthethings/generated/federation.go
7 |
8 | autobind:
9 | - "github.com/99designs/gqlgen/plugin/federation/testdata/allthethings/model"
10 |
--------------------------------------------------------------------------------
/plugin/federation/testdata/computedrequires/errors.go:
--------------------------------------------------------------------------------
1 | package computedrequires
2 |
3 | import "errors"
4 |
5 | // Errors defined for retained code that we want to stick around between generations.
6 | var (
7 | ErrResolvingHelloWithErrorsByName = errors.New("error resolving HelloWithErrorsByName")
8 | ErrEmptyKeyResolvingHelloWithErrorsByName = errors.New("error (empty key) resolving HelloWithErrorsByName")
9 | )
10 |
--------------------------------------------------------------------------------
/plugin/federation/testdata/computedrequires/gqlgen.yml:
--------------------------------------------------------------------------------
1 | schema:
2 | - "testdata/computedrequires/schema.graphql"
3 | exec:
4 | filename: testdata/computedrequires/generated/exec.go
5 | package: generated
6 | federation:
7 | filename: testdata/computedrequires/generated/federation.go
8 | package: generated
9 | version: 2
10 | options:
11 | computed_requires: true
12 | model:
13 | package: model
14 | filename: testdata/computedrequires/generated/models/models.go
15 | resolver:
16 | filename: testdata/computedrequires/resolver.go
17 | layout: follow-schema
18 | dir: testdata/computedrequires
19 | package: computedrequires
20 |
21 | omit_complexity: true
22 | call_argument_directives_with_null: true
23 |
--------------------------------------------------------------------------------
/plugin/federation/testdata/computedrequires/resolver.go:
--------------------------------------------------------------------------------
1 | package computedrequires
2 |
3 | // This file will not be regenerated automatically.
4 | //
5 | // It serves as dependency injection for your app, add any dependencies you require here.
6 |
7 | type Resolver struct{}
8 |
--------------------------------------------------------------------------------
/plugin/federation/testdata/entities/nokey.graphql:
--------------------------------------------------------------------------------
1 | type Hello {
2 | name: String!
3 | }
4 |
5 | type Query {
6 | hello: Hello!
7 | }
8 |
9 |
--------------------------------------------------------------------------------
/plugin/federation/testdata/entities/nokey.yml:
--------------------------------------------------------------------------------
1 | schema:
2 | - "testdata/entities/nokey.graphql"
3 | exec:
4 | filename: testdata/entities/generated/exec.go
5 | federation:
6 | filename: testdata/entities/generated/federation.go
7 |
8 | autobind:
9 | - "github.com/99designs/gqlgen/plugin/federation/test_data/model"
10 |
--------------------------------------------------------------------------------
/plugin/federation/testdata/entityinterfaces/generated/models_gen.go:
--------------------------------------------------------------------------------
1 | // Code generated by github.com/99designs/gqlgen, DO NOT EDIT.
2 |
3 | package generated
4 |
5 | type Hello interface {
6 | IsEntity()
7 | IsHello()
8 | GetID() string
9 | GetTitle() string
10 | }
11 |
12 | type Query struct {
13 | }
14 |
15 | type World struct {
16 | ID string `json:"id"`
17 | Title string `json:"title"`
18 | }
19 |
20 | func (World) IsHello() {}
21 | func (this World) GetID() string { return this.ID }
22 | func (this World) GetTitle() string { return this.Title }
23 |
24 | func (World) IsEntity() {}
25 |
--------------------------------------------------------------------------------
/plugin/federation/testdata/entityinterfaces/interface.graphql:
--------------------------------------------------------------------------------
1 | extend schema
2 | @link(url: "https://specs.apollo.dev/federation/v2.3",
3 | import: ["@key"])
4 |
5 | interface Hello @key(fields: "id"){
6 | id: String!
7 | title: String!
8 | }
9 |
10 | type World implements Hello @key(fields: "id") {
11 | id: String!
12 | title: String!
13 | }
--------------------------------------------------------------------------------
/plugin/federation/testdata/entityinterfaces/interface.yml:
--------------------------------------------------------------------------------
1 | schema:
2 | - "testdata/entityinterfaces/interface.graphql"
3 | exec:
4 | filename: testdata/entityinterfaces/generated/exec.go
5 | federation:
6 | filename: testdata/entityinterfaces/generated/federation.go
7 | version: 2
8 | model:
9 | filename: testdata/entityinterfaces/generated/models_gen.go
--------------------------------------------------------------------------------
/plugin/federation/testdata/entityresolver/generated/errors.go:
--------------------------------------------------------------------------------
1 | package generated
2 |
3 | import "errors"
4 |
5 | // Errors defined for retained code that we want to stick around between generations.
6 | var (
7 | ErrResolvingHelloWithErrorsByName = errors.New("error resolving HelloWithErrorsByName")
8 | ErrEmptyKeyResolvingHelloWithErrorsByName = errors.New("error (empty key) resolving HelloWithErrorsByName")
9 | )
10 |
--------------------------------------------------------------------------------
/plugin/federation/testdata/entityresolver/gqlgen.yml:
--------------------------------------------------------------------------------
1 | schema:
2 | - "testdata/entityresolver/schema.graphql"
3 | exec:
4 | filename: testdata/entityresolver/generated/exec.go
5 | federation:
6 | filename: testdata/entityresolver/generated/federation.go
7 | model:
8 | filename: testdata/entityresolver/generated/model/models.go
9 | package: model
10 | resolver:
11 | filename: testdata/entityresolver/resolver.go
12 | layout: follow-schema
13 | dir: testdata/entityresolver
14 | package: entityresolver
15 |
--------------------------------------------------------------------------------
/plugin/federation/testdata/entityresolver/resolver.go:
--------------------------------------------------------------------------------
1 | package entityresolver
2 |
3 | // This file will not be regenerated automatically.
4 | //
5 | // It serves as dependency injection for your app, add any dependencies you require here.
6 |
7 | type Resolver struct{}
8 |
9 | // FindWorldWithMultipleKeysByHelloNameAndFooBarValue shows we hit the FindWorldWithMultipleKeysByHelloNameAndFoo resolver
10 | const FindWorldWithMultipleKeysByHelloNameAndFooBarValue = 99
11 |
--------------------------------------------------------------------------------
/plugin/federation/testdata/entityresolver/schema.resolvers.go:
--------------------------------------------------------------------------------
1 | package entityresolver
2 |
3 | // This file will be automatically regenerated based on the schema, any resolver implementations
4 | // will be copied through when generating and any unknown code will be moved to the end.
5 |
--------------------------------------------------------------------------------
/plugin/federation/testdata/explicitrequires/generated/errors.go:
--------------------------------------------------------------------------------
1 | package generated
2 |
3 | import "errors"
4 |
5 | // Errors defined for retained code that we want to stick around between generations.
6 | var (
7 | ErrResolvingHelloWithErrorsByName = errors.New("error resolving HelloWithErrorsByName")
8 | ErrEmptyKeyResolvingHelloWithErrorsByName = errors.New("error (empty key) resolving HelloWithErrorsByName")
9 | )
10 |
--------------------------------------------------------------------------------
/plugin/federation/testdata/explicitrequires/gqlgen.yml:
--------------------------------------------------------------------------------
1 | schema:
2 | - "testdata/explicitrequires/schema.graphql"
3 | exec:
4 | filename: testdata/explicitrequires/generated/exec.go
5 | federation:
6 | filename: testdata/explicitrequires/generated/federation.go
7 | options:
8 | explicit_requires: true
9 | model:
10 | filename: testdata/explicitrequires/generated/models.go
11 | resolver:
12 | filename: testdata/explicitrequires/resolver.go
13 | layout: follow-schema
14 | dir: testdata/explicitrequires
15 | package: explicitrequires
16 | omit_complexity: true
17 |
--------------------------------------------------------------------------------
/plugin/federation/testdata/explicitrequires/resolver.go:
--------------------------------------------------------------------------------
1 | package explicitrequires
2 |
3 | // This file will not be regenerated automatically.
4 | //
5 | // It serves as dependency injection for your app, add any dependencies you require here.
6 |
7 | type Resolver struct{}
8 |
--------------------------------------------------------------------------------
/plugin/federation/testdata/explicitrequires/schema.resolvers.go:
--------------------------------------------------------------------------------
1 | package explicitrequires
2 |
3 | // This file will be automatically regenerated based on the schema, any resolver implementations
4 | // will be copied through when generating and any unknown code will be moved to the end.
5 |
--------------------------------------------------------------------------------
/plugin/federation/testdata/federation2/federation2.graphql:
--------------------------------------------------------------------------------
1 | extend schema
2 | @link(url: "https://specs.apollo.dev/federation/v2.7",
3 | import: ["@key", "@shareable", "@provides", "@external", "@tag", "@extends", "@override", "@inaccessible", "@interfaceObject", "@policy"])
4 |
5 | schema {
6 | query: CustomQuery
7 | }
8 |
9 | type Hello @key(fields:"name", resolvable: false) {
10 | name: String! @override(from: "old-service", label: "percent(5)")
11 | }
12 |
13 | type World @key(fields: "foo bar", resolvable: false) {
14 | foo: String!
15 | bar: Int!
16 | }
17 |
18 | extend type ExternalExtension @key(fields: " upc ") {
19 | upc: String!
20 | reviews: [Hello]
21 | }
22 |
23 | type CustomQuery {
24 | hello: Hello!
25 | }
26 |
--------------------------------------------------------------------------------
/plugin/federation/testdata/federation2/federation2.yml:
--------------------------------------------------------------------------------
1 | schema:
2 | - "testdata/federation2/federation2.graphql"
3 | exec:
4 | filename: testdata/federation2/generated/exec.go
5 | federation:
6 | filename: testdata/federation2/generated/federation.go
7 | version: 2
8 |
9 | autobind:
10 | - "github.com/99designs/gqlgen/plugin/federation/test_data/model2"
11 |
--------------------------------------------------------------------------------
/plugin/federation/testdata/interfaces/extends.graphqls:
--------------------------------------------------------------------------------
1 | interface Hello @extends {
2 | name: String!
3 | secondary: String!
4 | }
5 |
6 | extend type World implements Hello @key(fields: "name") {
7 | name: String! @external
8 | secondary: String!
9 |
10 | tertiary: String!
11 | }
12 |
--------------------------------------------------------------------------------
/plugin/federation/testdata/interfaces/extends.yml:
--------------------------------------------------------------------------------
1 | schema:
2 | - "testdata/interfaces/extends.graphqls"
3 | exec:
4 | filename: testdata/interfaces/generated/exec.go
5 | federation:
6 | filename: testdata/interfaces/generated/federation.go
7 |
--------------------------------------------------------------------------------
/plugin/federation/testdata/interfaces/key.graphqls:
--------------------------------------------------------------------------------
1 | extend interface Hello @key(fields: "name") {
2 | name: String!
3 | secondary: String!
4 | }
5 |
6 | type World implements Hello @key(fields: "name") {
7 | name: String!
8 | secondary: String!
9 | }
10 |
--------------------------------------------------------------------------------
/plugin/federation/testdata/interfaces/key.yml:
--------------------------------------------------------------------------------
1 | schema:
2 | - "testdata/interfaces/key.graphqls"
3 | exec:
4 | filename: testdata/interfaces/generated/exec.go
5 | federation:
6 | filename: testdata/interfaces/generated/federation.go
7 |
--------------------------------------------------------------------------------
/plugin/federation/testdata/interfaces/unused_key.graphqls:
--------------------------------------------------------------------------------
1 | extend interface Hello @key(fields: "name") {
2 | name: String!
3 | secondary: String!
4 | }
5 |
--------------------------------------------------------------------------------
/plugin/federation/testdata/interfaces/unused_key.yml:
--------------------------------------------------------------------------------
1 | schema:
2 | - "testdata/interfaces/unused_key.graphqls"
3 | exec:
4 | filename: testdata/interfaces/generated/exec.go
5 | federation:
6 | filename: testdata/interfaces/generated/federation.go
7 |
--------------------------------------------------------------------------------
/plugin/federation/testdata/multi/multi.graphqls:
--------------------------------------------------------------------------------
1 | extend schema
2 | @link(url: "https://specs.apollo.dev/federation/v2.7",
3 | import: ["@key"])
4 |
5 | directive @entityResolver(multi: Boolean) on OBJECT
6 |
7 | type Hello @key(fields: "name") @entityResolver(multi: true) {
8 | name: String!
9 | secondary: String!
10 | }
11 |
--------------------------------------------------------------------------------
/plugin/federation/testdata/multi/multi.yml:
--------------------------------------------------------------------------------
1 | schema:
2 | - "testdata/multi/multi.graphqls"
3 | exec:
4 | filename: testdata/multi/generated/exec.go
5 | federation:
6 | version: 2
7 | filename: testdata/multi/generated/federation.go
8 | omit_slice_element_pointers: true
--------------------------------------------------------------------------------
/plugin/federation/testdata/schema/customquerytype.graphql:
--------------------------------------------------------------------------------
1 | schema {
2 | query: CustomQuery
3 | }
4 |
5 | type Hello {
6 | name: String!
7 | }
8 |
9 | type CustomQuery {
10 | hello: Hello!
11 | }
12 |
13 |
--------------------------------------------------------------------------------
/plugin/federation/testdata/schema/customquerytype.yml:
--------------------------------------------------------------------------------
1 | schema:
2 | - "testdata/schema/customquerytype.graphql"
3 | exec:
4 | filename: testdata/schema/generated/exec.go
5 | federation:
6 | filename: testdata/schema/generated/federation.go
7 |
8 | autobind:
9 | - "github.com/99designs/gqlgen/plugin/federation/test_data/model"
10 |
--------------------------------------------------------------------------------
/plugin/federation/testdata/usefunctionsyntaxforexecutioncontext/generated/errors.go:
--------------------------------------------------------------------------------
1 | package generated
2 |
3 | import "errors"
4 |
5 | // Errors defined for retained code that we want to stick around between generations.
6 | var (
7 | ErrResolvingHelloWithErrorsByName = errors.New("error resolving HelloWithErrorsByName")
8 | ErrEmptyKeyResolvingHelloWithErrorsByName = errors.New("error (empty key) resolving HelloWithErrorsByName")
9 | )
10 |
--------------------------------------------------------------------------------
/plugin/federation/testdata/usefunctionsyntaxforexecutioncontext/gqlgen.yml:
--------------------------------------------------------------------------------
1 | schema:
2 | - "testdata/usefunctionsyntaxforexecutioncontext/schema.graphql"
3 | use_function_syntax_for_execution_context: true
4 | exec:
5 | filename: testdata/usefunctionsyntaxforexecutioncontext/generated/exec.go
6 | federation:
7 | filename: testdata/usefunctionsyntaxforexecutioncontext/generated/federation.go
8 | model:
9 | filename: testdata/usefunctionsyntaxforexecutioncontext/generated/model/models.go
10 | package: model
11 | resolver:
12 | filename: testdata/usefunctionsyntaxforexecutioncontext/resolver.go
13 | layout: follow-schema
14 | dir: testdata/usefunctionsyntaxforexecutioncontext
15 | package: usefunctionsyntaxforexecutioncontext
16 |
--------------------------------------------------------------------------------
/plugin/federation/testdata/usefunctionsyntaxforexecutioncontext/resolver.go:
--------------------------------------------------------------------------------
1 | package usefunctionsyntaxforexecutioncontext
2 |
3 | // This file will not be regenerated automatically.
4 | //
5 | // It serves as dependency injection for your app, add any dependencies you require here.
6 |
7 | type Resolver struct{}
8 |
9 | // FindWorldWithMultipleKeysByHelloNameAndFooBarValue shows we hit the FindWorldWithMultipleKeysByHelloNameAndFoo resolver
10 | const FindWorldWithMultipleKeysByHelloNameAndFooBarValue = 99
11 |
--------------------------------------------------------------------------------
/plugin/federation/testdata/usefunctionsyntaxforexecutioncontext/schema.resolvers.go:
--------------------------------------------------------------------------------
1 | package usefunctionsyntaxforexecutioncontext
2 |
3 | // This file will be automatically regenerated based on the schema, any resolver implementations
4 | // will be copied through when generating and any unknown code will be moved to the end.
5 |
--------------------------------------------------------------------------------
/plugin/modelgen/internal/extrafields/types.go:
--------------------------------------------------------------------------------
1 | package extrafields
2 |
3 | type Type struct{}
4 |
--------------------------------------------------------------------------------
/plugin/modelgen/out/existing.go:
--------------------------------------------------------------------------------
1 | package out
2 |
3 | type ExistingType struct {
4 | Name *string `json:"name"`
5 | Enum *ExistingEnum `json:"enum"`
6 | Int ExistingInterface `json:"int"`
7 | Existing *MissingTypeNullable `json:"existing"`
8 | }
9 |
10 | type ExistingModel struct {
11 | Name string
12 | Enum ExistingEnum
13 | Int ExistingInterface
14 | }
15 |
16 | type ExistingInput struct {
17 | Name string
18 | Enum ExistingEnum
19 | Int ExistingInterface
20 | }
21 |
22 | type ExistingEnum string
23 |
24 | type ExistingInterface interface {
25 | IsExistingInterface()
26 | }
27 |
28 | type ExistingUnion interface {
29 | IsExistingUnion()
30 | }
31 |
--------------------------------------------------------------------------------
/plugin/modelgen/out_enable_model_json_omitempty_tag_false/existing.go:
--------------------------------------------------------------------------------
1 | package out_enable_model_json_omitempty_tag_false
2 |
3 | type ExistingType struct {
4 | Name *string `json:"name"`
5 | Enum *ExistingEnum `json:"enum"`
6 | Int ExistingInterface `json:"int"`
7 | Existing *MissingTypeNullable `json:"existing"`
8 | }
9 |
10 | type ExistingModel struct {
11 | Name string
12 | Enum ExistingEnum
13 | Int ExistingInterface
14 | }
15 |
16 | type ExistingInput struct {
17 | Name string
18 | Enum ExistingEnum
19 | Int ExistingInterface
20 | }
21 |
22 | type ExistingEnum string
23 |
24 | type ExistingInterface interface {
25 | IsExistingInterface()
26 | }
27 |
28 | type ExistingUnion interface {
29 | IsExistingUnion()
30 | }
31 |
--------------------------------------------------------------------------------
/plugin/modelgen/out_enable_model_json_omitempty_tag_false_omitzero_tag_false/existing.go:
--------------------------------------------------------------------------------
1 | package out_enable_model_json_omitempty_tag_false_omitzero_tag_false
2 |
3 | type ExistingType struct {
4 | Name *string `json:"name"`
5 | Enum *ExistingEnum `json:"enum"`
6 | Int ExistingInterface `json:"int"`
7 | Existing *MissingTypeNullable `json:"existing"`
8 | }
9 |
10 | type ExistingModel struct {
11 | Name string
12 | Enum ExistingEnum
13 | Int ExistingInterface
14 | }
15 |
16 | type ExistingInput struct {
17 | Name string
18 | Enum ExistingEnum
19 | Int ExistingInterface
20 | }
21 |
22 | type ExistingEnum string
23 |
24 | type ExistingInterface interface {
25 | IsExistingInterface()
26 | }
27 |
28 | type ExistingUnion interface {
29 | IsExistingUnion()
30 | }
31 |
--------------------------------------------------------------------------------
/plugin/modelgen/out_enable_model_json_omitempty_tag_false_omitzero_tag_nil/existing.go:
--------------------------------------------------------------------------------
1 | package out_enable_model_json_omitempty_tag_false_omitzero_tag_nil
2 |
3 | type ExistingType struct {
4 | Name *string `json:"name"`
5 | Enum *ExistingEnum `json:"enum"`
6 | Int ExistingInterface `json:"int"`
7 | Existing *MissingTypeNullable `json:"existing"`
8 | }
9 |
10 | type ExistingModel struct {
11 | Name string
12 | Enum ExistingEnum
13 | Int ExistingInterface
14 | }
15 |
16 | type ExistingInput struct {
17 | Name string
18 | Enum ExistingEnum
19 | Int ExistingInterface
20 | }
21 |
22 | type ExistingEnum string
23 |
24 | type ExistingInterface interface {
25 | IsExistingInterface()
26 | }
27 |
28 | type ExistingUnion interface {
29 | IsExistingUnion()
30 | }
31 |
--------------------------------------------------------------------------------
/plugin/modelgen/out_enable_model_json_omitempty_tag_false_omitzero_tag_true/existing.go:
--------------------------------------------------------------------------------
1 | package out_enable_model_json_omitempty_tag_false_omitzero_tag_true
2 |
3 | type ExistingType struct {
4 | Name *string `json:"name"`
5 | Enum *ExistingEnum `json:"enum"`
6 | Int ExistingInterface `json:"int"`
7 | Existing *MissingTypeNullable `json:"existing"`
8 | }
9 |
10 | type ExistingModel struct {
11 | Name string
12 | Enum ExistingEnum
13 | Int ExistingInterface
14 | }
15 |
16 | type ExistingInput struct {
17 | Name string
18 | Enum ExistingEnum
19 | Int ExistingInterface
20 | }
21 |
22 | type ExistingEnum string
23 |
24 | type ExistingInterface interface {
25 | IsExistingInterface()
26 | }
27 |
28 | type ExistingUnion interface {
29 | IsExistingUnion()
30 | }
31 |
--------------------------------------------------------------------------------
/plugin/modelgen/out_enable_model_json_omitempty_tag_nil/existing.go:
--------------------------------------------------------------------------------
1 | package out_enable_model_json_omitempty_tag_nil
2 |
3 | type ExistingType struct {
4 | Name *string `json:"name"`
5 | Enum *ExistingEnum `json:"enum"`
6 | Int ExistingInterface `json:"int"`
7 | Existing *MissingTypeNullable `json:"existing"`
8 | }
9 |
10 | type ExistingModel struct {
11 | Name string
12 | Enum ExistingEnum
13 | Int ExistingInterface
14 | }
15 |
16 | type ExistingInput struct {
17 | Name string
18 | Enum ExistingEnum
19 | Int ExistingInterface
20 | }
21 |
22 | type ExistingEnum string
23 |
24 | type ExistingInterface interface {
25 | IsExistingInterface()
26 | }
27 |
28 | type ExistingUnion interface {
29 | IsExistingUnion()
30 | }
31 |
--------------------------------------------------------------------------------
/plugin/modelgen/out_enable_model_json_omitempty_tag_true/existing.go:
--------------------------------------------------------------------------------
1 | package out_enable_model_json_omitempty_tag_true
2 |
3 | type ExistingType struct {
4 | Name *string `json:"name"`
5 | Enum *ExistingEnum `json:"enum"`
6 | Int ExistingInterface `json:"int"`
7 | Existing *MissingTypeNullable `json:"existing"`
8 | }
9 |
10 | type ExistingModel struct {
11 | Name string
12 | Enum ExistingEnum
13 | Int ExistingInterface
14 | }
15 |
16 | type ExistingInput struct {
17 | Name string
18 | Enum ExistingEnum
19 | Int ExistingInterface
20 | }
21 |
22 | type ExistingEnum string
23 |
24 | type ExistingInterface interface {
25 | IsExistingInterface()
26 | }
27 |
28 | type ExistingUnion interface {
29 | IsExistingUnion()
30 | }
31 |
--------------------------------------------------------------------------------
/plugin/modelgen/out_enable_model_json_omitzero_tag_false/existing.go:
--------------------------------------------------------------------------------
1 | package out_enable_model_json_omitzero_tag_false
2 |
3 | type ExistingType struct {
4 | Name *string `json:"name"`
5 | Enum *ExistingEnum `json:"enum"`
6 | Int ExistingInterface `json:"int"`
7 | Existing *MissingTypeNullable `json:"existing"`
8 | }
9 |
10 | type ExistingModel struct {
11 | Name string
12 | Enum ExistingEnum
13 | Int ExistingInterface
14 | }
15 |
16 | type ExistingInput struct {
17 | Name string
18 | Enum ExistingEnum
19 | Int ExistingInterface
20 | }
21 |
22 | type ExistingEnum string
23 |
24 | type ExistingInterface interface {
25 | IsExistingInterface()
26 | }
27 |
28 | type ExistingUnion interface {
29 | IsExistingUnion()
30 | }
31 |
--------------------------------------------------------------------------------
/plugin/modelgen/out_enable_model_json_omitzero_tag_nil/existing.go:
--------------------------------------------------------------------------------
1 | package out_enable_model_json_omitzero_tag_nil
2 |
3 | type ExistingType struct {
4 | Name *string `json:"name"`
5 | Enum *ExistingEnum `json:"enum"`
6 | Int ExistingInterface `json:"int"`
7 | Existing *MissingTypeNullable `json:"existing"`
8 | }
9 |
10 | type ExistingModel struct {
11 | Name string
12 | Enum ExistingEnum
13 | Int ExistingInterface
14 | }
15 |
16 | type ExistingInput struct {
17 | Name string
18 | Enum ExistingEnum
19 | Int ExistingInterface
20 | }
21 |
22 | type ExistingEnum string
23 |
24 | type ExistingInterface interface {
25 | IsExistingInterface()
26 | }
27 |
28 | type ExistingUnion interface {
29 | IsExistingUnion()
30 | }
31 |
--------------------------------------------------------------------------------
/plugin/modelgen/out_enable_model_json_omitzero_tag_true/existing.go:
--------------------------------------------------------------------------------
1 | package out_enable_model_json_omitzero_tag_true
2 |
3 | type ExistingType struct {
4 | Name *string `json:"name"`
5 | Enum *ExistingEnum `json:"enum"`
6 | Int ExistingInterface `json:"int"`
7 | Existing *MissingTypeNullable `json:"existing"`
8 | }
9 |
10 | type ExistingModel struct {
11 | Name string
12 | Enum ExistingEnum
13 | Int ExistingInterface
14 | }
15 |
16 | type ExistingInput struct {
17 | Name string
18 | Enum ExistingEnum
19 | Int ExistingInterface
20 | }
21 |
22 | type ExistingEnum string
23 |
24 | type ExistingInterface interface {
25 | IsExistingInterface()
26 | }
27 |
28 | type ExistingUnion interface {
29 | IsExistingUnion()
30 | }
31 |
--------------------------------------------------------------------------------
/plugin/modelgen/out_nullable_input_omittable/existing.go:
--------------------------------------------------------------------------------
1 | package out_nullable_input_omittable
2 |
3 | import (
4 | "github.com/99designs/gqlgen/graphql"
5 | )
6 |
7 | type ExistingType struct {
8 | Name *string `json:"name"`
9 | Enum *ExistingEnum `json:"enum"`
10 | Int ExistingInterface `json:"int"`
11 | Existing *MissingTypeNullable `json:"existing"`
12 | }
13 |
14 | type ExistingModel struct {
15 | Name string
16 | Enum ExistingEnum
17 | Int ExistingInterface
18 | }
19 |
20 | type ExistingInput struct {
21 | Name graphql.Omittable[string]
22 | Enum graphql.Omittable[ExistingEnum]
23 | Int graphql.Omittable[ExistingInterface]
24 | }
25 |
26 | type ExistingEnum string
27 |
28 | type ExistingInterface interface {
29 | IsExistingInterface()
30 | }
31 |
32 | type ExistingUnion interface {
33 | IsExistingUnion()
34 | }
35 |
--------------------------------------------------------------------------------
/plugin/modelgen/out_omit_resolver_fields/generated.go:
--------------------------------------------------------------------------------
1 | // Code generated by github.com/99designs/gqlgen, DO NOT EDIT.
2 |
3 | package out_omit_resolver_fields
4 |
5 | type Base struct {
6 | StandardField string `json:"StandardField" database:"BaseStandardField"`
7 | }
8 |
9 | type Query struct {
10 | }
11 |
--------------------------------------------------------------------------------
/plugin/modelgen/out_struct_pointers/existing.go:
--------------------------------------------------------------------------------
1 | package out_struct_pointers
2 |
3 | type ExistingType struct {
4 | Name *string `json:"name"`
5 | Enum *ExistingEnum `json:"enum"`
6 | Int ExistingInterface `json:"int"`
7 | Existing *MissingTypeNullable `json:"existing"`
8 | }
9 |
10 | type ExistingModel struct {
11 | Name string
12 | Enum ExistingEnum
13 | Int ExistingInterface
14 | }
15 |
16 | type ExistingInput struct {
17 | Name string
18 | Enum ExistingEnum
19 | Int ExistingInterface
20 | }
21 |
22 | type ExistingEnum string
23 |
24 | type ExistingInterface interface {
25 | IsExistingInterface()
26 | }
27 |
28 | type ExistingUnion interface {
29 | IsExistingUnion()
30 | }
31 |
--------------------------------------------------------------------------------
/plugin/modelgen/testdata/gqlgen_omit_resolver_fields.yml:
--------------------------------------------------------------------------------
1 | schema:
2 | - "testdata/schema_omit_resolver_fields.graphql"
3 |
4 | exec:
5 | filename: out_omit_resolver_fields/ignored.go
6 | model:
7 | filename: out_omit_resolver_fields/generated.go
8 |
9 | omit_resolver_fields: true
10 |
--------------------------------------------------------------------------------
/plugin/modelgen/testdata/gqlgen_omit_root_models.yml:
--------------------------------------------------------------------------------
1 | schema:
2 | - "testdata/schema_omit_root_models.graphql"
3 |
4 | exec:
5 | filename: out/ignored.go
6 | model:
7 | filename: out/generated_omit_root_models.go
8 |
9 | omit_root_models: true
10 |
--------------------------------------------------------------------------------
/plugin/modelgen/testdata/schema_omit_resolver_fields.graphql:
--------------------------------------------------------------------------------
1 | directive @goTag(
2 | key: String!
3 | value: String
4 | ) on INPUT_FIELD_DEFINITION | FIELD_DEFINITION
5 |
6 | directive @goField(
7 | forceResolver: Boolean
8 | name: String
9 | omittable: Boolean
10 | type: String
11 | ) on INPUT_FIELD_DEFINITION | FIELD_DEFINITION | INTERFACE
12 |
13 | type Base {
14 | StandardField: String!
15 | ResolverField: String! @goField(forceResolver: true)
16 | }
17 |
--------------------------------------------------------------------------------
/plugin/modelgen/testdata/schema_omit_root_models.graphql:
--------------------------------------------------------------------------------
1 | type Query {
2 | thisShoudlntGetGenerated: Boolean
3 | }
4 |
5 | type Mutation {
6 | thisShoudlntGetGenerated: Boolean
7 | }
8 |
9 | type Subscription {
10 | thisShoudlntGetGenerated: Boolean
11 | }
12 |
13 | enum SomeContent {
14 | This
15 | Is
16 | A
17 | Test
18 | }
19 |
--------------------------------------------------------------------------------
/plugin/resolvergen/testdata/filetemplate/gqlgen.yml:
--------------------------------------------------------------------------------
1 | schema:
2 | - "testdata/schema.graphql"
3 |
4 | exec:
5 | filename: testdata/singlefile/out/ignored.go
6 | model:
7 | filename: testdata/singlefile/out/generated.go
8 | resolver:
9 | type: CustomResolverType
10 | layout: follow-schema
11 | dir: testdata/filetemplate/out
12 | filename_template: "{name}.custom.go"
13 |
14 | models:
15 | Resolver:
16 | model: github.com/99designs/gqlgen/plugin/resolvergen/testdata/singlefile/out.Resolver
17 |
18 | omit_gqlgen_version_in_file_notice: true
19 |
--------------------------------------------------------------------------------
/plugin/resolvergen/testdata/filetemplate/out/model.go:
--------------------------------------------------------------------------------
1 | package customresolver
2 |
3 | import "context"
4 |
5 | type Resolver struct{}
6 |
7 | type QueryResolver interface {
8 | Resolver(ctx context.Context) (*Resolver, error)
9 | }
10 |
11 | type ResolverResolver interface {
12 | Name(ctx context.Context, obj *Resolver) (string, error)
13 | }
14 |
--------------------------------------------------------------------------------
/plugin/resolvergen/testdata/filetemplate/out/resolver.go:
--------------------------------------------------------------------------------
1 | package customresolver
2 |
3 | // This file will not be regenerated automatically.
4 | //
5 | // It serves as dependency injection for your app, add any dependencies you require here.
6 |
7 | type CustomResolverType struct{}
8 |
--------------------------------------------------------------------------------
/plugin/resolvergen/testdata/followschema/gqlgen.yml:
--------------------------------------------------------------------------------
1 | schema:
2 | - "testdata/schema.graphql"
3 |
4 | exec:
5 | filename: testdata/singlefile/out/ignored.go
6 | model:
7 | filename: testdata/singlefile/out/generated.go
8 | resolver:
9 | type: CustomResolverType
10 | layout: follow-schema
11 | dir: testdata/followschema/out
12 |
13 | models:
14 | Resolver:
15 | model: github.com/99designs/gqlgen/plugin/resolvergen/testdata/singlefile/out.Resolver
16 |
17 | omit_gqlgen_version_in_file_notice: true
18 |
--------------------------------------------------------------------------------
/plugin/resolvergen/testdata/followschema/out/model.go:
--------------------------------------------------------------------------------
1 | package customresolver
2 |
3 | import "context"
4 |
5 | type Resolver struct{}
6 |
7 | type QueryResolver interface {
8 | Resolver(ctx context.Context) (*Resolver, error)
9 | }
10 |
11 | type ResolverResolver interface {
12 | Name(ctx context.Context, obj *Resolver) (string, error)
13 | }
14 |
--------------------------------------------------------------------------------
/plugin/resolvergen/testdata/followschema/out/resolver.go:
--------------------------------------------------------------------------------
1 | package customresolver
2 |
3 | // This file will not be regenerated automatically.
4 | //
5 | // It serves as dependency injection for your app, add any dependencies you require here.
6 |
7 | type CustomResolverType struct{}
8 |
--------------------------------------------------------------------------------
/plugin/resolvergen/testdata/invalid_model_path/gqlgen.yml:
--------------------------------------------------------------------------------
1 | schema:
2 | - "testdata/schema.graphql"
3 |
4 | models:
5 | Resolver:
6 | model: github.com/99designs/invalid/invalid/invalid/nope.Resolver
7 |
--------------------------------------------------------------------------------
/plugin/resolvergen/testdata/omit_template_comment/gqlgen.yml:
--------------------------------------------------------------------------------
1 | schema:
2 | - "testdata/schema.graphql"
3 |
4 | exec:
5 | filename: testdata/singlefile/out/ignored.go
6 | model:
7 | filename: testdata/singlefile/out/generated.go
8 | resolver:
9 | type: CustomResolverType
10 | layout: follow-schema
11 | dir: testdata/omit_template_comment/out
12 | omit_template_comment: true
13 |
14 | models:
15 | Resolver:
16 | model: github.com/99designs/gqlgen/plugin/resolvergen/testdata/singlefile/out.Resolver
17 |
18 | omit_gqlgen_version_in_file_notice: true
19 |
--------------------------------------------------------------------------------
/plugin/resolvergen/testdata/omit_template_comment/out/resolver.go:
--------------------------------------------------------------------------------
1 | package out
2 |
3 | // This file will not be regenerated automatically.
4 | //
5 | // It serves as dependency injection for your app, add any dependencies you require here.
6 |
7 | type CustomResolverType struct{}
8 |
--------------------------------------------------------------------------------
/plugin/resolvergen/testdata/resolver_implementor/gqlgen.yml:
--------------------------------------------------------------------------------
1 | schema:
2 | - "testdata/schema.graphql"
3 |
4 | exec:
5 | filename: testdata/resolver_implementor/out/ignored.go
6 | model:
7 | filename: testdata/resolver_implementor/out/generated.go
8 | resolver:
9 | type: CustomResolverType
10 | layout: follow-schema
11 | dir: testdata/resolver_implementor/out
12 |
13 | models:
14 | Resolver:
15 | model: github.com/99designs/gqlgen/plugin/resolvergen/testdata/resolver_implementor/out.Resolver
16 |
17 | omit_gqlgen_version_in_file_notice: true
18 |
--------------------------------------------------------------------------------
/plugin/resolvergen/testdata/resolver_implementor/out/model.go:
--------------------------------------------------------------------------------
1 | package customresolver
2 |
3 | import "context"
4 |
5 | type Resolver struct{}
6 |
7 | type QueryResolver interface {
8 | Resolver(ctx context.Context) (*Resolver, error)
9 | }
10 |
11 | type ResolverResolver interface {
12 | Name(ctx context.Context, obj *Resolver) (string, error)
13 | }
14 |
--------------------------------------------------------------------------------
/plugin/resolvergen/testdata/resolver_implementor/out/resolver.go:
--------------------------------------------------------------------------------
1 | package customresolver
2 |
3 | // This file will not be regenerated automatically.
4 | //
5 | // It serves as dependency injection for your app, add any dependencies you require here.
6 |
7 | type CustomResolverType struct{}
8 |
--------------------------------------------------------------------------------
/plugin/resolvergen/testdata/resolvertemplate/gqlgen.yml:
--------------------------------------------------------------------------------
1 | schema:
2 | - "testdata/schema.graphql"
3 |
4 | exec:
5 | filename: testdata/singlefile/out/ignored.go
6 | model:
7 | filename: testdata/singlefile/out/generated.go
8 | resolver:
9 | type: CustomResolverType
10 | layout: follow-schema
11 | dir: testdata/resolvertemplate/out
12 | filename_template: "{name}.resolvers.go"
13 | resolver_template: "testdata/resolvertemplate/customResolverTemplate.gotpl"
14 |
15 | models:
16 | Resolver:
17 | model: github.com/99designs/gqlgen/plugin/resolvergen/testdata/singlefile/out.Resolver
18 |
19 | omit_gqlgen_version_in_file_notice: true
20 |
--------------------------------------------------------------------------------
/plugin/resolvergen/testdata/resolvertemplate/out/resolver.go:
--------------------------------------------------------------------------------
1 | package out
2 |
3 | // This file will not be regenerated automatically.
4 | //
5 | // It serves as dependency injection for your app, add any dependencies you require here.
6 |
7 | type CustomResolverType struct{}
8 |
--------------------------------------------------------------------------------
/plugin/resolvergen/testdata/return_values/gqlgen.yml:
--------------------------------------------------------------------------------
1 | schema:
2 | - schema.graphqls
3 |
4 | exec:
5 | filename: ignored.go
6 | model:
7 | filename: model.go
8 | resolver:
9 | filename: resolvers.go
10 |
11 | resolvers_always_return_pointers: false
12 |
--------------------------------------------------------------------------------
/plugin/resolvergen/testdata/return_values/model.go:
--------------------------------------------------------------------------------
1 | // Code generated by github.com/99designs/gqlgen, DO NOT EDIT.
2 |
3 | package return_values
4 |
5 | type User struct {
6 | ID string `json:"id"`
7 | Name string `json:"name"`
8 | }
9 |
--------------------------------------------------------------------------------
/plugin/resolvergen/testdata/return_values/resolvers.go:
--------------------------------------------------------------------------------
1 | package return_values
2 |
3 | // THIS CODE IS A STARTING POINT ONLY. IT WILL NOT BE UPDATED WITH SCHEMA CHANGES.
4 |
5 | import (
6 | "context"
7 | )
8 |
9 | type Resolver struct{}
10 |
11 | // // foo
12 | func (r *queryResolver) User(ctx context.Context) (User, error) {
13 | panic("not implemented")
14 | }
15 |
16 | // // foo
17 | func (r *queryResolver) UserPointer(ctx context.Context) (*User, error) {
18 | panic("not implemented")
19 | }
20 |
21 | // Query returns QueryResolver implementation.
22 | func (r *Resolver) Query() QueryResolver { return &queryResolver{r} }
23 |
24 | type queryResolver struct{ *Resolver }
25 |
--------------------------------------------------------------------------------
/plugin/resolvergen/testdata/return_values/return_values_test.go:
--------------------------------------------------------------------------------
1 | package return_values
2 |
3 | import (
4 | "reflect"
5 | "testing"
6 |
7 | "github.com/stretchr/testify/require"
8 | )
9 |
10 | //go:generate rm -f resolvers.go
11 | //go:generate go run ../../../../testdata/gqlgen.go -config gqlgen.yml
12 |
13 | func TestResolverReturnTypes(t *testing.T) {
14 | // verify that the return value of the User resolver is a struct, not a pointer
15 | require.Equal(t, "struct", reflect.TypeOf((&queryResolver{}).User).Out(0).Kind().String())
16 | // the UserPointer resolver should return a pointer
17 | require.Equal(t, "ptr", reflect.TypeOf((&queryResolver{}).UserPointer).Out(0).Kind().String())
18 | }
19 |
--------------------------------------------------------------------------------
/plugin/resolvergen/testdata/return_values/schema.graphqls:
--------------------------------------------------------------------------------
1 | type User {
2 | id: ID!
3 | name: String!
4 | }
5 |
6 | type Query {
7 | user: User!
8 | userPointer: User
9 | }
10 |
--------------------------------------------------------------------------------
/plugin/resolvergen/testdata/schema.graphql:
--------------------------------------------------------------------------------
1 | type Query {
2 | resolver: Resolver!
3 | }
4 |
5 | type Resolver {
6 | name: String!
7 | }
8 |
--------------------------------------------------------------------------------
/plugin/resolvergen/testdata/singlefile/gqlgen.yml:
--------------------------------------------------------------------------------
1 | schema:
2 | - "testdata/schema.graphql"
3 |
4 | exec:
5 | filename: testdata/singlefile/out/ignored.go
6 | model:
7 | filename: testdata/singlefile/out/generated.go
8 | resolver:
9 | filename: testdata/singlefile/out/resolver.go
10 | type: CustomResolverType
11 | preserve_resolver: false
12 |
13 | models:
14 | Resolver:
15 | model: github.com/99designs/gqlgen/plugin/resolvergen/testdata/singlefile/out.Resolver
16 |
17 | omit_gqlgen_version_in_file_notice: true
18 |
--------------------------------------------------------------------------------
/plugin/resolvergen/testdata/singlefile/out/model.go:
--------------------------------------------------------------------------------
1 | package customresolver
2 |
3 | import "context"
4 |
5 | type Resolver struct{}
6 |
7 | type QueryResolver interface {
8 | Resolver(ctx context.Context) (*Resolver, error)
9 | }
10 |
11 | type ResolverResolver interface {
12 | Name(ctx context.Context, obj *Resolver) (string, error)
13 | }
14 |
--------------------------------------------------------------------------------
/plugin/resolvergen/testdata/singlefile_preserve/gqlgen.yml:
--------------------------------------------------------------------------------
1 | schema:
2 | - "testdata/schema.graphql"
3 |
4 | exec:
5 | filename: testdata/singlefile_preserve/out/ignored.go
6 | model:
7 | filename: testdata/singlefile_preserve/out/generated.go
8 | resolver:
9 | filename: testdata/singlefile_preserve/out/resolver.go
10 | type: CustomResolverType
11 | preserve_resolver: true
12 |
13 | models:
14 | Resolver:
15 | model: github.com/99designs/gqlgen/plugin/resolvergen/testdata/singlefile_preserve/out.Resolver
16 |
17 | omit_gqlgen_version_in_file_notice: true
18 |
--------------------------------------------------------------------------------
/plugin/resolvergen/testdata/singlefile_preserve/out/model.go:
--------------------------------------------------------------------------------
1 | package customresolver
2 |
3 | import "context"
4 |
5 | type Resolver struct{}
6 |
7 | type QueryResolver interface {
8 | Resolver(ctx context.Context) (*Resolver, error)
9 | }
10 |
11 | type ResolverResolver interface {
12 | Name(ctx context.Context, obj *Resolver) (string, error)
13 | }
14 |
--------------------------------------------------------------------------------
/testdata/gomod-with-leading-comments.mod:
--------------------------------------------------------------------------------
1 | // main module of gqlgen
2 |
3 | // and another module to test stripping of comment lines
4 |
5 | module github.com/99designs/gqlgen // replace it for new project
6 |
7 | go 1.18
8 |
--------------------------------------------------------------------------------