尝试使用GraphQL Mesh

本文是Ateam LifeDesign Advent Calendar 2022的第一日历的第四天的文章。

首先

GraphQL已成为一种在前端从取回数据的主要技术。本次介绍的是GraphQL Mesh,它不仅可以作为后端的GraphQL服务器,还可以使用GraphQL查询请求gRPC、REST API等,并将这些多个API整合为一个GraphQL服务器的技术。

スクリーンショット 2022-12-02 0.33.52.png

 

使用GraphQL Mesh可以解决上述问题,并且可以轻松构建将多个服务绑定在一起的GraphQL网关。这样做的好处是不需要阅读和创建多个后端API的规范、架构和解析器等,从而节省了大量的工作量和维护难度。

试着使用

这次我们将使用Swagger Petstore作为REST API,使用SpaceX作为GraphQL API,然后试图启动一个将它们整合在一起的GraphQL服务器。

安装所需的软件包

为了使用REST API和GraphQL API,还需要安装OpenAPI和GraphQL的包。

$ yarn add graphql @graphql-mesh/cli @graphql-mesh/openapi @graphql-mesh/graphql

创建Mesh的配置文件

创建一个名为.meshrc.yaml的文件,并在其中描述每个API的配置。

sources:
  - name: PetStore
    handler:
      openapi:
        baseUrl: https://petstore3.swagger.io/api/v3
        source: ./openapi.json
  - name: Space
    handler:
      graphql:
        endpoint: https://api.spacex.land/graphql

只需要按照以下方式在 REST API 中使用,将 handler 设为 openapi,并指定 baseUrl 和 API 文档的路径,Mesh 将会将 API 的 JSON 定义转换成 GraphQL 的模式。在 GraphQL API 中,只需要将 handler 设为 graphql 并设置端点即可完成基本配置。

这就是基本配置的全部内容!让我们立即启动 GraphQL 服务器来试试吧。

尝试启动由Mesh创建的GraphQL服务器。

完成.meshrc.yaml文件后,尝试启动GraphQL服务器。

$ yarn mesh dev

当您启动时,将显示以下日志。

? ?️  Mesh - Server Generating the unified schema...
(node:3356) ExperimentalWarning: The Fetch API is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
? ?️  Mesh - PetStore Dereferencing the bundle
? ?️  Mesh - PetStore Creating the GraphQL Schema from dereferenced schema
Transformed schema is not set yet. Returning a dummy one.
? ?️  Mesh Generating index file in TypeScript
? ?️  Mesh - Server Serving GraphQL Mesh: http://0.0.0.0:4000
? ?️  Mesh Writing index.ts for ESM to the disk.

我认为它放出了蜘蛛网的表情符号,因为“mesh”意味着网眼,太棒了。

スクリーンショット 2022-12-03 0.59.23.png

我想立即撰写查询,首先我们先看一下模式。
当您点击左上方类似书本的图标时,可以查看模式。

スクリーンショット 2022-12-03 2.23.41.png

哦,確實可以看到由REST API(如findPetsByStatus和findPetsByTags)生成的模式和由GraphQL API(如capsules和capsulesPast)生成的模式結合在一起的新模式。更了不起的是,它還能讀取和反映REST API定義的描述。只需在先前提到的簡單設置上,就可以用GraphQL調用REST API,並且很容易地與另一個GraphQL API結合來創建服務器。

我将尝试执行这个查询。

スクリーンショット 2022-12-03 2.32.33.png

我尝试同时调用REST API中的getPetById查询和GraphQL API中的capsules查询。
可以看到分别调用了每个API,并且正确地作为响应返回。太棒了。

尝试追加设置

您还可以在.meshrc.yaml中写入有关模式和查询等的详细选项。
这次我们将尝试设置查询的前缀和命名规则。
首先安装所需的包。

$ yarn add @graphql-mesh/transform-prefix @graphql-mesh/transform-naming-convention

然后,我们将在.meshrc.yaml文件中添加以下设置。

sources:
  - name: PetStore
    handler:
      openapi:
        baseUrl: https://petstore3.swagger.io/api/v3
        source: ./openapi.json
+    transforms:
+      - prefix:
+          mode: wrap
+          includeRootOperations: true
+          value: pet_store_
+      - namingConvention:
+          typeNames: pascalCase
+          fieldNames: camelCase
+          fieldArgumentNames: camelCase
  - name: Space
    handler:
      graphql:
        endpoint: https://api.spacex.land/graphql
+    transforms:
+      - prefix:
+          mode: wrap
+          includeRootOperations: true
+          value: space_
+      - namingConvention:
+          typeNames: pascalCase
+          fieldNames: camelCase
+          fieldArgumentNames: camelCase
スクリーンショット 2022-12-03 17.57.08.png

看起来设置的前缀和命名规则已经反映出来了。
似乎还可以进行其他各种设置。
以上是简单介绍GraphQL Mesh,可以轻松创建GraphQL集成模式。
有兴趣的人可以尝试一下。

多一個小禮物

介绍一种在从前端获取数据时可以使用的方便工具GraphQL Code Generator。使用它可以自动生成类型定义文件和包装自定义查询的useQuery。首先,安装所需的包。

$ yarn add @graphql-codegen/cli @graphql-codegen/typescript @graphql-codegen/typescript-operations @graphql-codegen/typescript-react-apollo

下一步,创建一个名为codegen.yml的文件,并按照以下方式填写内容。

schema:
  - ".mesh/schema.graphql"
documents:
  - "*.graphql"
generates:
  graphql/generated/graphql.ts:
    plugins:
      - "typescript"
      - "typescript-operations"
      - "typescript-react-apollo"

在 `schema` 中,我们可以通过 `Mesh` 来指定生成的 GraphQL schema。`documents` 参数用于指定要创建的查询或片段的路径。`generaters` 参数用于指定生成文件的路径。

配置了 `typescript` 插件的话,它将根据 schema 生成类型。而 `typescript-operations` 插件则根据查询生成类型。如果设置了 `typescript-react-apollo`,它会从 `documents` 指定的 graphql 文件中加载查询,并帮助我们创建一个包装了 Apollo Client 的 `useQuery` 的自定义 hook。

我会试着创建一个查询。

query Test {
  petStoreGetPetById(petId: 1) {
    id
    name
    category {
      name
    }
  }
  spaceCapsules {
    id
    missions {
      flight
      name
    }
  }
}

创建查询后,运行graphql-codegen。

$ yarn graphql-codegen --config codegen.yml

当执行graphql-codegen时,将根据codegen.yml中的generate指定生成相应的文件。
通过查看生成的文件内容,可以确认为test查询生成了一个自定义的钩子函数。

.
.
.
/**
 * __useTestQuery__
 *
 * To run a query within a React component, call `useTestQuery` and pass it any options that fit your needs.
 * When your component renders, `useTestQuery` returns an object from Apollo Client that contains loading, error, and data properties
 * you can use to render your UI.
 *
 * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
 *
 * @example
 * const { data, loading, error } = useTestQuery({
 *   variables: {
 *   },
 * });
 */
export function useTestQuery(baseOptions?: Apollo.QueryHookOptions<TestQuery, TestQueryVariables>) {
        const options = {...defaultOptions, ...baseOptions}
        return Apollo.useQuery<TestQuery, TestQueryVariables>(TestDocument, options);
      }
export function useTestLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<TestQuery, TestQueryVariables>) {
          const options = {...defaultOptions, ...baseOptions}
          return Apollo.useLazyQuery<TestQuery, TestQueryVariables>(TestDocument, options);
        }
export type TestQueryHookResult = ReturnType<typeof useTestQuery>;
export type TestLazyQueryHookResult = ReturnType<typeof useTestLazyQuery>;
export type TestQueryResult = Apollo.QueryResult<TestQuery, TestQueryVariables>;

如果您在组件中导入这个,您就可以进行数据获取,而无需每次导入 useQuery 或查询。
希望对未来的开发有所帮助。

广告
将在 10 秒后关闭
bannerAds