Ent项目:自动生成GraphQL过滤器指南

Ent项目:自动生成GraphQL过滤器指南

ent ent: 是一个基于 Go 语言的轻量级 ORM 库,用于处理关系型数据库。适合开发者使用 ent 进行数据库访问和操作。 ent 项目地址: https://gitcode.com/gh_mirrors/en/ent

概述

Ent作为一个强大的Go语言实体框架,近期推出了自动生成GraphQL过滤器的功能。这项功能允许开发者直接从Ent的schema定义生成类型安全的GraphQL过滤器(即Where谓词),并能够无缝地将GraphQL查询映射到Ent查询。本文将详细介绍这一功能的背景、实现方式和使用方法。

背景与设计理念

Ent框架的核心设计原则之一是"通过代码生成提供静态类型和显式API"。这意味着对于开发者定义的每个实体,Ent都会生成明确、类型安全的代码,用于高效地与数据进行交互。

GraphQL作为一种API查询语言,同样强调类型安全。Ent与GraphQL的集成让开发者能够轻松创建与Ent映射的API服务器,进行数据库数据的增删改查操作。

自动生成GraphQL过滤器

生成过滤器输入类型

要为ent/schema中的每种类型生成过滤器输入类型(如TodoWhereInput),需要修改ent/entc.go配置文件:

func main() {
    ex, err := entgql.NewExtension(
        entgql.WithWhereFilters(true),
        entgql.WithConfigPath("../gqlgen.yml"),
        entgql.WithSchemaPath("<PATH-TO-GRAPHQL-SCHEMA>"),
    )
    if err != nil {
        log.Fatalf("creating entgql extension: %v", err)
    }
    err = entc.Generate("./schema", &gen.Config{}, entc.Extensions(ex))
    if err != nil {
        log.Fatalf("running ent codegen: %v", err)
    }
}

运行go generate ./ent/...后,Ent会为schema中的每种类型生成对应的<T>WhereInput类型,并自动更新GraphQL schema。

生成的过滤器类型示例

生成的过滤器类型包括:

// TodoWhereInput代表用于过滤Todo查询的where输入
type TodoWhereInput struct {
    Not *TodoWhereInput   `json:"not,omitempty"`
    Or  []*TodoWhereInput `json:"or,omitempty"`
    And []*TodoWhereInput `json:"and,omitempty"`

    // "created_at"字段谓词
    CreatedAt      *time.Time  `json:"createdAt,omitempty"`
    CreatedAtNEQ   *time.Time  `json:"createdAtNEQ,omitempty"`
    CreatedAtIn    []time.Time `json:"createdAtIn,omitempty"`
    CreatedAtNotIn []time.Time `json:"createdAtNotIn,omitempty"`
    CreatedAtGT    *time.Time  `json:"createdAtGT,omitempty"`
    CreatedAtGTE   *time.Time  `json:"createdAtGTE,omitempty"`
    CreatedAtLT    *time.Time  `json:"createdAtLT,omitempty"`
    CreatedAtLTE   *time.Time  `json:"createdAtLTE,omitempty"`

    // 其他字段谓词...
}

对应的GraphQL schema也会相应更新:

input TodoWhereInput {
  not: TodoWhereInput
  and: [TodoWhereInput!]
  or: [TodoWhereInput!]
  
  """created_at字段谓词"""
  createdAt: Time
  createdAtNEQ: Time
  createdAtIn: [Time!]
  createdAtNotIn: [Time!]
  createdAtGT: Time
  createdAtGTE: Time
  createdAtLT: Time
  createdAtLTE: Time
  
  # 其他字段谓词...
}

使用生成的过滤器

1. 修改GraphQL schema

在GraphQL schema中添加where参数:

type Query {
  todos(
    after: Cursor,
    first: Int,
    before: Cursor,
    last: Int,
    orderBy: TodoOrder,
    where: TodoWhereInput,
  ): TodoConnection!
}

2. 在解析器中使用过滤器

在GraphQL解析器中使用生成的过滤器:

func (r *queryResolver) Todos(ctx context.Context, after *ent.Cursor, first *int, before *ent.Cursor, last *int, orderBy *ent.TodoOrder, where *ent.TodoWhereInput) (*ent.TodoConnection, error) {
    return r.client.Todo.Query().
        Paginate(ctx, after, first, before, last,
            ent.WithTodoOrder(orderBy),
            ent.WithTodoFilter(where.Filter),
        )
}

过滤器规范

逻辑运算符

可以使用notandor字段添加逻辑运算符:

{
  or: [
    {
      status: COMPLETED,
    },
    {
      not: {
        hasParent: true,
        status: IN_PROGRESS,
      }
    }
  ]
}

当提供多个过滤字段时,Ent会隐式添加And运算符。

边/关系过滤器

边(关系)谓词可以使用与Ent相同的语法表达:

{
  hasParent: true,
  hasChildrenWith: {
    status: IN_PROGRESS,
  }
}

这将生成以下Ent查询:

client.Todo.
    Query().
    Where(
        todo.HasParent(),
        todo.HasChildrenWith(
            todo.StatusEQ(todo.StatusInProgress),
        ),
    ).
    All(ctx)

实际应用示例

假设我们需要查询所有状态为"COMPLETED"的待办事项,可以执行以下GraphQL查询:

query QueryAllCompletedTodos {
  todos(
    where: {
      status: COMPLETED,
    },
  ) {
    edges {
      node {
        id
      }
    }
  }
}

更复杂的查询示例如下:

query FilterTodos {
  todos(
    where: {
      or: [
        {
          hasParent: false,
          status: COMPLETED,
        },
        {
          status: IN_PROGRESS,
          hasParentWith: {
            priorityLT: 1,
            statusNEQ: COMPLETED,
          },
        }
      ]
    },
  ) {
    edges {
      node {
        id
      }
    }
  }
}

总结

Ent的自动GraphQL过滤器生成功能将Ent的类型安全特性扩展到了API层,为开发者提供了从数据库到API的一致开发体验。通过简单的配置,开发者可以获得强大的过滤能力,同时保持代码的类型安全和可维护性。

这项功能特别适合需要构建复杂查询接口的应用场景,能够显著减少样板代码的编写,提高开发效率。

ent ent: 是一个基于 Go 语言的轻量级 ORM 库,用于处理关系型数据库。适合开发者使用 ent 进行数据库访问和操作。 ent 项目地址: https://gitcode.com/gh_mirrors/en/ent

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

丁操余

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值