赞
踩
5个请求方式的使用规范
Restful风格api设计
RESTful是Web API接口的设计规范风格,这种风格的理念认为后端开发任务就是提供数据的,对外提供的是数据资源的访问接口,尤其适用于前后端分离的应用模式中。所以在定义接口时,客户端访问的URL路径就表示这种要操作的数据资源。
任何一个框架都可以实现符合restful规范的API接口。
RESTful十条规范:
1 数据的安全保障:url链接一般都采用https协议进行传输
2 接口特征表现,一看就知道是个api接口
- 用api关键字标识接口url:https://www.baidu.com/api
3 多数据版本共存,在url链接中标识数据版本
- https://api.baidu.com/v1
- https://api.baidu.com/v2
!!!4 数据即是资源,均使用名词(可复数)
- 接口一般都是完成前后台数据的交互,交互的数据我们称之为资源
- https://api.baidu.com/users
注:一般提倡用资源的复数形式,在url链接中奖励不要出现操作资源的动词- 特殊的接口可以出现动词,因为这些接口一般没有一个明确的资源,或是动词就是接口的核心含义
- https://api.baidu.com/place/search
- https://api.baidu.com/login
!!!5 资源操作由请求方式决定(method)
- 操作资源一般都会涉及到增删改查,使用请求方式确定操作类型
- https://api.baidu.com/books - get请求:获取所有书
- https://api.baidu.com/books/1 - get请求:获取主键为1的书
- https://api.baidu.com/books - post请求:新增一本书书
- https://api.baidu.com/books/1 - put请求:整体修改主键为1的书
- https://api.baidu.com/books/1 - patch请求:局部修改主键为1的书
- https://api.baidu.com/books/1 - delete请求:删除主键为1的书
6 过滤,通过在url上传参的形式传递搜索条件,或者说查询参数(query_params)
- https://api.example.com/v1/zoos?limit=10:指定返回记录的数量
- https://api.example.com/v1/zoos?offset=10:指定返回记录的开始位置
- https://api.example.com/v1/zoos?page=2&per_page=100:指定第几页,以及每页的记录数
- https://api.example.com/v1/zoos?sortby=name&order=asc:指定返回结果按照哪个属性排序,以及排序顺序
- https://api.example.com/v1/zoos?animal_type_id=1:指定筛选条件
7 响应状态码
8 错误处理
9 返回结果,针对不同操作,服务器向用户返回的结果应该符合以下规范
GET /collection:返回资源对象的列表(数组)
GET /collection/resource:返回单个资源对象
POST /collection:返回新生成的资源对象
PUT /collection/resource:返回完整的资源对象
PATCH /collection/resource:返回完整的资源对象
DELETE /collection/resource:返回一个空文档
10 需要url请求的资源需要访问资源的请求链接
- Hypermedia API,RESTful API最好做到Hypermedia,
- 即返回结果中提供链接,连向其他API方法,使得用户不查文档,也知道下一步应该做什么
{ "status": 0, "msg": "ok", "results":[ { "name":"肯德基(罗餐厅)", "img": "https://image.baidu.com/kfc/001.png" } ] }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
源码示例:模拟RESTFul风格的api
import typing from fastapi import FastAPI, HTTPException, status from fastapi.encoders import jsonable_encoder from pydantic import BaseModel app = FastAPI(title="Blog CRUD") # mock db blogs = { 1: { "id": 1, "title": "blog1", "body": "this is blog1", "desc": "desc" }, 2: { "id": 2, "title": "blog2", "body": "this is blog2", "desc": "desc" } } # blogs = [ # { # "id": 1, # "title": "blog1", # "body": "this is blog1", # "desc": "desc" # }, # { # "id": 2, # "title": "blog2", # "body": "this is blog2", # "desc": "desc" # } # ] class Blog(BaseModel): title: typing.Optional[str] = None body: typing.Optional[str] = None desc: str @app.get("/blogs", tags=["Blog"]) def get_blogs(page: int = 1, size: int = 10): blogs_list = list(blogs.values()) return blogs_list[(page - 1) * size:page * size] @app.get("/blog", tags=["Blog"]) def get_blog_by_id(blog_id: int): blog = blogs.get(blog_id) if not blog: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail=f"Not found the blog with id: {blog_id}" ) return blog @app.post("/blog", tags=["Blog"]) def create_blog(blog: Blog): blog_id = len(blogs) + 1 blogs[blog_id] = {"id": blog_id, **jsonable_encoder(blog)} return blogs[blog_id] @app.put("/blog", tags=["Blog"]) def update_blog(blog_id: int, blog: Blog): to_update_blog = blogs.get(blog_id) if not to_update_blog: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail=f"Not found the blog with id: {blog_id}" ) to_update_blog.update(jsonable_encoder(blog)) blogs[blog_id] = to_update_blog return to_update_blog @app.patch("/blog", tags=["Blog"]) def update_blog2(blog_id: int, blog: Blog): to_update_blog = blogs.get(blog_id) if not to_update_blog: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail=f"Not found the blog with id: {blog_id}" ) to_update_blog.update(**jsonable_encoder(blog, exclude_unset=True)) blogs[blog_id] = to_update_blog return to_update_blog @app.delete("/blog", tags=["Blog"]) def delete_blog(blog_id: int): if not blogs.get(blog_id): raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail=f"Not found the blog with id: {blog_id}" ) return blogs.pop(blog_id, None)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。