本文目录导读:

我来详细讲解如何编写RESTful风格路由,包括概念、设计原则和具体实现。
RESTful路由核心原则
资源命名
- 使用名词(复数形式)表示资源
- 使用HTTP方法表示操作
- 使用URL层级表示关系
各种后端框架实现
Node.js (Express)
const express = require('express');
const router = express.Router();
// 获取所有用户
router.get('/users', (req, res) => {
res.json({ users: [] });
});
// 获取单个用户
router.get('/users/:id', (req, res) => {
res.json({ user: { id: req.params.id } });
});
// 创建用户
router.post('/users', (req, res) => {
res.status(201).json({ message: 'Created' });
});
// 更新用户(全量更新)
router.put('/users/:id', (req, res) => {
res.json({ message: 'Updated' });
});
// 部分更新用户
router.patch('/users/:id', (req, res) => {
res.json({ message: 'Partially updated' });
});
// 删除用户
router.delete('/users/:id', (req, res) => {
res.status(204).send();
});
module.exports = router;
Express 路由分组最佳实践
// routes/users.js
const router = require('express').Router();
router.route('/')
.get(getUsers)
.post(createUser);
router.route('/:id')
.get(getUser)
.put(updateUser)
.patch(partialUpdateUser)
.delete(deleteUser);
// 嵌套资源
router.route('/:userId/posts')
.get(getUserPosts)
.post(createUserPost);
router.route('/:userId/posts/:postId')
.get(getUserPost)
.put(updateUserPost)
.delete(deleteUserPost);
module.exports = router;
Python (Flask)
from flask import Flask, request, jsonify
from flask_restful import Api, Resource
app = Flask(__name__)
api = Api(app)
class UserList(Resource):
def get(self):
return {'users': []}
def post(self):
data = request.get_json()
return {'message': 'Created'}, 201
class UserDetail(Resource):
def get(self, user_id):
return {'user': {'id': user_id}}
def put(self, user_id):
return {'message': 'Updated'}
def delete(self, user_id):
return '', 204
api.add_resource(UserList, '/users')
api.add_resource(UserDetail, '/users/<int:user_id>')
if __name__ == '__main__':
app.run(debug=True)
Python (Django REST Framework)
# urls.py
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from . import views
router = DefaultRouter()
router.register(r'users', views.UserViewSet)
urlpatterns = [
path('', include(router.urls)),
]
# views.py
from rest_framework import viewsets
from .models import User
from .serializers import UserSerializer
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
# 自定义动作
@action(detail=True, methods=['post'])
def activate(self, request, pk=None):
user = self.get_object()
user.is_active = True
user.save()
return Response({'status': 'activated'})
Java (Spring Boot)
@RestController
@RequestMapping("/api/users")
public class UserController {
@GetMapping
public ResponseEntity<List<User>> getAllUsers() {
return ResponseEntity.ok(userService.findAll());
}
@GetMapping("/{id}")
public ResponseEntity<User> getUser(@PathVariable Long id) {
return ResponseEntity.ok(userService.findById(id));
}
@PostMapping
public ResponseEntity<User> createUser(@RequestBody @Valid User user) {
User created = userService.save(user);
return ResponseEntity.status(HttpStatus.CREATED).body(created);
}
@PutMapping("/{id}")
public ResponseEntity<User> updateUser(@PathVariable Long id, @RequestBody User user) {
return ResponseEntity.ok(userService.update(id, user));
}
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
userService.delete(id);
return ResponseEntity.noContent().build();
}
}
Ruby on Rails
# config/routes.rb
Rails.application.routes.draw do
resources :users do
resources :posts, shallow: true
member do
get :activate
end
collection do
get :search
end
end
end
# app/controllers/users_controller.rb
class UsersController < ApplicationController
def index
@users = User.all
render json: @users
end
def show
@user = User.find(params[:id])
render json: @user
end
def create
@user = User.new(user_params)
if @user.save
render json: @user, status: :created
else
render json: @user.errors, status: :unprocessable_entity
end
end
end
RESTful路由设计模板
CRUD操作映射
| HTTP方法 | 路由 | 操作 | 状态码 |
|---|---|---|---|
| GET | /users | 获取所有用户 | 200 |
| GET | /users/:id | 获取单个用户 | 200 |
| POST | /users | 创建用户 | 201 |
| PUT | /users/:id | 更新用户 | 200 |
| PATCH | /users/:id | 部分更新 | 200 |
| DELETE | /users/:id | 删除用户 | 204 |
高级路由模式
// 搜索和过滤 GET /api/users?status=active&role=admin GET /api/users?page=1&limit=20&sort=-createdAt // 关系资源 GET /api/users/:userId/orders GET /api/users/:userId/orders/:orderId // 操作动作 POST /api/users/:userId/activate POST /api/orders/:orderId/cancel // 批量操作 POST /api/users/batch DELETE /api/users/batch
最佳实践
版本控制
// URL版本控制 /api/v1/users /api/v2/users // 请求头版本控制 Accept: application/vnd.company.v1+json // 子域名版本控制 v1.api.example.com/users
错误处理
// 统一的错误响应格式
{
"error": {
"code": "USER_NOT_FOUND",
"message": "User with ID 123 not found",
"details": {
"userId": "123"
}
}
}
// 错误状态码使用
200 - 成功
201 - 创建成功
204 - 删除成功
400 - 请求参数错误
401 - 未认证
403 - 无权限
404 - 资源不存在
422 - 验证失败
429 - 请求过多
500 - 服务器错误
分页实现
// 请求
GET /api/users?page=2&limit=20
// 响应
{
"data": [...],
"pagination": {
"page": 2,
"limit": 20,
"total": 100,
"totalPages": 5,
"next": "/api/users?page=3&limit=20",
"prev": "/api/users?page=1&limit=20"
}
}
关联数据
// 包含关联数据
GET /api/users/123?include=posts,settings
// 响应
{
"id": 123,
"name": "John",
"posts": [...],
"settings": {...}
}
注意事项
- 一致性:保持命名和格式的统一
- 安全性:始终验证和清理输入
- 文档:使用Swagger/OpenAPI规范文档
- 测试:为每个路由编写单元测试
- 性能:添加缓存、限制和过滤
这样设计的路由清晰、可维护,符合RESTful最佳实践。