GraphQL 是一种用于 API 的查询语言,它允许客户端精确地指定需要的数据,从而避免了传统 REST API 中的过度获取或不足获取的问题。然而,在使用 GraphQL 进行查询时,我们经常会遇到变量类型检查问题。本文将介绍一些解决 GraphQL 变量类型检查问题的方法。
问题描述
在 GraphQL 中,我们可以通过变量来传递参数。例如,我们可以通过以下查询获取某个用户的信息:
query getUser($id: ID!) { user(id: $id) { id name email age } }
在上面的查询中,我们定义了一个名为 $id
的变量,并指定了它的类型为 ID!
,也就是必须传递一个非空的 ID。然而,在客户端传递变量时,我们很容易出现类型不匹配的问题,例如将一个字符串类型的值传递给了一个期望数字类型的变量。
解决方法
使用 TypeScript
TypeScript 是一种静态类型检查的 JavaScript 超集,它可以帮助我们在编译时发现类型不匹配的问题。在使用 GraphQL 查询时,我们可以使用 graphql-codegen
工具自动生成 TypeScript 类型定义文件,从而在编写客户端代码时获得类型检查的支持。
首先,我们需要安装 graphql-codegen
:
npm install --save-dev graphql-codegen
然后,在项目根目录下创建一个名为 codegen.yml
的文件,用于配置代码生成器。以下是一个示例配置:
schema: https://api.example.com/graphql documents: src/**/*.graphql generates: src/generated/graphql.ts: plugins: - typescript - typescript-operations - typescript-react-apollo
在上面的配置中,我们指定了 GraphQL API 的 schema 和查询文件的路径,并配置了三个插件用于生成 TypeScript 文件。其中,typescript-operations
插件可以根据查询文件自动生成对应的 TypeScript 类型定义文件。
接下来,我们可以使用 graphql-codegen
命令生成 TypeScript 文件:
npx graphql-codegen
这将会根据配置文件自动生成 TypeScript 文件,并保存在 src/generated/graphql.ts
中。然后,我们就可以在客户端代码中使用这些类型定义了,例如:
// javascriptcn.com 代码示例 import { gql } from '@apollo/client'; import { GetUserQuery, GetUserQueryVariables } from './generated/graphql'; const GET_USER = gql` query getUser($id: ID!) { user(id: $id) { id name email age } } `; const variables: GetUserQueryVariables = { id: '123' }; client.query<GetUserQuery>({ query: GET_USER, variables }).then(result => { console.log(result.data.user); });
在上面的代码中,我们使用 GetUserQuery
和 GetUserQueryVariables
类型来指定查询结果和变量的类型,并在查询时传递了一个类型正确的变量。
使用 Joi
Joi 是一个 Node.js 中的对象模式描述语言和验证器,它可以帮助我们对变量进行详细的类型检查和验证。在使用 GraphQL 查询时,我们可以使用 Joi 来对传递的变量进行验证,从而避免类型不匹配的问题。
首先,我们需要安装 joi
:
npm install joi
然后,我们可以使用以下代码来验证变量:
// javascriptcn.com 代码示例 const Joi = require('joi'); const { graphql } = require('graphql'); const { makeExecutableSchema } = require('@graphql-tools/schema'); const typeDefs = ` type Query { user(id: ID!): User } type User { id: ID! name: String! email: String! age: Int! } `; const resolvers = { Query: { user: (parent, { id }) => ({ id, name: 'Alice', email: 'alice@example.com', age: 30, }), }, }; const schema = makeExecutableSchema({ typeDefs, resolvers }); const query = ` query getUser($id: ID!) { user(id: $id) { id name email age } } `; const variables = { id: '123' }; const schemaValidation = Joi.object({ id: Joi.string().required(), }); const variablesValidation = schemaValidation.validate(variables); if (variablesValidation.error) { console.error(variablesValidation.error); } else { graphql(schema, query, null, null, variables).then(result => { console.log(result.data.user); }); }
在上面的代码中,我们首先定义了一个 GraphQL schema 和 resolvers,然后定义了一个查询和变量,并使用 Joi.object
来定义变量的验证规则。最后,我们使用 Joi.validate
方法来验证变量是否符合规则,如果验证通过,则执行 GraphQL 查询并返回结果。
使用 Yup
Yup 是一个 JavaScript 对象模式验证器,它可以帮助我们对变量进行详细的类型检查和验证。在使用 GraphQL 查询时,我们可以使用 Yup 来对传递的变量进行验证,从而避免类型不匹配的问题。
首先,我们需要安装 yup
:
npm install yup
然后,我们可以使用以下代码来验证变量:
// javascriptcn.com 代码示例 const yup = require('yup'); const { graphql } = require('graphql'); const { makeExecutableSchema } = require('@graphql-tools/schema'); const typeDefs = ` type Query { user(id: ID!): User } type User { id: ID! name: String! email: String! age: Int! } `; const resolvers = { Query: { user: (parent, { id }) => ({ id, name: 'Alice', email: 'alice@example.com', age: 30, }), }, }; const schema = makeExecutableSchema({ typeDefs, resolvers }); const query = ` query getUser($id: ID!) { user(id: $id) { id name email age } } `; const variables = { id: '123' }; const schemaValidation = yup.object().shape({ id: yup.string().required(), }); schemaValidation .validate(variables) .then(validatedVariables => { graphql(schema, query, null, null, validatedVariables).then(result => { console.log(result.data.user); }); }) .catch(error => { console.error(error); });
在上面的代码中,我们使用 yup.object().shape
来定义变量的验证规则,并使用 yup.validate
方法来验证变量是否符合规则。如果验证通过,则执行 GraphQL 查询并返回结果,否则抛出异常。
总结
在使用 GraphQL 进行查询时,我们经常会遇到变量类型检查问题。本文介绍了三种解决 GraphQL 变量类型检查问题的方法:使用 TypeScript、使用 Joi 和使用 Yup。这些方法都可以帮助我们在客户端代码中获得类型检查的支持,从而提高代码的可靠性和可维护性。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/655951edd2f5e1655d3c008b