GraphQL 是一种用于 API 开发的查询语言,它提供了一种更加灵活、高效和强类型的方式来获取数据。在 GraphQL 中,数据验证和类型约束是非常重要的一部分,它可以帮助我们在运行查询之前,检查输入的数据是否符合规范,以及保证返回的数据类型正确无误。本文将介绍 GraphQL 中的数据验证和类型约束,以及如何使用它们来构建更加健壮和安全的 API。
数据验证
在 GraphQL 中,我们可以使用 Schema 和 Type 来定义 API 中的数据模型,以及定义输入参数和返回值的数据类型。GraphQL 提供了多种数据类型,包括标量类型、枚举类型、对象类型、接口类型和联合类型等。在定义 Schema 和 Type 的时候,我们可以使用一些约束条件来限制输入参数和返回值的数据类型和取值范围,比如:
type User {
id: ID!
name: String!
email: String!
age: Int
}在上面的示例中,我们定义了一个 User 类型,包含四个字段:id、name、email 和 age。其中,id 和 name 是必填项,使用了感叹号表示非空类型;email 是必填项但没有使用感叹号,表示可选但一旦提供值就必须是字符串类型;age 是可选项,表示可以是整数类型或者空值。这样一来,在使用 GraphQL 查询这个 User 类型的时候,输入参数的数据类型和取值会被按照定义的约束条件进行验证,确保输入的数据是合法的,同时返回值的数据类型也会受到约束,确保返回的数据是正确的。
类型约束
除了数据验证之外,GraphQL 还提供了更加严格的类型约束机制,可以帮助我们在编写代码时更加准确和安全。例如,在 resolver 函数中,对查询结果进行处理时,如果数据类型不对或者取值不在规定范围内,会导致运行时异常或错误,不仅会损害用户体验,还会导致系统崩溃或被攻击。使用 GraphQL 的类型约束机制,我们可以将这些问题在编译时就捕捉到,并及时修复,减少出错的风险。
在 GraphQL 中,我们可以使用 Interface 和 Union 来定义类型约束。Interface 是一系列共有字段的集合,可以用于描述一个对象的一些基本行为;Union 是一系列可能的类型集合,可以用于描述一个对象可能具有的不同类型。使用 Interface 和 Union 可以使我们的 Schema 更加灵活和高效,同时也更加安全和可维护。
// www.javascriptcn.com code example
interface Node {
id: ID!
}
type User implements Node {
id: ID!
name: String!
email: String!
posts: [Post!]!
}
type Post implements Node {
id: ID!
title: String!
content: String!
author: User!
}在上面的示例中,我们定义了一个 Node 接口,包含一个必须的 id 字段;同时,我们定义了两个类型 User 和 Post,都实现了 Node 接口,表示它们具有 id 字段,并且可以作为查询的结果。这样一来,我们就可以在查询中使用 Node 类型进行查询,返回 User 或 Post 类型的结果,同时对返回结果的数据类型进行了约束,保证了代码的类型安全性。
示例代码
在实际使用 GraphQL 的时候,需要编写 Schema、Type 和 resolver 函数等代码,并使用服务器框架(如 Express、Koa、Apollo 等)来运行 API。下面是一个简单的示例,在 Express 中使用 GraphQL 实现查询 User 和 Post 的 API。
// www.javascriptcn.com code example
const express = require('express');
const { graphqlHTTP } = require('express-graphql');
const { buildSchema } = require('graphql');
const schema = buildSchema(`
interface Node {
id: ID!
}
type User implements Node {
id: ID!
name: String!
email: String!
posts: [Post!]!
}
type Post implements Node {
id: ID!
title: String!
content: String!
author: User!
}
type Query {
user(id: ID!): User
post(id: ID!): Post
}
`);
const users = [
{ id: 1, name: 'Alice', email: 'alice@example.com' },
{ id: 2, name: 'Bob', email: 'bob@example.com' },
];
const posts = [
{ id: 1, title: 'Post 1', content: 'Content 1', author: users[0] },
{ id: 2, title: 'Post 2', content: 'Content 2', author: users[1] },
];
const root = {
user: ({ id }) => users.find(user => user.id === id),
post: ({ id }) => posts.find(post => post.id === id),
};
const app = express();
app.use('/api', graphqlHTTP({
schema,
rootValue: root,
graphiql: true,
}));
app.listen(3000, () => console.log('Server started at http://localhost:3000/api'));在上面的示例中,我们使用 buildSchema 函数来构建 Schema,定义了 Node、User、Post 和 Query 四个 Type,并实现了查询 User 和 Post 的 resolver 函数。然后将 Schema 和 resolver 函数传递给 express-graphql 中间件,启动了一个 GraphQL API 服务器,并可以使用 GraphiQL 界面来测试 API 接口。使用 GraphQL 的数据验证和类型约束机制,可以保证 API 输入和输出的数据类型正确无误,并提高代码的质量和可维护性。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67c8f880e46428fe9efd8239