当前位置:   article > 正文

FastAPI Web框架教程 第5章 阶段总结练习

FastAPI Web框架教程 第5章 阶段总结练习

关于博客的增删改查练习

  • 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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/436546
推荐阅读
相关标签
  

闽ICP备14008679号