GraphQL代码生成器会生成什么样的代码?
使用GraphQL时,我知道有一款名为GraphQL Code Generator的工具非常方便,可以为我们生成各种代码。
实际上,我通常都是使用预设的设置,但是我意识到自己没有完全理解这个工具是做什么的,所以做了些调查。
GraphQL架构
GraphQL代码生成器的基础是GraphQL模式。
在前端使用TypeScript时,它看起来像TypeScript,但实际上是GraphQL模式语言。
type Human implements Character {
id: ID!
name: String!
friends: [Character]
appearsIn: [Episode]!
starships: [Starship]
totalCredits: Int
}
由于GraphQL Schema不依赖于特定的语言,它具有独特的语法,因此不限制GraphQL服务器的实现语言。
这次要解释的客户端代码将基于此架构生成。
生成客户端代码
可以通过使用GraphQL代码生成器插件来生成各种代码。
我們將介紹一些在這次客戶端中可能常用的東西。
前期准备
由于需要一个模式来进行演示,我们将使用GitHub GraphQL API的模式。
您可以从以下页面下载,然后将其下载并放置在存储库中。
顺便说一下,这次我尝试调整的环境是这个。
@graphql-codegen/cli 的当前版本是 v2.6.2。
1. GraphQL模式的类型定义
根据GraphQL模式生成客户端使用的类型定义文件。
插件将使用TypeScript。
如果设置codegen.yml文件如下所示,将根据GitHub GraphQL API的模式生成类型定义,并存储在src/generated/types.ts中。
overwrite: true
schema: './github.schema.graphql'
documents: 'src/graphql/*.gql'
generates:
src/generated/types.ts:
plugins:
- typescript
当查看其中的内部时,生成了对象的类型、标量、枚举和查询参数的类型。
请你看一下我在这里生成的文件,会有详细信息。
2. 操作类型
這些是在客戶端定義的查詢、突變、訂閱和片段的型別。
我們將使用 TypeScript Operations。
例如,我们定义以下查询。
query GetViewer {
viewer {
login
}
}
当我们添加设置并生成代码时,结果如下所示。
export type GetViewerQueryVariables = Types.Exact<{ [key: string]: never }>
export type GetViewerQuery = {
__typename?: 'Query'
viewer: { __typename?: 'User'; login: string }
}
通过使用本次的查询,了解到该查询没有参数,并且执行查询时会返回上述类型的数据。使用这个功能可以实现类型安全的代码。
3. 创建React hooks
使用TypeScript React Apollo可以生成hooks。
import { useQuery } from '@apollo/client'
import type { GetViewerQuery } from './generated/operations'
import GetViewer from './graphql/GetViewer.gql'
const { data } = useQuery<GetViewerQuery>(GetViewer)
使用到了之前生成的代码,可以按上述方式操作。但是,借助这个插件可以创建一个名为useGetViewerQuery的hooks。
import { useGetViewerQuery } from './generated/graphql'
const { data } = useGetViewerQuery()
只需上面的代码即可减少编写量。
这个实现看起来就像是简单地将useQuery包装起来的。
export function useGetViewerQuery(
baseOptions?: Apollo.QueryHookOptions<
Types.GetViewerQuery,
Types.GetViewerQueryVariables
>
) {
const options = { ...defaultOptions, ...baseOptions };
return Apollo.useQuery<Types.GetViewerQuery, Types.GetViewerQueryVariables>(
GetViewerDocument,
options
);
}
(附注:在调查过程中,还有以下类似的文章,所以并不表示强烈推荐使用。)
我打算以后也试着使用这个。
其他
还有其他各种插件可供选择。
我們剛才介紹的是客戶端用的,但還有用於後端或React以外的庫的插件可用。
此外,GraphQL Code Generator网站的首页上还有一个实时示例,可以很容易地想象出生成的代码是什么样子的,请务必去看一看。
因为有一些我还未能了解的部分,所以我打算更多地尝试和接触!
请参阅
-
- https://www.graphql-code-generator.com
-
- https://graphql.org/learn/schema/
-
- https://qiita.com/shinnoki/items/576277184de0e89cab97
-
- https://qiita.com/suin/items/de0afe49f95990083ffc
- https://docs.github.com/ja/graphql/overview/public-schema