Flask RESTful API 开发:Flask-RESTful、请求解析与响应封装
RESTful API 是现代 Web 服务的标准接口风格,基于 HTTP 协议,使用 GET/POST/PUT/DELETE 等方法操作资源。Flask-RESTful 是 Flask 官方推荐的 REST API 扩展,提供了 Resource 基类、请求解析(reqparse)、响应格式化(marshal)等开箱即用的功能。
一、Flask-RESTful 核心用法
flask_restful.Resource 是 API 视图的基类,通过 Api.add_resource() 将资源类绑定到 URL 路径。
from flask import Flask, request
from flask_restful import Api, Resource, fields, marshal_with, reqparse, abort
from datetime import datetime
app = Flask(__name__)
api = Api(app)
articles_db = {
1: {'id': 1, 'title': 'Flask 入门', 'content': 'Flask 是一个轻量级 Web 框架...', 'author': '张三', 'created_at': '2026-01-15'},
2: {'id': 2, 'title': 'RESTful API 设计', 'content': 'RESTful 是互联网软件架构的约束...', 'author': '李四', 'created_at': '2026-01-20'},
}
next_id = 3
article_fields = {
'id': fields.Integer,
'title': fields.String,
'author': fields.String,
'created_at': fields.String,
'url': fields.Url('article', absolute=True),
}
parser = reqparse.RequestParser(bundle_errors=True)
parser.add_argument('title', type=str, required=True, location='json', help='标题不能为空')
parser.add_argument('content', type=str, required=True, location='json', help='内容不能为空')
parser.add_argument('author', type=str, location='json', default='匿名')
get_parser = reqparse.RequestParser()
get_parser.add_argument('page', type=int, default=1, location='args')
get_parser.add_argument('per_page', type=int, default=10, location='args')
class ArticleListResource(Resource):
@marshal_with(article_fields)
def get(self):
args = get_parser.parse_args()
all_articles = list(articles_db.values())
start = (args['page'] - 1) * args['per_page']
return all_articles[start:start + args['per_page']]
def post(self):
global next_id
args = parser.parse_args()
article = {
'id': next_id,
'title': args['title'],
'content': args['content'],
'author': args['author'],
'created_at': datetime.now().strftime('%Y-%m-%d'),
}
articles_db[next_id] = article
next_id += 1
return article, 201
class ArticleResource(Resource):
def get(self, article_id):
article = articles_db.get(article_id)
if not article:
abort(404, message=f'文章 {article_id} 不存在')
return article
def put(self, article_id):
if article_id not in articles_db:
abort(404, message=f'文章 {article_id} 不存在')
args = parser.parse_args()
articles_db[article_id].update(args)
return articles_db[article_id]
def delete(self, article_id):
if article_id not in articles_db:
abort(404, message=f'文章 {article_id} 不存在')
del articles_db[article_id]
return '', 204
api.add_resource(ArticleListResource, '/api/articles/', endpoint='articles')
api.add_resource(ArticleResource, '/api/articles//', endpoint='article')
if __name__ == '__main__':
app.run(debug=True, port=5000)
二、API 路由设计规范
GET /api/articles/ # 获取文章列表(可分页)
POST /api/articles/ # 创建文章
GET /api/articles/1/ # 获取 ID=1 的文章
PUT /api/articles/1/ # 更新 ID=1 的文章
DELETE /api/articles/1/ # 删除 ID=1 的文章
三、常见问题
Q1:reqparse 校验失败后返回什么?
默认返回 HTTP 400,响应体包含所有校验错误信息。bundle_errors=True 会收集所有字段的错误一起返回;bundle_errors=False(默认)只返回第一个错误。
Q2:如何统一封装 API 响应格式?
通过 @api.representation('application/json') 装饰器拦截所有 JSON 输出,统一包装为 {code, data, message} 格式。
Q3:跨域请求(CORS)怎么处理?
安装 flask-cors 扩展,from flask_cors import CORS; CORS(app) 即可为所有路由添加 CORS 响应头。
四、延伸阅读
- Flask-RESTful 官方文档:https://flask-restful.readthedocs.io/
- HTTP 状态码规范:RFC 7231 定义了标准语义
- API 认证方案:JWT(JSON Web Token)、OAuth 2.0
- API 文档工具:Flask-RESTX(Swagger/OpenAPI 自动生成)