고급 웹프로그래밍
FastAPI(models)
rabbit-jun
2025. 4. 2. 19:58
아래의 코드를 설명하기 앞서 전체적인 흐름을 알고가자.
- 클라이언트가
POST /tags
요청을 보낸다 - Tag에 id와 tag 그리고 datetime과 secret이 담긴 객체가 생성된다
- 이렇게 만든 Tag객체를 services.create_tag(tag)에 인자로 보낸다.
- services에서 정의한대로 tag_list에 클라이언트가 보낸 id와 tag가 딕셔너리 형태로 저장된다.
- 클라이언트가
GET/tags/{id}
요청을 보낸다 - 클라이언트가 보낸 id가 services.get_tag(id)의 인자로 넣어진다
- create_tag에 의해 만들어진 list에서 클라이언트가 만든 id와 GET 요청으로 보낸 id가 같으면 Tag 인스턴스 생성
- 이 인스턴스에서 TagOut을 반환한다 했으니 TagOut에 정의한 데이터들만 Tag에서 반환
models.py
from datetime import datetime
from pydantic import BaseModel
class Tag(BaseModel):
id: int
tag: str
created_at: datetime
secret: str
class TagIn(BaseModel):
id: int
tag: str
class TagOut(BaseModel):
id: int
tag: str
created_at: datetime
Tag
: 서버 내부에서 사용하는 전체 데이터 구조TagIn
: 클라이언트가 요청 시 제공해야 하는 데이터 구조TagOut
: 클라이언트가 값을 받을 때 datetime도 받을 수 있게 만든 구조- 'BaseModel`: 데이터를 다룰 수 있는 객체
- 자동 json 파싱
- 타입 검사(ex. ``tag: str`이면 str만 받는다)
- 문서화 (/docs)
- 데이터 검증 (값이 빠졌거나, 잘못된 형식이면 자동 오류 발생)
services.py
import datetime
from models import Tag
from fastapi import HTTPException
tag_list={}
def create_tag(tag: Tag) -> Tag:
tag_list[tag.id]= tag.tag
return tag
def get_tag(id: int) -> Tag:
for k,v in tag_list.items():
if k == id:
return Tag(id= k,
tag=v,
created_at= datetime.datetime.now(),
secret="secret"
)
raise HTTPException(status_code=404, detail="Tag not found")
create_tag
: 실제 저장 로직이 들어가는 자리get_tag
: 예시 데이터를 반환하는 함수
main.py
from models import Tag,TagIn
import services
import datetime
@app.post("/tags")
def create_tag(tag_in: TagIn) -> TagIn:
tag: Tag = Tag(
id=tag_in.id,
tag=tag_in.tag,
created_at=datetime.datetime.now(),
secret="a"
)
services.create_tag(tag)
return tag_in
@app.get("/tags/{id}")
def get_tag(id: int) -> TagOut:
tag: Tag = services.get_tag(id)
return tag # Tag 객체에서 TagOut이 요청하는 데이터를 자동으로 추출해서 반환(TagOut이 Tag의 서브셋이라 가능)
tag_in: TagIn
: 요청 본문을TagIn
모델로 파싱함 (id, tag만 있음)-> TagIn
: 응답으로TagIn
형식만 클라이언트에게 전달- 내부에서는
TagIn
+ 추가정보 ->Tag
객체 생성 services.create_tag(tag)
: 저장 또는 가공 로직 호출return tag_in
: 민감 정보(secret 등)를 숨기고 클라이언트에게 요청값 그대로 반환
데이터를 만들고 가져오는 예시
질문
1. TagOut이 Tag의 서브셋인지는 자동으로 판단하나요?
- FastAPI가 Tag와 같은 변수명을 쓰는 TagOut을 서브셋으로 인식
2. services.create_tag(tag) 에서 객체를 인자로 받았는데 이거 그냥 쓰면 안되나?
def create_tag(tag: Tag) -> Tag:
tag_list[tag.id] = tag
return tag
def get_tag(id: int) -> Tag:
tag = tag_list.get(id)
if not tag:
raise HTTPException(status_code=404, detail="Tag not found")
return tag
이렇게 하면 객체를 통으로 가져다 쓸 수 있다
반응형