Node.js API设计
介绍
API(应用程序编程接口)是不同软件系统之间交互的桥梁。在Node.js后端开发中,设计良好的API能够提高系统的可扩展性、可维护性和用户体验。本文将介绍RESTful API和GraphQL的设计原则和实践。
原理
RESTful API原理
REST(表述性状态传递)是一种软件架构风格,基于HTTP协议设计:
- 资源:通过URI标识的实体
- 表述:资源的表现形式(如JSON、XML)
- 状态转移:通过HTTP方法(GET、POST、PUT、DELETE等)改变资源状态
- 无状态:服务器不保存客户端状态,每次请求都是独立的
GraphQL原理
GraphQL是一种用于API的查询语言和运行时环境:
- 允许客户端精确指定需要的数据
- 使用类型系统定义数据结构
- 支持嵌套查询和 mutations
- 单一端点,通过查询参数控制返回数据
图示
RESTful API流程
客户端 -> HTTP请求(方法+URI+头部+体) -> 服务器 -> HTTP响应(状态码+头部+体) -> 客户端
GraphQL流程
客户端 -> GraphQL查询 -> 服务器 -> 解析器 -> 数据源 -> 解析器 -> GraphQL响应 -> 客户端
实例
RESTful API实现 (使用Express)
// app.js
const express = require('express');
const app = express();
app.use(express.json());
// 模拟数据
let users = [
{ id: 1, name: 'John Doe', email: 'john@example.com' },
{ id: 2, name: 'Jane Smith', email: 'jane@example.com' }
];
// 获取所有用户
app.get('/api/users', (req, res) => {
res.json(users);
});
// 获取单个用户
app.get('/api/users/:id', (req, res) => {
const user = users.find(u => u.id === parseInt(req.params.id));
if (!user) return res.status(404).send('User not found');
res.json(user);
});
// 创建用户
app.post('/api/users', (req, res) => {
const user = {
id: users.length + 1,
name: req.body.name,
email: req.body.email
};
users.push(user);
res.status(201).json(user);
});
// 更新用户
app.put('/api/users/:id', (req, res) => {
const user = users.find(u => u.id === parseInt(req.params.id));
if (!user) return res.status(404).send('User not found');
user.name = req.body.name;
user.email = req.body.email;
res.json(user);
});
// 删除用户
app.delete('/api/users/:id', (req, res) => {
const user = users.find(u => u.id === parseInt(req.params.id));
if (!user) return res.status(404).send('User not found');
const index = users.indexOf(user);
users.splice(index, 1);
res.json(user);
});
const port = process.env.PORT || 3000;
app.listen(port, () => console.log(`Server running on port ${port}`));
GraphQL实现 (使用Apollo Server)
- 安装依赖
npm install apollo-server-express express
- 实现GraphQL服务
// app.js
const express = require('express');
const { ApolloServer, gql } = require('apollo-server-express');
// 模拟数据
let users = [
{ id: 1, name: 'John Doe', email: 'john@example.com', posts: [1, 2] },
{ id: 2, name: 'Jane Smith', email: 'jane@example.com', posts: [3] }
];
let posts = [
{ id: 1, title: 'Post 1', content: 'Content 1', authorId: 1 },
{ id: 2, title: 'Post 2', content: 'Content 2', authorId: 1 },
{ id: 3, title: 'Post 3', content: 'Content 3', authorId: 2 }
];
// 定义类型
const typeDefs = gql`
type User {
id: ID!
name: String!
email: String!
posts: [Post!]!
}
type Post {
id: ID!
title: String!
content: String!
authorId: ID!
author: User!
}
type Query {
users: [User!]!
user(id: ID!): User
posts: [Post!]!
post(id: ID!): Post
}
type Mutation {
createUser(name: String!, email: String!): User!
updateUser(id: ID!, name: String, email: String): User
deleteUser(id: ID!): User
}
`;
// 定义解析器
const resolvers = {
User: {
posts: (parent) => posts.filter(post => post.authorId === parent.id)
},
Post: {
author: (parent) => users.find(user => user.id === parent.authorId)
},
Query: {
users: () => users,
user: (_, { id }) => users.find(user => user.id === parseInt(id)),
posts: () => posts,
post: (_, { id }) => posts.find(post => post.id === parseInt(id))
},
Mutation: {
createUser: (_, { name, email }) => {
const user = {
id: users.length + 1,
name,
email,
posts: []
};
users.push(user);
return user;
},
updateUser: (_, { id, name, email }) => {
const user = users.find(user => user.id === parseInt(id));
if (!user) return null;
if (name) user.name = name;
if (email) user.email = email;
return user;
},
deleteUser: (_, { id }) => {
const user = users.find(user => user.id === parseInt(id));
if (!user) return null;
const index = users.indexOf(user);
users.splice(index, 1);
return user;
}
}
};
// 创建Apollo服务器
const server = new ApolloServer({ typeDefs, resolvers });
// 创建Express应用
const app = express();
server.applyMiddleware({ app });
const port = process.env.PORT || 3000;
app.listen({ port }, () =>
console.log(`Server running at http://localhost:${port}${server.graphqlPath}`)
);
专业解决方案
API文档
- Swagger/OpenAPI:自动生成RESTful API文档
- GraphQL Playground:交互式GraphQL文档
身份验证与授权
- JWT(JSON Web Tokens):无状态的身份验证
- OAuth 2.0:授权框架
- Passport.js:灵活的身份验证中间件
API网关
- Express Gateway:基于Express的API网关
- Kong:云原生API网关
- AWS API Gateway:托管的API网关服务
性能优化
- 数据缓存:使用Redis缓存频繁访问的数据
- 响应压缩:使用压缩中间件减小响应大小
- 限流:防止API被过度使用
- 分页:处理大量数据的查询请求
安全最佳实践
- 输入验证:使用joi、express-validator等工具验证输入数据
- 防止SQL注入:使用参数化查询或ORM/ODM
- 防止XSS攻击:对用户输入进行转义和过滤
- 设置适当的HTTP头部:使用helmet中间件
- CORS配置:正确配置跨域资源共享