FastAPI 공식문서 따라하기[5] - Request Body
https://fastapi.tiangolo.com/ko/ 공식문서 따라하는 글
☑️ 1. Request Body
client
가server
쪽으로 보내는 데이터를 requestbody라고 한다.responsebody는
server
가client
쪽으로 보내는 데이터를 말한다.request body는
Pydantic
이 가지고 있는 혜택을 통해 더 유연하게 동작할 수 있다.
데이터를 보낼땐
GET
을 쓰지 않는것이 좋습니다.GET
을 조회용으로만 쓰는것이 HTTP 명세입니다.
☑️ 2. Import Pydantic’s BaseModel
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: Optional[str] = None
price: float
tax: Optional[float] = None
app = FastAPI()
@app.post("/items/")
async def create_item(item: Item):
return item
Item
라고 선언한 클래스는 BaseModel
에 의해 상속받고 있다.
None
이라고 초기값을 준 것은필수
로 받아야하는 값이 아니다. 그러나None
을 명시하지 않으면 그 값은필수
로 받아야한다.
즉 다음과 같은 데이터도 허용한다는 것이다.
1
2
3
4
{
"name" : "kms"
"price" : 45.2
}
description
속성과tax
속성에는 아무값도 주지 않아도 된다는 것이다.
☑️ 3. 결과
FastAPI
는 다음과 같이 프로세스를 진행한다.
request
에서JSON
으로 데이터를 읽는다,- 데이터의 형식에 맞게 타입을 변환한다.(필요시)
- 데이터를 검증한다
- 만약 데이터가 유효하지 않다면
clear error
를 리턴하며 정확히 어떤 데이터가 문제인지 명시해준다
- 만약 데이터가 유효하지 않다면
- 파라미터에 있는
item
을 받아 온다.만약
Item
의 매개변수들을 선언하였다면, 편집기에서 자동완성 기능을 사용할 수 있다.
- 프로그래머가 작성한 클래스 모델에 맞춰
JSON Schema
를 만들어 낸다. - 이
schemas
는 생성된OpenAPI schema
의 일부가 되고, Swagger와 같은 자동완성 문서에 사용된다.
☑️ 4. Model 활용법
정의한 클래스의 속성값에 맞게 접근 할 수 있다.
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
from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: Optional[str] = None
price: float
tax: Optional[float] = None
app = FastAPI()
@app.post("/items/")
async def create_item(item: Item):
#이부분
item_dict = item.dict()
if item.tax:
price_with_tax = item.price * item.tax
item_dict.update({"item price with tax : " : price_with_tax})
return item_dict
☑️ 5. Request Body + path parameter
request body
와 path parameter
를 같이 사용할 수 있다.
FastAPI
를 사용할때 path parameter
는 경로
에서 받아야하고 model
을 받을때는 request body
에서 받아야합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: Optional[str] = None
price: float
tax: Optional[float] = None
app = FastAPI()
@app.put("/items/{item_id}")
async def create_item(item_id: int, item: Item):
return {"item_id": item_id, **item.dict()}
결과
Swagger에서 테스트 진행.
1
2
3
4
5
6
7
8
9
10
11
#curl
curl -X 'PUT' \
'http://localhost:8000/items/5' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"name": "string",
"description": "string",
"price": 0,
"tax": 0
}'
1
2
3
4
5
6
7
{
"item_id": 5,
"name": "string",
"description": "string",
"price": 0,
"tax": 0
}
☑️ 6. Request Body + path parameter + query parameters
세 가지를 짬뽕하면 어떻게 해야할까
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: Optional[str] = None
price: float
tax: Optional[float] = None
app = FastAPI()
@app.put("/items/{item_id}")
async def create_item(item_id: int, item: Item, q: Optional[str] = None) :
result = {"item_id" : item_id,**item.dict()}
if q:
result.update({"q" : q})
return result
FastAPI
는 놀랍게도 이 모든것을 정확하게 인지하고 데이터를 넣어준다.
어떻게 하는걸까?
- 만약 경로에 파라미터가 선언되어있다면 이는
path parameter
로 인지한다. - 만약
sigular type
(int
,float
등..)타입이면query parameter
로 인지한다. - 만약
Pydantic model
타입으로 파라미터가 선언되어 있으면 이는request body
로 인지한다.
Pydantic model
을 사용하지 않는다면 Body Parametes
에 넣는 방법도 있다.
https://fastapi.tiangolo.com/ko/tutorial/body-multiple-params/#singular-values-in-body