gqlgen 字段解决方法的使用技巧

gqlgen 是什么?

gqlgen是一个用于Go语言的GraphQL库,它可以根据用户自定义的GraphQL模式生成解析器接口,并且只需实现解析器的实际功能,就能轻松实现基于GraphQL模式的开发。

绑定功能 (baindō

gqlgen提供了数据模型绑定功能,可以将GraphQL的类型和Go应用程序的结构体绑定起来,自动解析字段。

# entity.gql
type User {
  id: ID!
  name: String!
  tags: [Tag!]!
}
// entity/user.go
type User struct {
  ID int
  Name string
}
// entity/tag.go
type Tag struct {
  ID int
  text string
}
# gqlgen.yml
models:
  User:
    model: github.com/yourpkg/entity.User
  Tag:
    model: github.com/yourpkg/entity.Tag
# または
autobind:
  - github.com/yourpkg/entity

按照上述方式,当解决用户时,ID和Name将自动使用User结构体的字段,并且只需要写下述的解析器来解决不存在于结构体中的标签。

func (r *userResolver) Tags(ctx context.Context, obj *User) ([]*Tag, error) {
  return r.tagUsecase.GetTagsByUserID(ctx, obj.ID)
}

此外,还有一种方法是通过将结构体设置如下,而无需编写解析器。

// entities/user.go
type User struct {
  ID int
  Name string
  Tags []*Tag
}

通过在获取用户时进行及早加载,可以自动解析所有字段。

自动生成构造体的功能

gqlgen具有将Go的结构体定义从GraphQL模式中自动生成的功能。如果不使用绑定功能,则可以使用此功能,它会根据先前的模式为我们创建以下结构体。

type User struct {
    ID        ID       `json:"id"`
    Name      string   `json:"name"`
    Tags      []*Tag   `json:"tags"`
}

在中文中如何区别使用

如果你打算使用 gqlgen 创建一个新的 GraphQL API,下面是关于如何使用「绑定到自定义结构体」,「实现解析器」或者「从模式自动生成的模型」的提示。

基本的思维方式

突如ですが、私は基本的にすべてのエンティティに対して自動バインディングを有効にしています。
実際に、gqlgenの利点は、まずGraphQLスキーマを決定し、それに基づいてバックエンドを構築する「スキーマファースト開発」ができることだと考えています。gqlgenにリゾルバの作成を任せ、リゾルバがアプリケーションのユースケースを呼び出すことで、アプリケーション内でGraphQLの概念が混ざらないようにしています。そのため、GraphQLスキーマとは別に、アプリケーション専用のエンティティを定義しています。これらの二つが偶然一致する部分を自動的にバインディングし、一致しないフィールドのリゾルバを個別に実装するという考え方です。

实施领域解析器。

将结构体绑定并解决的意思是,结构体必须以满足字段的状态存在,并且如果将 RDBMS 作为数据存储,则必须在存储库层面取得上述 Tags 等信息时进行 JOIN,并进行 eager loading。这样做可以避免 n+1 的问题,但也忽略了 GraphQL 作为查询语言的特性,即可以仅请求所需字段的能力。

因此,在应用程序中,只允许加入必要的最低限度的内容,以确保仓库层返回给用例层时字段存在,并且其他内容主要由解析器自行处理。为了解决由并行运行的解析器产生的n+1问题,我们使用其他数据加载器等方式进行避免。

基本上,我們使用數據庫的表模型與庫模型相對應形成的表,通過轉換將其填充到實體模型中,在庫層中確保了所有與數據庫相關的gorm標籤和方法等等不會外洩到用例層。

利用从架构中自动生成的结构体

根据上述的观点,我们基本上不使用从模式自动生成主要的类型。然而,我们仅在解析器层中生成需要的类型,而不涉及用例层。
例如,输入类型和用于分页的类型等与mutation相关的类型都是专用于GraphQL的,因此我们仅在解析器中直接使用自动生成的类型。

在这里,我们姑且不谈自动生成用于Fragment的接口定义和通过鸭子类型来表明实体与特定的Fragment相关。

总结

    • GraphQL スキーマとアプリケーションの型は根本的には別に考える

その上で一致したものは gqlgen に任せる
別で考えてもスキーマが要求するものを返すアプリケーションを作るわけだから結局似る

それ以外はリゾルバーで解決する

n+1 を無理に eager loading で解決しようとしない
リポジトリ層はシンプルに

構造体の自動生成は input などの表層モデルでのみ利用する

ビジネスロジックが使うモデルを GraphQL や gqlgen に依存させない

就是这样。

广告
将在 10 秒后关闭
bannerAds