gqlgen README

The project's README from github.com/99designs/gqlgen. As one markdown file: README.md.

gqlgen

gqlgen Integration Coverage Status Go Report Card Go Reference Read the Docs

What is gqlgen?

gqlgen is a Go library for building GraphQL servers without any fuss.

Still not convinced enough to use gqlgen? Compare gqlgen with other Go graphql implementations

Quick start

  1. Initialise a new go module
mkdir example
cd example
go mod init example
  1. Add github.com/99designs/gqlgen to your project, as a tool dependency
go get -tool github.com/99designs/gqlgen
  1. Initialise gqlgen config and generate models
go tool gqlgen init
  1. Start the graphql server
go run server.go

More help to get started:

Reporting Issues

If you think you've found a bug, or something isn't behaving the way you think it should, please raise an issue on GitHub.

Contributing

We welcome contributions, Read our Contribution Guidelines to learn more about contributing to gqlgen

Frequently asked questions

How do I prevent fetching child objects that might not be used?

When you have nested or recursive schema like this:

type User {
	id: ID!
	name: String!
	friends: [User!]!
}

You need to tell gqlgen that it should only fetch friends if the user requested it. There are two ways to do this:

Using Custom Models

Write a custom model that omits the friends field:

type User struct {
  ID int
  Name string
}

And reference the model in gqlgen.yml:

# gqlgen.yml
models:
  User:
    model: github.com/you/pkg/model.User # go import path to the User struct above

Using Explicit Resolvers

If you want to keep using the generated model, mark the field as requiring a resolver explicitly in gqlgen.yml like this:

# gqlgen.yml
models:
  User:
    fields:
      friends:
        resolver: true # force a resolver to be generated

After doing either of the above and running generate we will need to provide a resolver for friends:

func (r *userResolver) Friends(ctx context.Context, obj *User) ([]*User, error) {
  // select * from user where friendid = obj.ID
  return friends,  nil
}

You can also use inline config with directives to achieve the same result

directive @goModel(
	model: String
	models: [String!]
) on OBJECT | INPUT_OBJECT | SCALAR | ENUM | INTERFACE | UNION

directive @goField(
	forceResolver: Boolean
	name: String
	omittable: Boolean
	type: String
  autoBindGetterHaser: Boolean
  forceGenerate: Boolean
	batch: Boolean
) on INPUT_FIELD_DEFINITION | FIELD_DEFINITION

type User @goModel(model: "github.com/you/pkg/model.User") {
	id: ID! @goField(name: "todoId")
	friends: [User!]! @goField(forceResolver: true)
	# When omit_resolver_fields is enabled, this field will still be generated in the struct
	data: String! @goField(forceResolver: true, forceGenerate: true)
}

The field resolvers will be executed concurrently in separate goroutines. The degree of concurrency can be customized with the worker_limit configuration attribute.

Can I change the type of the ID from type String to Type Int?

Yes! You can by remapping it in config as seen below:

models:
  ID: # The GraphQL type ID is backed by
    model:
      - github.com/99designs/gqlgen/graphql.IntID # a go integer
      - github.com/99designs/gqlgen/graphql.ID # or a go string
      - github.com/99designs/gqlgen/graphql.UintID # or a go uint

This means gqlgen will be able to automatically bind to strings or ints for models you have written yourself, but the first model in this list is used as the default type and it will always be used when:

There isn't any way around this, gqlgen has no way to know what you want in a given context.

Why do my interfaces have getters? Can I disable these?

These were added in v0.17.14 to allow accessing common interface fields without casting to a concrete type. However, certain fields, like Relay-style Connections, cannot be implemented with simple getters.

If you'd prefer to not have getters generated in your interfaces, you can add the following in your gqlgen.yml:

# gqlgen.yml
omit_getters: true

Other Resources

gqlgen (99designs/gqlgen)

Searching Database…

10.8K ·GitHub
这是什么?gqlgen 是一个 Go 库,用于构建 GraphQL 服务器,采用 schema 优先、代码生成的方式,无需编写大量样板代码。
这是我要运行的框架,还是我导入的库?它是一个 Go 库,同时结合了基于 go generate 的代码生成器:你编写 GraphQL schema 和少量解析器函数,gqlgen 会为你生成样板代码,包括模型、解析器接口和执行代码。
我怎样用它把 GraphQL 服务器跑起来?初始化一个 Go 模块,将 github.com/99designs/gqlgen 作为 tool 依赖添加到项目中,运行 gqlgen config/generate 步骤来生成模型脚手架,然后启动生成的服务器。
使用它除了 Go 还需要别的东西吗?没有列出其他运行时依赖,只需要一个 Go 模块,并把 gqlgen 作为 tool 依赖添加进来;其余内容(模型、解析器)都会根据你自己的 schema 生成。
使用类型化的 ID 或嵌套解析器有什么坑吗?你可以在配置中重新映射 ID 类型(例如把 String 改为 Int),但列出的第一个类型始终作为生成的模型和解析器参数的默认类型,且无法按上下文单独覆盖。嵌套字段默认会被提前获取,除非你编写自定义模型,或将该字段标记为需要显式解析器。
这个工具适合谁?它和其他 Go 的 GraphQL 库相比怎么样?它面向希望编写类型安全、以 schema 为先的 GraphQL 服务器,又不想手写样板代码的 Go 开发者。README 中有一份专门的对比文档,将它与其他 Go GraphQL 实现进行比较,供正在评估替代方案的人参考。
schema 优先的方式日常到底是怎么工作的?你用 GraphQL 模式定义语言(Schema Definition Language)编写 API,gqlgen 会据此生成对应的 Go 模型和解析器接口,因此 schema 始终是唯一的权威来源。
能不能让查询不总是获取子对象?可以。要么编写一个省略该字段的自定义模型,要么在 gqlgen.yml 中将该字段标记为需要显式解析器,这样 gqlgen 只会在该字段真正被请求时才调用它。
字段解析器是顺序运行还是并行运行?默认情况下它们在各自的 goroutine 中并发运行,并发程度可以通过 workerlimit 配置属性进行调整。
为什么 gqlgen 要避免使用 map[string]interface{}?它优先保证类型安全,因此生成的代码会为你的 schema 使用具体的 Go 结构体和类型,而不是无类型的 map,从而在编译时发现类型不匹配的问题。
Creator
99designs
Size
27.2 MB
Stars
10.8K
Age
8y
Commits · 90 Days