๐ ์ฝ 1๋ถ ์ฝ๋ ๋ฐ ์์๋ฉ๋๋ค
์ด์ ๊ธ ๋ณด๊ธฐ(FastAPI ์ํ ๊ด๋ฆฌ์ ์์กด์ฑ ์ฃผ์ )
โ HTTPException๋ถํฐ ์ปค์คํ ์์ธ ํธ๋ค๋ฌ๊น์ง ํ ๋ฒ์ ์ตํ๋ณด์
โ์๋ฌ๋ ์จ๊ธฐ์ง ๋ง๊ณ ๋ช ํํ๊ฒ ๋ค๋ค์ผ ํ๋ค.โ
FastAPI๋ ์๋ฌ ์ฒ๋ฆฌ ๋ํ ๋ชจ๋ํ๊ณ ๊น๋ํ๊ฒ ์ ๊ณตํ๋ค. ๋จ์ํ ์๋ฒ์์ ํฐ์ง๋ ์ค๋ฅ๋ฅผ ๋ฐฉ์งํ๋ ๊ฒ๋ฟ ์๋๋ผ, ํด๋ผ์ด์ธํธ์๊ฒ ์ ์ฉํ ์๋ฌ ๋ฉ์์ง๋ฅผ ๋ฐํํ๊ณ , API์ ์ ๋ขฐ์ฑ์ ๋์ด๋ ๋ฐฉ์์ผ๋ก ์ ๊ทผํด์ผ ํ๋ค.
โ ์์ธ ์ฒ๋ฆฌ ๊ธฐ๋ณธ ๊ตฌ์กฐ
FastAPI๋ ๋ด๋ถ์ ์ผ๋ก Python์ ์์ธ ์์คํ
์ ๊ทธ๋๋ก ์ฌ์ฉํ๋ค. ์ฌ๊ธฐ์ ์น ํ์ค์ธ HTTP ์ํ ์ฝ๋๋ฅผ ์ ๋ชฉ์์ผ HTTPException
์ด๋ผ๋ ์์ธ ํด๋์ค๋ฅผ ์ ๊ณตํ๋ค.
1. ๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ ์์ธ ์ฒ๋ฆฌ ๋ฐฉ๋ฒ
from fastapi import FastAPI, HTTPException
app = FastAPI()
@app.get("/items/{item_id}")
def read_item(item_id: int):
if item_id > 100:
raise HTTPException(status_code=404, detail="Item not found")
return {"item_id": item_id}
HTTPException
์ FastAPI๊ฐ ์ ๊ณตํ๋ ์์ธ ํด๋์ค์ด๋ค.status_code
๋ ๋ฐํํ HTTP ์ํ ์ฝ๋์ด๋ค.detail
์ ํด๋ผ์ด์ธํธ์๊ฒ ์ ๊ณตํ ์๋ฌ ๋ฉ์์ง์ด๋ค.
์ด๋ ๊ฒ ์์ฑํ๋ฉด item_id
๊ฐ 100์ ์ด๊ณผํ ๊ฒฝ์ฐ ํด๋ผ์ด์ธํธ๋ 404 ์๋ฌ์ ํจ๊ป "Item not found"
๋ฉ์์ง๋ฅผ ๋ฐ๊ฒ ๋๋ค.
๐ฆ ๋ค์ํ HTTP ์ํ ์ฝ๋ ์ฌ์ฉํด๋ณด๊ธฐ
FastAPI์์๋ ํ์ค HTTP ์ํ ์ฝ๋๋ฅผ ๋ง์๋๋ก ์ฌ์ฉํ ์ ์๋ค. ์์ฃผ ์ฌ์ฉํ๋ ๋ช ๊ฐ์ง ์ํ ์ฝ๋๋ ์๋์ ๊ฐ๋ค.
์ํ ์ฝ๋ | ์๋ฏธ |
---|---|
400 | Bad Request โ ์๋ชป๋ ์์ฒญ์ด๋ค |
401 | Unauthorized โ ์ธ์ฆ์ด ํ์ํ๋ค |
403 | Forbidden โ ์ ๊ทผ์ด ๊ธ์ง๋์๋ค |
404 | Not Found โ ์์์ ์ฐพ์ ์ ์๋ค |
500 | Internal Server Error โ ์๋ฒ ๋ด๋ถ ์ค๋ฅ์ด๋ค |
์ฌ์ฉ ์๋ ๋ค์๊ณผ ๊ฐ๋ค.
if not authorized:
raise HTTPException(status_code=401, detail="๋ก๊ทธ์ธ์ด ํ์ํฉ๋๋ค.")
์ด๋ ๊ฒ ์ํฉ์ ๋ฐ๋ผ ์ ์ ํ ์ํ ์ฝ๋๋ฅผ ์ฌ์ฉํ๋ฉด ํด๋ผ์ด์ธํธ ์ ์ฅ์์๋ API์ ์๋๋ฅผ ๋ ์ ์ดํดํ ์ ์๋ค.
๐งฐ ์ถ๊ฐ ํ๋: headers, content
HTTPException
์ ๋จ์ํ ์ํ ์ฝ๋์ ๋ฉ์์ง๋ง ์ ๋ฌํ๋ ๊ฒ์ด ์๋๋ค. ํ์ํ๋ค๋ฉด ์๋ต ํค๋๋ ์์ธ ๋ด์ฉ์ ๋ ์ถ๊ฐํ ์ ์๋ค.
raise HTTPException(
status_code=403,
detail="Access denied",
headers={"X-Error": "Permission denied"}
)
- ์ ์์์ฒ๋ผ ํค๋์
X-Error
๋ฅผ ์ถ๊ฐํด ํด๋ผ์ด์ธํธ ์ธก์์ ๋ก๊น ์ด๋ ํธ๋ํน์ ์ฌ์ฉํ ์๋ ์๋ค. - ๋ณด์์ด๋ ์ฌ์ฉ์ฑ ์ธก๋ฉด์์ ์ ์ฉํ๊ฒ ํ์ฉํ ์ ์๋ค.
๐ ์ปค์คํ ์์ธ ํธ๋ค๋ฌ ์์ฑํ๊ธฐ
์ด๋ค ์์ธ๋ ์ง ์ฐ๋ฆฌ๊ฐ ์ง์ ์ฒ๋ฆฌ ๋ก์ง์ ์ ์ํ๊ณ ์ถ์ ๋๊ฐ ์๋ค. ์๋ฅผ ๋ค์ด ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ค๋ฅ๋ ์ฌ์ฉ์ ์ ์ ์๋ฌ๊ฐ ๋ฐ์ํ์ ๋, ๋ชจ๋ ์์ธ๋ฅผ ๊ณตํต๋ ํ์์ผ๋ก ์๋ตํ๊ณ ์ถ๋ค๋ฉด **์ปค์คํ ์์ธ ํธ๋ค๋ฌ(Custom Exception Handler)**๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
1. ์ฌ์ฉ์ ์ ์ ์์ธ ํด๋์ค ๋ง๋ค๊ธฐ
class MyCustomException(Exception):
def __init__(self, name: str):
self.name = name
- ์ผ๋ฐ์ ์ธ Python ์์ธ ํด๋์ค๋ฅผ ๋ง๋ ๋ค.
- ํ์์ ๋ฐ๋ผ ํ๋ผ๋ฏธํฐ๋ฅผ ๋๊ธฐ๊ฑฐ๋ ๋ฉ์์ง๋ฅผ ์ค์ ํ ์ ์๋ค.
2. ์์ธ ํธ๋ค๋ฌ ๋ฑ๋กํ๊ธฐ
FastAPI์์๋ @app.exception_handler()
๋ฐ์ฝ๋ ์ดํฐ๋ฅผ ํตํด ์์ธ๋ฅผ ํธ๋ค๋งํ ์ ์๋ค.
from fastapi.responses import JSONResponse
from fastapi.requests import Request
@app.exception_handler(MyCustomException)
async def my_exception_handler(request: Request, exc: MyCustomException):
return JSONResponse(
status_code=418,
content={"message": f"Oops! {exc.name}์ด๋ผ๋ ์๋ฌ๊ฐ ๋ฐ์ํ์ต๋๋ค."}
)
Request
๊ฐ์ฒด์ ๋ฐ์ํ ์์ธexc
๋ฅผ ์ธ์๋ก ๋ฐ๋๋ค.- JSON ํ์์ผ๋ก ์๋ต์ ์ง์ ๊ตฌ์ฑํ ์ ์๋ค.
- ์ด ๋ฐฉ์์ผ๋ก ๋ชจ๋ ์ฌ์ฉ์ ์ ์ ์์ธ๋ฅผ ๊ณตํต ํฌ๋งท์ผ๋ก ์ถ๋ ฅํ ์ ์๋ค.
๐ ์: ์ปค์คํ ์์ธ๋ฅผ ์ค์ API์ ์ ์ฉํด๋ณด์
@app.get("/error-test/{name}")
def error_test(name: str):
if name == "bad":
raise MyCustomException(name)
return {"name": name}
/error-test/bad
๋ก ์์ฒญํ๋ฉด ์ฐ๋ฆฌ๊ฐ ์ ์ํMyCustomException
์ด ๋ฐ์ํ๋ค.- ์ด ์์ธ๋ ์์ ๋ฑ๋กํ ํธ๋ค๋ฌ์์ ์๋์ผ๋ก ์ฒ๋ฆฌ๋๋ค.
- ํด๋ผ์ด์ธํธ๋ ์ํ ์ฝ๋ 418๊ณผ ํจ๊ป
"Oops! bad์ด๋ผ๋ ์๋ฌ๊ฐ ๋ฐ์ํ์ต๋๋ค."
๋ฉ์์ง๋ฅผ ๋ฐ๊ฒ ๋๋ค.
๐คน ์์ธ ์ฒ๋ฆฌ ํ๊ณผ ์ฃผ์์ฌํญ
- ๊ฐ๋ฅํ ๋ชจ๋ ์์ธ๋ฅผ ํธ๋ค๋งํ์.
- FastAPI๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์์ธ๋ฅผ JSON ํํ๋ก ๋ฐํํ์ง๋ง, ๋ช ํํ ๋ฉ์์ง๋ฅผ ์ง์ ์ ๋ฌํด์ฃผ๋ ๊ฒ์ด ํจ์ฌ ์ข๋ค.
- ๊ณตํต ์ค๋ฅ ํฌ๋งท์ ์ฌ์ฉํ์.
- API์์ ์ผ๊ด๋ ํํ์ ์๋ฌ ๋ฉ์์ง๋ฅผ ์ ๊ณตํ๋ฉด ํด๋ผ์ด์ธํธ ์ธก์์ ํ์ฑ๊ณผ ์ฒ๋ฆฌ๋ ์ฌ์์ง๋ค.
- ์์ธ ๋ฉ์์ง์ ๋ฏผ๊ฐํ ์ ๋ณด๋ ๋ด์ง ๋ง์.
- DB ์ฟผ๋ฆฌ ์ค๋ฅ๋ ์์คํ ๋ฉ์์ง๋ฅผ ๊ทธ๋๋ก ๋ ธ์ถํ๋ฉด ๋ณด์์ ์ํํ๋ค.
- ํ
์คํธ๋ฅผ ํตํด ๋ชจ๋ ๊ฒฝ๋ก์์ ์์ธ๊ฐ ์ ๋ฐ์ํ๋์ง ํ์ธํ์.
- ์์ธ ์ฒ๋ฆฌ๊ฐ ์๋ชป๋๋ฉด 500 ์ค๋ฅ๋ก ๋์ด๊ฐ ์ฌ์ฉ์๋ ์ด์ ๋ฅผ ์ ์ ์๋ค.
๐งพ ์ ๋ฆฌํด๋ณด์
FastAPI์ ์๋ฌ ์ฒ๋ฆฌ ๋ฐฉ์์ ๋จ์ํ ์์ธ ๋ฐ์์ ๋์ด, ์น ์๋น์ค ์ ๋ฐ์ ์ ๋ขฐ์ฑ๊ณผ ํ์ง์ ํฅ์์ํค๋ ๋๊ตฌ์ด๋ค. HTTPException
์ ์ฆ๊ฐ์ ์ธ ์ค๋ฅ ์๋ต์ ์ข๊ณ , ์ปค์คํ
์์ธ ํธ๋ค๋ฌ๋ ๋ณต์กํ ๋ก์ง์ ์ ์ฐํ๊ฒ ๋์ํ ์ ์๊ฒ ๋์์ค๋ค.
๊ธฐ๋ฅ | ์ฌ์ฉ๋ฒ | ๋ชฉ์ |
---|---|---|
HTTPException | raise HTTPException(status_code, detail) | ๋น ๋ฅธ HTTP ์ค๋ฅ ๋ฐํ |
์ปค์คํ ์์ธ ํด๋์ค | class MyException(Exception) | ์ฌ์ฉ์ ์ ์ ๋ก์ง ํํ |
์ปค์คํ ํธ๋ค๋ฌ | @app.exception_handler(MyException) | ์์ธ ๋ฉ์์ง ์ปค์คํฐ๋ง์ด์ง |
FastAPI์์๋ ์์ธ๊ฐ ๊ณง ์ฌ์ฉ์ ๊ฒฝํ์ด๋ค. ์ด๋ป๊ฒ ์๋ฌ๋ฅผ ์ ๋ฌํ ์ง์ ๋ฐ๋ผ ์๋น์ค์ ์ ๋ฌธ์ฑ์ด ๋๋ฌ๋๋ค.
๋ค์ ๋จ๊ณ๋ก ๋์ด๊ฐ๊ธฐ ์ ์, ์์ ์ด ๋ง๋ ๋ชจ๋ API ๋ผ์ฐํธ์ ์ฌ๋ฐ๋ฅธ ์์ธ ์ฒ๋ฆฌ๊ฐ ์๋์ง ๋ค์ ํ ๋ฒ ์ ๊ฒํด๋ณด์.
FastAPI ๊ณต์ ๋ฌธ์ : https://fastapi.tiangolo.com/ko/
