跳到主要内容

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)

  1. 安装依赖
npm install apollo-server-express express
  1. 实现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配置:正确配置跨域资源共享