使用 StepZen 将 PostgreSQL 数据部署为 GraphQL API

首先

本文介绍了使用StepZen将PostgreSQL数据转换为GraphQL API的方法。
StepZen是一个可以轻松集成和统一GraphQL和REST API的GraphQL API构建服务,它能够将多个数据源整合为一个端点。通过创建GraphQL模式和数据的集成非常容易,这使得前端开发人员可以在不用关注后端细节的情况下访问所需的数据。

我是参考StepZen的官方文档(使用@dbquery自定义指令开始使用PostgreSQL数据库)来进行验证的,使用了模拟的只读数据库。我想整理一下在实际尝试中发现的问题和感受。

希望的读者

假设您熟悉GraphQL的指令。

指令 – Apollo GraphQL 文档 参考

数据库的构建

可以使用以下连接信息连接到本文中使用的数据库。

host: postgresql.introspection.stepzen.net
database name: introspection
username: testUserIntrospection
password: HurricaneStartingSample1934

而且,所使用的数据库由六个表组成,包括顾客(customer)、住址(address)、订单(order)、商品(products)、管理顾客和住址之间关系的中间表(customeraddress)、管理订单和商品之间关系的中间表(lineitem)。每个表之间的关系如下所示。

顾客和地址之间是多对多的关系,通过中间表格(customeraddress)进行连接。
顾客和订单之间是一对多的关系。
订单和商品之间是多对多的关系,通过中间表格(lineitem)进行连接。

在下图中,展示了一个实体关系图。

Screenshot 2023-07-02 at 22.54.16.png

安装和设置StepZen CLI

按照 StepZen 的官方文档(StepZen 安装和设置),首先安装 StepZen CLI。如果已经安装了 Node.js,可以使用 npm install -g stepzen 进行安装。接下来,创建 StepZen 账户并从仪表板获取 Admin Key,然后使用 stepzen login 命令进行登录。

使用StepZen创建GraphQL API。

按照StepZen官方文档(使用@dbquery自定义指令开始使用PostgreSQL数据库)的步骤,使用stepzen import postgresql命令来根据数据库的模式信息生成GraphQL配置文件。

我們將以對話方式回答關於數據庫連接信息等的問題。

? What would you like your endpoint to be called? api/opining-condor
? What is your host? postgresql.introspection.stepzen.net
? What is the username? testUserIntrospection
? What is the password? [hidden]
? What is your database name? introspection
? What is your database schema (leave blank to use defaults)? 
? Automatically link types based on foreign key relationships using @materializer
 (https://stepzen.com/docs/features/linking-types) Yes
Starting... done

在这里,最后一个问题是什么?通过使用@materializer(https://stepzen.com/docs/features/linking-types)根据外键关系自动链接类型,可以将基于外键约束的关系映射到分层的GraphQL定义中。执行上述命令后,将会生成以下文件。

hello-stepzen
├── config.yaml
├── index.graphql
├── postgresql
│   └── index.graphql
└── stepzen.config.json

StepZen的配置文件为stepzen.config.json,其中包含了端点名称等信息。

{
  "endpoint": "api/willing-dingo"
}

为了连接到PostgreSQL,已生成了一个config.yaml文件。此文件将在稍后被postgresql/index.graphql引用。

configurationset:
  - configuration:
      name: postgresql_config
      uri: postgresql://postgresql.introspection.stepzen.net/introspection?user=testUserIntrospection&password=HurricaneStartingSample1934

在顶层的GraphQL模式中,生成了index.graphql文件。您可以使用@sdl指令来指定其他模式文件。关于StepZen提供的指令,可以在官方文档(GraphQL指令参考@rest @dbquery @graphql @materializer)中找到说明。

schema @sdl(files: ["postgresql/index.graphql"]) {
  query: Query
}

使用StepZen创建的GraphQL API会生成以下类型的查询和变更操作,与PostgreSQL表对应的GraphQL schema现在已经生成了,位于`postgresql/index.graphql`。该文件中使用了`@materializer`和`@dbquery`等指令。

    • Query

id による個別の取得
List 全体の取得
PaginatedList 範囲指定による取得
ViaXXX 多対多リレーションのフィルタリング
UsingXXXfkey 外部キーによるフィルタリング
UsingXXXidx インデックス付きカラムによるフィルタリング

Mutation

insert
delete
update

然而,默认情况下,不会生成用于对多对多关系表(例如customeraddress或lineitem)进行CRUD操作的端点。

postgresql/index.graphql(内容太长,已折叠)postgresql/index.graphql
地址类型(Address):
– 城市(citi):字符串(String)
– 国家地区(countryregion):字符串(String)
– 客户(customer):[顾客(Customer)] @materializer(query: “customerViaCustomeraddress”)
– ID(id):整数(Int),必选(!)
– 邮编(postalcode):字符串(String)
– 州/省(stateprovince):字符串(String)
– 街道(street):字符串(String)

顾客类型(Customer):
– 地址(address):[地址(Address)] @materializer(query: “addressViaCustomeraddress”)
– 电子邮件(email):字符串(String),必选(!)
– ID(id):整数(Int),必选(!)
– 姓名(name):字符串(String),必选(!)
– 订单(order):[订单(Order)] @materializer(query: “orderUsingOrder_customerid_fkey”)

订单项类型(Lineitem):
– 订单(order):订单(Order) @materializer(query: “orderUsingLineitem_orderid_fkey”)
– 订单ID(orderid):整数(Int),必选(!)
– 商品(product):商品(Product) @materializer(query: “productUsingLineitem_productid_fkey”)
– 商品ID(productid):整数(Int),必选(!)
– 数量(quantity):整数(Int)

订单类型(Order):
– 快递承运人(carrier):字符串(String)
– 创建日期(createdat):日期(Date),必选(!)
– 顾客(customer):顾客(Customer) @materializer(query: “customerUsingOrder_customerid_fkey”)
– 顾客ID(customerid):整数(Int),必选(!)
– ID(id):整数(Int),必选(!)
– 订单项(lineitem):订单项(Lineitem) @materializer(query: “lineitemUsingLineitem_orderid_fkey”)
– 运费(shippingcost):浮点数(Float)
– 跟踪ID(trackingid):字符串(String)

商品类型(Product):
– 描述(description):字符串(String)
– ID(id):整数(Int),必选(!)
– 图片(image):字符串(String)
– 订单项(lineitem):订单项(Lineitem) @materializer(query: “lineitem”)
– 标题(title):字符串(String)

“””
以下查询只是一组访问模式的示例。
请随意修改或添加更多。
“””
查询类型(Query):
“查询地址类型”
getAddress(id: Int!): 地址(Address)
@dbquery(
type: “postgresql”
schema: “public”
table: “address”
configuration: “postgresql_config”
)
getAddressList: [地址(Address)]
@dbquery(
type: “postgresql”
schema: “public”
table: “address”
configuration: “postgresql_config”
)
getAddressPaginatedList(first: Int, after: Int): [地址(Address)]
@dbquery(
type: “postgresql”
schema: “public”
query: “””
SELECT “city”, “countryregion”, “id”, “postalcode”, “stateprovince”, “street” FROM “address” ORDER BY “id” LIMIT $1 OFFSET $2
“””
configuration: “postgresql_config”
)
getCustomersViaCustomerAddress(id: Int!): [顾客(Customer)]
@dbquery(
type: “postgresql”
schema: “public”
query: “””
SELECT T.”email”, T.”id”, T.”name”
FROM “customer” T, “customeraddress” V
WHERE
V.”addressid” = $1 AND
V.”customerid” = T.”id”
“””
configuration: “postgresql_config”
)

自定义API时的要点

在StepZen中,您可以通过修改生成的postgresql/index.graphql等文件来自定义API。通过使用@dbquery指令直接编写SQL,您可以进行复杂的过滤和连接操作。此外,按照上述模式文件的描述,您还可以使用@materializer指令生成分层的GraphQL API。

请参阅官方文档(使用@dbquery自定义指令开始使用PostgreSQL数据库)以获取更详细的信息。

通过利用这些指令,您可以精确地自定义API的行为。

个人感受

据我调查,据说 StepZen 不支持处理验证。不过,由于可以在模式中指定类型,如果是没有副作用的数据获取查询,应该没有问题。然而,在 Mutation 方面,无法使用验证可能成为一个问题。作为对此的一个解决方案,可以考虑使用由 StepZen 生成的 GraphQL API 仅使用查询的方法。对于验证的实现方法,我将继续进行调查。

此外,使用诸如@dbquery和@materializer等指令进行定制化非常方便,因为可以轻松进行各种设置。这些设置可以在.graphql文件中进行描述,无需记忆特定的语法格式,这也是一个优点。此外,由于可以声明性地进行描述,因此可以将其视为代码进行管理(IaC:基础设施即代码),这也具有一定的优势。

結尾

我解释了使用StepZen将PostgreSQL数据转换为GraphQL API的方法。通过查看生成的文件内容,我能够理解StepZen的工作原理。我还发现了其他看起来很有用的功能,所以我打算继续调查。

广告
将在 10 秒后关闭
bannerAds