API设计完全指南:RESTful与GraphQL最佳实践
"优秀的API设计是系统集成的基石。清晰的接口规范、合理的版本策略、完善的安全机制,让API易于理解、使用和维护。"
一、RESTful API设计原则
REST架构风格强调资源的表述和状态转移,核心原则包括: 资源为中心:URL表示资源,HTTP方法表示操作 无状态:每个请求包含所有必要信息 统一接口:遵循一致的约定URL设计规范
# 使用名词表示资源,使用复数形式
GET /users # 获取用户列表
POST /users # 创建新用户
GET /users/{id} # 获取指定用户
PUT /users/{id} # 更新指定用户(完整替换)
PATCH /users/{id} # 部分更新用户
DELETE /users/{id} # 删除用户
# 资源嵌套表示关系
GET /users/{id}/orders # 获取用户的订单
POST /users/{id}/orders # 为用户创建订单
# 使用查询参数过滤和分页
GET /users?role=admin&sort=-created_at
GET /users?page=2&limit=20
HTTP状态码使用
200 OK # 成功处理请求 201 Created # 成功创建资源 204 No Content # 成功但无返回内容(删除操作) 400 Bad Request # 请求参数错误 401 Unauthorized # 未认证 403 Forbidden # 无权限 404 Not Found # 资源不存在 409 Conflict # 资源冲突 500 Internal Server Error # 服务器错误 503 Service Unavailable # 服务不可用
二、API响应格式
统一响应结构
{
"code": 0,
"message": "success",
"data": {
"users": [...],
"pagination": {
"page": 1,
"limit": 20,
"total": 100,
"totalPages": 5
}
}
}
// 错误响应
{
"code": 40001,
"message": "用户名已存在",
"errors": [
{
"field": "username",
"message": "该用户名已被注册"
}
]
}
三、API版本管理
# URL路径版本(推荐) /api/v1/users /api/v2/users # HTTP头部版本 Accept: application/vnd.myapi.v1+json # 查询参数版本 /api/users?version=1
四、GraphQL实践
Schema定义
type User {
id: ID!
username: String!
email: String!
role: Role!
orders: [Order!]!
createdAt: DateTime!
}
type Order {
id: ID!
user: User!
items: [OrderItem!]!
total: Float!
status: OrderStatus!
}
enum Role {
ADMIN
USER
GUEST
}
type Query {
user(id: ID!): User
users(filter: UserFilter, page: Int, limit: Int): UserConnection!
}
type Mutation {
createUser(input: CreateUserInput!): User!
updateUser(id: ID!, input: UpdateUserInput!): User!
deleteUser(id: ID!): Boolean!
}
input CreateUserInput {
username: String!
email: String!
password: String!
}
解析器实现
const resolvers = {
Query: {
user: async (_, { id }, { dataSources }) => {
return dataSources.userAPI.getUserById(id);
},
users: async (_, { filter, page = 1, limit = 20 }, { dataSources }) => {
const { users, total } = await dataSources.userAPI.getUsers(filter, page, limit);
return {
data: users,
pagination: {
page,
limit,
total,
totalPages: Math.ceil(total / limit)
}
};
}
},
User: {
orders: async (user, _, { dataSources }) => {
return dataSources.orderAPI.getOrdersByUserId(user.id);
}
},
Mutation: {
createUser: async (_, { input }, { dataSources }) => {
const user = await dataSources.userAPI.createUser(input);
return user;
}
}
};
五、API安全实践
认证机制
// JWT认证中间件
const authMiddleware = (req, res, next) => {
const token = req.headers.authorization?.split(' ')[1];
if (!token) {
return res.status(401).json({ message: '未提供认证令牌' });
}
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET);
req.user = decoded;
next();
} catch (error) {
return res.status(401).json({ message: '令牌无效或已过期' });
}
};
// OAuth2.0授权码流程
const oauthCallback = async (code) => {
const response = await fetch('https://oauth.provider.com/token', {
method: 'POST',
body: new URLSearchParams({
grant_type: 'authorization_code',
code,
client_id: process.env.CLIENT_ID,
client_secret: process.env.CLIENT_SECRET,
redirect_uri: process.env.REDIRECT_URI
})
});
const { access_token, refresh_token } = await response.json();
return { accessToken: access_token, refreshToken: refresh_token };
};
限流与防护
// 限流中间件
const rateLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15分钟
max: 100, // 最多100次请求
message: {
code: 42901,
message: '请求过于频繁,请稍后再试'
},
keyGenerator: (req) => {
return req.user?.id || req.ip;
}
});
app.use('/api', rateLimiter);
// 参数验证
const validateUser = celebrate({
body: Joi.object({
username: Joi.string().alphanum().min(3).max(30).required(),
email: Joi.string().email().required(),
password: Joi.string().pattern(new RegExp('^[a-zA-Z0-9]{8,30}$')).required()
})
});
app.post('/api/v1/users', validateUser, createUser);
六、API文档
OpenAPI规范
openapi: 3.0.3
info:
title: My API
version: 1.0.0
paths:
/users:
get:
summary: 获取用户列表
parameters:
- name: page
in: query
schema:
type: integer
default: 1
- name: limit
in: query
schema:
type: integer
default: 20
responses:
'200':
description: 成功
content:
application/json:
schema:
$ref: '#/components/schemas/UserList'
post:
summary: 创建用户
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateUser'
responses:
'201':
description: 创建成功
components:
schemas:
User:
type: object
properties:
id:
type: integer
username:
type: string
email:
type: string
总结
优秀的API设计需要遵循一致的规范,提供清晰的文档,并确保安全性。RESTful适合简单的CRUD场景,GraphQL适合复杂数据查询。无论选择哪种方式,都要注重开发者体验,让API易于理解和使用。本文链接:https://www.kkkliao.cn/?id=853 转载需授权!
版权声明:本文由廖万里的博客发布,如需转载请注明出处。



手机流量卡
免费领卡
号卡合伙人
产品服务
关于本站
