GraphQL 是一种用于 API 的查询语言,它可以帮助前端开发人员更高效地获取数据。然而,许多现有的应用程序都是基于 REST API 构建的,因此如何将 GraphQL 与 REST API 集成是一个值得探讨的话题。
在本文中,我们将介绍如何编写兼容 REST API 的 GraphQL 查询,并提供相关示例代码和指导意义。
REST API 与 GraphQL 的差异
REST API 和 GraphQL 有许多不同之处。其中最显著的区别是 REST API 基于 URL 和 HTTP 方法,而 GraphQL 使用单一入口点和查询语言。
REST API 的 URL 表示资源的地址,而 HTTP 方法表示对该资源执行的操作。例如,使用 GET 方法获取资源,使用 POST 方法创建资源,使用 PUT 方法更新资源,使用 DELETE 方法删除资源。
GraphQL 通过单个入口点(通常是 /graphql)接受查询,并使用查询语言来描述所需的数据。查询语言允许客户端指定其需要的数据,而不是由服务器决定返回什么。
兼容 REST API 的 GraphQL 查询编写方法
为了兼容 REST API,我们需要将 REST API 的 URL 和 HTTP 方法映射到 GraphQL 查询。我们可以使用 GraphQL 的自定义解析器来实现这一点。
以下是一个示例 REST API:
GET /api/users // 获取所有用户 GET /api/users/:id // 获取单个用户 POST /api/users // 创建用户 PUT /api/users/:id // 更新用户 DELETE /api/users/:id // 删除用户
我们可以使用以下 GraphQL 查询来映射上述 REST API:
// www.javascriptcn.com code example
type Query {
users: [User]
user(id: ID!): User
}
type Mutation {
createUser(input: CreateUserInput!): User
updateUser(id: ID!, input: UpdateUserInput!): User
deleteUser(id: ID!): User
}
input CreateUserInput {
name: String!
email: String!
}
input UpdateUserInput {
name: String
email: String
}
type User {
id: ID!
name: String!
email: String!
}在上面的代码中,我们定义了 Query 和 Mutation 类型来映射 REST API 的 URL 和 HTTP 方法。我们还定义了 User 类型来表示用户对象。
对于每个 REST API,我们都定义了相应的查询或变异。例如,users 查询对应于 GET /api/users,user 查询对应于 GET /api/users/:id,createUser 变异对应于 POST /api/users,updateUser 变异对应于 PUT /api/users/:id,deleteUser 变异对应于 DELETE /api/users/:id。
我们还定义了 CreateUserInput 和 UpdateUserInput 输入类型,用于表示创建和更新用户时的输入数据。
示例代码
以下是使用 Node.js 和 Express 实现的示例代码:
// www.javascriptcn.com code example
const express = require('express');
const { graphqlHTTP } = require('express-graphql');
const {
GraphQLSchema,
GraphQLObjectType,
GraphQLList,
GraphQLNonNull,
GraphQLString,
GraphQLID,
} = require('graphql');
const app = express();
const users = [
{ id: '1', name: 'Alice', email: 'alice@example.com' },
{ id: '2', name: 'Bob', email: 'bob@example.com' },
{ id: '3', name: 'Charlie', email: 'charlie@example.com' },
];
const UserType = new GraphQLObjectType({
name: 'User',
fields: {
id: { type: GraphQLNonNull(GraphQLID) },
name: { type: GraphQLNonNull(GraphQLString) },
email: { type: GraphQLNonNull(GraphQLString) },
},
});
const schema = new GraphQLSchema({
query: new GraphQLObjectType({
name: 'Query',
fields: {
users: {
type: GraphQLList(UserType),
resolve: () => users,
},
user: {
type: UserType,
args: {
id: { type: GraphQLNonNull(GraphQLID) },
},
resolve: (_, { id }) => users.find(user => user.id === id),
},
},
}),
mutation: new GraphQLObjectType({
name: 'Mutation',
fields: {
createUser: {
type: UserType,
args: {
input: { type: GraphQLNonNull(CreateUserInputType) },
},
resolve: (_, { input }) => {
const user = { ...input, id: String(users.length + 1) };
users.push(user);
return user;
},
},
updateUser: {
type: UserType,
args: {
id: { type: GraphQLNonNull(GraphQLID) },
input: { type: UpdateUserInputType },
},
resolve: (_, { id, input }) => {
const index = users.findIndex(user => user.id === id);
if (index === -1) {
throw new Error(`User with id ${id} not found`);
}
const user = { ...users[index], ...input };
users[index] = user;
return user;
},
},
deleteUser: {
type: UserType,
args: {
id: { type: GraphQLNonNull(GraphQLID) },
},
resolve: (_, { id }) => {
const index = users.findIndex(user => user.id === id);
if (index === -1) {
throw new Error(`User with id ${id} not found`);
}
const user = users[index];
users.splice(index, 1);
return user;
},
},
},
}),
});
app.use('/graphql', graphqlHTTP({
schema,
graphiql: true,
}));
app.listen(3000, () => {
console.log('Server started on http://localhost:3000');
});在上面的代码中,我们定义了一个 UserType 类型,表示用户对象。我们还定义了一个 schema,包含 Query 和 Mutation 类型。
我们使用 express-graphql 中间件将 GraphQL API 添加到 Express 应用程序中。
指导意义
在使用 GraphQL 与现有的 REST API 集成时,需要考虑以下几点:
- GraphQL 查询应该与现有的 REST API URL 和 HTTP 方法对应。
- GraphQL 查询应该使用自定义解析器来实现与 REST API 的集成。
- GraphQL 查询应该定义输入类型,以表示创建和更新资源时的输入数据。
- GraphQL 查询应该定义错误处理,以处理 REST API 返回的错误信息。
在实现 GraphQL 与现有 REST API 的集成时,需要仔细考虑这些因素,并确保 GraphQL 查询与现有 REST API 兼容。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67d3fc9ba941bf713478c9cd