Fast API 사용을 위한 서버 구축을 완료 했다면, 이제 서비스 구현을 해 나가야 겠죠?
가장 필요한것은 API들을 만들어 나가는 것인데요.
Web에서 현재 거의 표준이다시피 한 것이 REST API 일 것입니다.
REST API 를 Restfull 하게 설계 하기 위해서는 몇가지 알아 두어야 할 사항이 있습니다.
REST API 설계 레시피
1. CRUD - POST/GET/PUT/DELETE 에 맞춰서 설계한다.
2. RESOURE 정의 데이타 중심으로 한다.
- api에 동사 사용하지 않는다 : http://server.com/get-items => GET http://server.com/items
- 소문자만 사용한다 : GET http://server.com/Items => GET http://server.com/items
- 단어와 단어 사이에는 "_"(underscore, 밑줄) 대신 "-"(dash, 중간선)을 사용한다.
GET http://server.com/shoping_items => GET http://server.com/shoping-items
먼저 HTTP 의 request 종류와 용도를 알아두면 좋습니다.
HTTP request 와 CRUD
아마 REST API를 검색하면 많은 빈도수로 CRUD가 나올 것입니다.
REST API | example (resource = item) http://myserver.com/api/item |
|
C Create |
POST item 생성 |
POST http://myserver.com/api/item/12223 { name:"hello", value:"1234" } |
R Read |
GET item 읽기 |
GET http://myserver.com/api/item/12223 |
U Update |
PUT/ PATCH item 업데이트 |
PUT http://myserver.com/api/item/12223 { name:"hello", value:"1234" } PATCH http://myserver.com/api/item/12223 { value:"1234" } |
D Delete |
DELETE item 삭제 |
DELETE http://myserver.com/api/item/12223 |
원래 DB 쪽에서 시작된 용어이긴 하지만 일반적인 API 설계시에도 잘 들어 맞습니다.
그래서 REST API 설계시에도 매우 유용한 개념이기 때문에 REST API 설계시 사용하기 시작했습니다.
Fast API로 REST API 설계하기
Fast API로 rest api의 형태를 잡기 위해서는 가장 먼저 알아놔야 할것이 rest api 파라미터(parameter)의 형태를 어떻게 가져갈 것인가 입니다.
경로 파라미터
url 기본 패스(path)로 정의 하는 형태입니다.
아래와 같이 items 가 api의 resource에 해당하는 파트입니다. 즉, items 에 접근하기 위한 api를 의미합니다. 따로 get-items 와 같이 동사를 붙이지 않죠. GET이라는 행위는 http request의 형식에 GET으로 정의 합니다.
Fast API로는 아래와 같이 구현 합니다.
from fastapi import FastAPI
app = FastAPI()
@app.get("/items")
async def get_item_counts():
return {"count": 10}
Fast API로 api를 정의한 부분을 보니 , 간단하고 보기 편하죠?
그다음 좀더 확장해서 경로 파라메터에 변수를 포함해서 활용하는 방법입니다.
패스에 변수를 포함시키는 형태는 이와 같습니다.
GET http://myserver.com/items/{item_id}
ex) GET http://myserver.com/items/10
items/10 은 여기서 10번 item 정보를 가져온다고 가정 하죠.
이를 fast API에서는 아래와 같이 표현합니다.
from fastapi import FastAPI
app = FastAPI()
@app.get("/items/{item_id}")
async def read_item(item_id):
return {"item_id": item_id}
read_item() 이라는 함수에 item_id를 넣고, item_id를 입력받은 변수로 사용하면 됩니다.
실제 구현에서는 item_id에 해당 하는 item을 꺼내서 return 해주면 되겠죠?
아래의 user_id 처럼 주소 중간에도 추가가 가능합니다.
@app.get("/users/{user_id}items/{item_id}")
async def read_user_item(user_id, item_id):
return {
"user_id": user_id,
"item_id": item_id
}
형태를 봤을때 경로 파라메터는 아주 단순하죠? 좀더 복잡하고 다양한 형태의 입력을 받아야 하는 경우들이 인터넷 세상에는 많습니다.
복잡하고 많은 정보를 입력으로 받아야 하는 경우, 2가지 형태로 구현할 수 있습니다.
첫번째는 쿼리(URL query) 형태입니다.
쿼리(Query)
쿼리 형태는 사실 표현 형식에서 경로 형태에 파라메터가 추가되는 형태로 흔히 브라우져에서 주소 입력창에서 자주 보던 형태 일건데요.
아래와 같은 형식입니다.
POST http://myserver.com/items ?user_id="goodboy" & item_id="123"
이렇게 ? 뒤에 key-value 형태로 파라메터를 추가해서 전달하는 방식입니다.
python 함수 내에 parameter로 정의 하는 것 만으로도 쿼리 구현이 됩니다. (fast api에 잘 구현되어있어서 편하게 쓸수 있네요.)
@app.post("/items")
async def add_item(user_id:str, item_id:str):
return {
"result":"success",
"item_id":"D1234-889X-XX",
"price":"5000000",
}
데이타의 형태가 복잡해지거나 로직이 복잡해질 수록 query 처리하기 힘들어 지는 경우들이 발생합니다.
그중 한가지 예로 클래스로 데이타를 묶고 클래스로 데이타를 전달받고 처리하면 편리해질 것입니다.
이때 클래스의 구조가 바뀌면 parameter 형태도 바뀌게 되서 찾아서 수정해야 할 부분도 많아지겠죠.
이런 불편을 덜 수 있는 형태가 Requst body 입니다.
Request Body
Requst body를 이용하면 클래스와 같은 데이타 묶음을 처리하기 쉽습니다.
코드 를 작성할때 아래와 같이 어떤 정보를 json 으로 다뤄야 할 경우, 다음과 같이 합니다.
fast api에서 이렇게 class 를 json object로 잘 다룰 수 있도록 Pydantic BaseModel 이 구현되어 있습니다.
Pydantic BaseModel
먼저 Pydantic모듈의 BaseModel을 import하여 Class를 구성한다.
from typing import Union, List, Optional
from fastapi import FastAPI, Query
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: Union[str, None] = None
price: float
tax: Union[float, None] = None
@app.post("/items/{item_id}")
async def add_tree(item:Item):
pick = itemTable[item]
return {
"result":"success",
"item_name":pick.name,
"price":pick.price,
}
이렇게 Item이 모듈화 됨으로 해서 구현이나 관리가 훨씬 편리해지고 유연해 질 수 있습니다.
이정도를 기초로 익혀두면 자신의 서비스를 확장해 나가는데 도움이 될것 같습니다.
더 심오한 내용이나 복잡한 것들은 추가로 Fast API 사이트를 레퍼런스 삼아서 공부 해야 겠죠 ^^
1. NginX 와 Fast API 셋업은 여기를...
해피 코딩 ^^!!
참고자료.
https://juna-dev.tistory.com/7
Fast API 튜토리얼
https://fastapi.tiangolo.com/ko/tutorial/
'NginX+FastAPI' 카테고리의 다른 글
[NginX+Fast API] 1. Nginx + gunicorn + fast api 설정하기 (0) | 2022.11.10 |
---|