베트남에서 백엔드 개발 인턴을 하고 있다. 나의 업무는 python FastAPI를 만드는 것.
오늘 사수님께서 코드리뷰를 해주셨고, 관련한 레슨런을 적어보려고 한다.
FastAPI 애플리케이션이 클라이언트 요청을 처리하는 단계를 우선 설명해주셨다. 클라이언트의 요청이 들어오면 여러 단계를 거쳐 최종적으로 엔드포인트 함수에 도달하며, 이를 "요청 처리 파이프라인"이라고 한다.
미들웨어는 요청이 들어오거나 응답이 반환될 때 가장 먼저 또는 가장 마지막에 실행된다.
역할:
예제 코드:
@app.middleware("http")
async def log_request_time(request: Request, call_next):
print(f"Incoming request: {request.url}")
response = await call_next(request) # 다음 단계로 넘김
print(f"Completed request: {request.url}")
return response
나는 OS를 배울 때 이 미들웨어를 들어봐서 이게 어플리케이션을 만들 때에도 코드 상으로 구현을 하는 것이 처음이었다.
이 docs에 의하면, FastAPI 앱에도 미들웨어를 직접 추가할 수 있다고 한다.
특정 업무를 수행하기 전 모든 request, 그리고 response를 주기 전에 수행되는 function이라고 한다.
그런데 내가 기존에 개발한 파일 업로드 기능에 관해서는 일단 그대로 하고, 나중에 도입을 하는 것을 추천하셨다. 아마 유저 관리 관련해서는 해봐야겠다.
/api/upload-docs/
에 대한 POST
요청은 upload_docs
함수로 전달된다.@app.post("/api/upload-docs/")
async def upload_docs(file: UploadFile):
...
Request
, Depends
, File
등은 FastAPI가 필요한 객체를 주입한다.from fastapi import Depends, Request
async def validate_user(request: Request):
# 요청 헤더에 토큰이 있는지 검증
token = request.headers.get("Authorization")
if not token:
raise HTTPException(status_code=401, detail="Unauthorized")
return token
@app.post("/api/upload-docs/")
async def upload_docs(file: UploadFile, token=Depends(validate_user)):
...
위 코드에서 Depends(validate_user)
는 upload_docs
함수가 호출될 때 사용자 검증 함수를 먼저 실행한다.
FastAPI는 pydantic
을 사용해 요청 본문을 자동으로 밸리데이션한다.
예제 (Pydantic 모델 사용):
from pydantic import BaseModel
class FileUploadRequest(BaseModel):
filename: str
@app.post("/api/validate-upload/")
async def validate_upload(file_data: FileUploadRequest):
return {"message": f"Received file: {file_data.filename}"}
{"filename": "sample.docx"}
형태여야 한다.filename
필드가 없으면 400 응답이 반환된다.@app.post("/api/upload-docs/")
async def upload_docs(file: UploadFile = File(...)):
file_path = save_file(file.filename, file.file) # 서비스 레이어 호출
return {"message": "File uploaded", "file_path": file_path}
예를 들어:
{
"detail": "File not found"
}
Depends()
로 필요한 검증 또는 공통 작업 수행.pydantic
모델).사수님께서 강조하신 내용은 미들웨어 → 서비스 레이어 → 컨트롤러 함수 흐름으로 코드의 유지보수성과 확장성을 높이는 구조를 고려하라는 의미다. 파일 업로드 API처럼 간단한 경우에는 이런 단계를 모두 적용하지 않아도 괜찮지만, 복잡한 기능을 추가할 때는 이러한 구조를 통해 코드 가독성과 재사용성을 높일 수 있다.