From 0e47fbc7f3e48fcf32eda74a2d3662cf81f5788d Mon Sep 17 00:00:00 2001 From: CaptainNEO Date: Thu, 10 Mar 2022 21:14:17 +0800 Subject: [PATCH] add more descriptions --- README.md | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 102 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 480b0af..e2c7aa0 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,6 @@ OpenAPI Specification(下文简称OAS)定义了一个标准的、语言无 以及下文中所涉及项目的完整代码均保存在本仓库中。 - ### 1. Goa #### 1. 开发过程 @@ -500,6 +499,55 @@ class StudentView(viewsets.ModelViewSet): 查看[main.py](./python/fastapi_example/main.py) +```python +from typing import Optional + +from fastapi import FastAPI +from pydantic import BaseModel, Field + +app = FastAPI() + + +class Item(BaseModel): + id: Optional[int] = None + name: str = Field(description="The name of the item", regex="^[a-zA-Z0-9]*$") + price: float + is_offer: Optional[bool] = None + + +db = { + 1: Item(id=1, name="Foo", price=19.99), + 2: Item(id=2, name="Bar", price=29.99), + 3: Item(id=3, name="Baz", price=39.99), +} + + +@app.get("/") +def get_items( + limit: int = 10, # 一个可选的int类型的参数,名字是limit,且默认值为10,通过query string传递 + offset: int = Field(..., description="db offset"), # 一个必选的int类型的参数,名字是offset,通过query string传递 + q: Optional[str] = None, # 一个可选的str类型的参数,名字是q,通过query string传递 +): + return [ + {"item": db[k], "price": db[k].price} + for k in sorted(db.keys())[offset : offset + limit] + ] + + +@app.get("/items/{item_id}") +def read_item(item_id: int): + return db[item_id] + + +@app.post("/items") +def create_item(item: Item) -> Item: + pid = list(db.keys())[-1] + 1 + item.id = pid + db[pid] = item + return item + +``` + ##### 2. 使用uvicorn启动服务 ```bash @@ -528,7 +576,59 @@ uvicorn main:app #### 1. 开发过程 这里采用官方用例提供的一个模拟用户CURD的例子 -查看代码[main.rs](./rust/poem/src/main.rs) +完整代码查看[main.rs](./rust/poem/src/main.rs) + +```rust + +#[derive(Tags)] +enum ApiTags { + /// Operations about user + User, +} + +#[OpenApi] +impl Api { + /// Update user by id <<<<<这里的注释是三条斜线,不是普通的注释,程序编译的时候可以拿到这个信息 + #[oai(path = "/users/:user_id", method = "put", tag = "ApiTags::User")] + async fn put_user(&self, user_id: Path, update: Json) -> UpdateUserResponse { + let mut users = self.users.lock().await; + match users.get_mut(user_id.0 as usize) { + Some(user) => { + if let Some(name) = update.0.name { + user.name = name; + } + if let Some(password) = update.0.password { + user.password = password; + } + UpdateUserResponse::Ok + } + None => UpdateUserResponse::NotFound, + } + } +} + + +/// Update user schema +#[derive(Debug, Object, Clone, Eq, PartialEq)] +struct UpdateUser { + /// Name + #[oai(validator(max_length = 20))] + name: Option, + /// Password + password: Option, +} + + +#[derive(ApiResponse)] +enum UpdateUserResponse { + /// Returns when the user is successfully updated. + #[oai(status = 200)] + Ok, + /// Return when the specified user is not found. + #[oai(status = 404)] + NotFound, +} +``` #### 2. OAS的实现方式 @@ -536,13 +636,11 @@ uvicorn main:app 2. 函数的入参和返回用于判断接口的Request和Response,这里有点类似FastAPI,只不过python用的类型注解来判断参数类型,rust使用的是泛型。 3. 编译的时候,这些宏在全部展开,配合[Doc Comment](https://doc.rust-lang.org/rust-by-example/meta/doc.html)可以得到OpenAPI所需的全部信息。 - #### 3. 优点 1. Rust语言提供零成本抽象能力、零GC、保证内存安全等特性使其性能非常优异。而且语言为用户提供了非常丰富的抽象能力、和特性。 2. 框架本身提供的宏非常简洁。Go1.18宏正式启用后,可以调研是否可以借鉴思想。 - #### 4. 缺点 1. Rust的学习成本比起Go语言要高,市场上相关人才比较少。