Django分步连续上传场景API端点设计咨询
Django 菜谱场景API设计优化方案
初始设计问题修正
你的基础设计逻辑是通顺的,有几个小问题可以提前调整:
- 创建菜谱的POST接口请求包含文本和文件,需要明确用
multipart/form-data格式,不能混合JSON和文件参数 - 全量替换配料、步骤列表的操作用
PUT语义更合适,PATCH更适合单个字段的局部更新 - 缺少基础的HTTP状态码定义,接口异常时前端无法快速判断错误类型
疑问解答
1. 配料、操作步骤顺序调整处理
最适合新手且性能足够的方案:
- 给Ingredient、Step模型加
order(你设计里的index)整数字段,查询时默认按该字段升序返回 - 调整顺序时前端直接传全量的配料/步骤列表,每个元素携带新的
order值,后端全量覆盖当前菜谱对应的子资源数据即可。菜谱场景下子资源数量通常不会超过50条,全量替换的性能完全够用,实现成本极低 - 如果后续有增量调整顺序的需求,可以单独加
PATCH /recipe/{id}/ingredients/order接口,传调整顺序的元素ID和新order值即可,初期不用做这么复杂
2. 媒体文件上传方案
优先选择先单独上传媒体文件到S3拿到URL,再调用业务接口提交数据的方案,优势非常明显:
- 接口解耦,业务接口只需要处理JSON请求,Django侧的序列化、校验逻辑会简单很多
- 上传失败只需要重传文件,不需要重试整个业务请求,安卓端实现上传进度条、断点续传也更方便
- 大视频上传不会导致业务接口超时,稳定性更高
- 如果是小于100KB的小图标,也可以选择同步上传,大于1MB的文件强烈建议分开处理
最终推荐API设计
1. 创建菜谱基础信息
POST /api/v1/recipes/
- 请求格式:
multipart/form-data
参数:name: string 菜谱名称cover_image: File 菜谱封面图
- 成功响应(201 Created):
{ "id": "123xyz", "name": "Pizza", "cover_image_url": "s3://xxx/pizza.png" }
2. 更新菜谱基础属性
PATCH /api/v1/recipes/{recipe_id}/
- 请求格式:
application/json
参数:
{ "serving": 2, "difficulty": "m", "prep_time": 80 }
- 成功响应(200 OK):
{ "id": "123xyz", "name": "Pizza", "cover_image_url": "s3://xxx/pizza.png", "serving": 2, "difficulty": "m", "prep_time": 80 }
3. 全量更新菜谱配料列表
PUT /api/v1/recipes/{recipe_id}/ingredients/
- 请求格式:
application/json
参数:
[ {"ingredient": "rice", "amount": "1/2", "unit": "g", "order": 1}, {"ingredient": "water", "amount": "1/2", "unit": "ml", "order": 2} ]
- 成功响应(200 OK):
{ "id": "123xyz", "ingredients": [ {"id": "i1", "ingredient": "rice", "amount": "1/2", "unit": "g", "order": 1}, {"id": "i2", "ingredient": "water", "amount": "1/2", "unit": "ml", "order": 2} ] }
4. 全量更新菜谱步骤列表
PUT /api/v1/recipes/{recipe_id}/steps/
- 请求格式:
application/json
参数:
[ {"description": "abc", "image_url": "s3//step1.png", "order": 1}, {"description": "xyz", "video_url": "s3//step2.mp4", "order": 2} ]
- 成功响应(200 OK):
{ "id": "123xyz", "steps": [ {"id": "s1", "description": "abc", "image_url": "s3//step1.png", "video_url": null, "order": 1}, {"id": "s2", "description": "xyz", "image_url": null, "video_url": "s3//step2.mp4", "order": 2} ] }
可选:单独媒体上传接口
POST /api/v1/media/upload/
- 请求格式:
multipart/form-data
参数:file: File 要上传的媒体文件 - 成功响应(201 Created):
{ "url": "s3://xxx/xxxx.png", "file_type": "image" }
Django 快速实现提示
- 模型层用
django-ordered-model第三方库,不用自己写排序逻辑,一行代码搞定子资源的顺序管理 - 接口层用Django REST Framework(DRF)开发,嵌套路由用
drf-nested-routers直接生成,分别写三个模型对应的序列化器即可 - S3存储对接用
django-storages库,不需要自己写S3上传逻辑
内容的提问来源于stack exchange,提问作者Chitrang
相关产品推荐
相关产品推荐

