제3장 3.4: 우주선 CRUD 작업
학습 시간: 1시간
1. CRUD: 우주 임무 관리의 전체 주기
지금까지는 데이터만 읽었습니다(Read
). 그러나 진정한 비행 통제 센터는 모든 것을 할 수 있어야 합니다:
- Create (생성): 새로운 위성을 궤도에 진입시킵니다.
- Read (읽기): 기존 우주선의 상태를 요청합니다.
- Update (업데이트): 궤도를 수정하거나 소프트웨어를 업데이트합니다.
- Delete (삭제): 오래된 위성을 궤도에서 이탈시킵니다.
이 네 가지 작업인 CRUD는 대부분의 API의 기본을 이룹니다. 이 장에서는 우리 함대 관리를 위한 완전한 주기를 구현할 것입니다.
2. Create: 새로운 우주선 발사 (POST)
새로운 우주선을 생성하기 위해 POST
메서드를 사용할 것입니다. 새로운 우주선에 대한 데이터는 요청 본문에 JSON 형식으로 전달됩니다.
단계 1: 들어오는 데이터를 위한 새로운 Pydantic 모델 생성
새로운 모델이 왜 필요할까요? 우주선을 생성할 때 id
를 모르기 때문입니다. id
는 서버가 할당해야 합니다.
이 모델을 main.py
에 추가하세요:
# main.py
from pydantic import BaseModel, Field
class SpaceshipCreate(BaseModel):
"""새로운 우주선 생성을 위한 모델 (ID 없음)."""
name: str = Field(..., min_length=3, max_length=50)
type: str
launch_year: int = Field(..., gt=1950)
status: str
Spaceship
모델과 거의 동일하지만, 들어오는 데이터의 유효성 검사에 사용될 것입니다.
단계 2: POST /spaceships
엔드포인트 구현
# main.py
import random # 파일 상단에 이 임포트를 추가하세요
# ... 나머지 코드 ...
@app.post("/spaceships", response_model=Spaceship, status_code=201)
def create_spaceship(ship: SpaceshipCreate):
"""
레지스트리에 새로운 우주선을 추가합니다.
"""
# 우주선을 위한 새롭고 고유한 ID를 생성합니다.
new_id = max(db_spaceships.keys() or [0]) + 1
# 전체 Spaceship 모델에 해당하는 우주선 객체를 생성합니다.
new_ship = Spaceship(id=new_id, **ship.dict())
# 우리의 "데이터베이스"에 저장합니다.
db_spaceships[new_id] = new_ship.dict()
return new_ship
@app.post(...)
:POST
요청을 위한 데코레이터를 사용합니다.status_code=201
: 성공적으로 생성될 경우201 Created
상태를 반환하도록 지정합니다.ship: SpaceshipCreate
: 여기에 마법이 있습니다! FastAPI는 요청 본문(JSON)을 자동으로 가져와SpaceshipCreate
모델에 따라 유효성을 검사한 다음,ship
객체로 함수에 전달합니다.new_id = ...
: 새로운 ID를 생성하기 위한 간단한 로직입니다.**ship.dict()
: 수신된ship
모델의 데이터를 전체 모델로 "언팩"합니다.response_model=Spaceship
: 응답은id
를 포함하여 전체 모델에 따를 것입니다.
3. Update: 코스 수정 (PUT)
기존 리소스를 완전히 업데이트하려면 PUT
메서드가 사용됩니다.
PUT /spaceships/{ship_id}
엔드포인트 구현:
# main.py
from fastapi import FastAPI, HTTPException # 임포트를 업데이트하세요
# ... 나머지 코드 ...
@app.put("/spaceships/{ship_id}", response_model=Spaceship)
def update_spaceship(ship_id: int, ship_update: SpaceshipCreate):
"""
우주선 데이터를 완전히 업데이트합니다.
"""
if ship_id not in db_spaceships:
raise HTTPException(status_code=404, detail="우주선이 발견되지 않았습니다.")
updated_ship = Spaceship(id=ship_id, **ship_update.dict())
db_spaceships[ship_id] = updated_ship.dict()
return updated_ship
ship_update: SpaceshipCreate
: 들어오는 데이터의 유효성 검사를 위해 다시 이 모델을 사용합니다.HTTPException
: 해당id
를 가진 우주선이 발견되지 않으면, FastAPI의 표준 예외를 "던져" 아름다운404
코드의 JSON 응답으로 변환됩니다.
4. Delete: 궤도 이탈 (DELETE)
리소스를 삭제하려면 DELETE
메서드가 사용됩니다. 일반적으로 이러한 엔드포인트는 응답 본문을 반환하지 않습니다.
DELETE /spaceships/{ship_id}
엔드포인트 구현:
# main.py
from fastapi import FastAPI, HTTPException, Response, status # 임포트를 업데이트하세요
# ... 나머지 코드 ...
@app.delete("/spaceships/{ship_id}", status_code=status.HTTP_204_NO_CONTENT)
def delete_spaceship(ship_id: int):
"""
레지스트리에서 우주선을 삭제합니다.
"""
if ship_id not in db_spaceships:
raise HTTPException(status_code=404, detail="우주선이 발견되지 않았습니다.")
del db_spaceships[ship_id]
# 204 상태로 빈 응답을 반환합니다.
return Response(status_code=status.HTTP_204_NO_CONTENT)
status_code=status.HTTP_204_NO_CONTENT
: 명시적으로204 No Content
상태를 지정합니다.del db_spaceships[ship_id]
: 사전에서 항목을 삭제합니다.return Response(...)
: 삭제된 객체에 대한 데이터가 클라이언트에 필요 없으므로 빈 응답을 반환합니다.
5. /docs
에서 전체 주기 테스트
uvicorn
이 재시작되었을 것입니다.
http://127.0.0.1:8000/docs
를 엽니다. 이제 완전한 CRUD 작업 세트를 갖게 되었습니다!- POST:
POST /spaceships
엔드포인트를 확장하고 "Try it out"을 클릭한 다음, JSON 본문을 작성하고 (예: "제임스 웹 우주 망원경" 생성) "Execute"를 클릭합니다. 새로운 망원경 데이터와 함께201
응답을 받아야 합니다. - GET: 이제
GET /spaceships
를 실행합니다. 목록에 새로운 망원경이 나타나야 합니다. - PUT: 새로운 망원경의 ID를 사용하여
PUT /spaceships/{ship_id}
를 통해 데이터를 업데이트합니다. 예를 들어, 상태를 변경합니다. - DELETE: 동일한 ID를 사용하여
DELETE /spaceships/{ship_id}
를 통해 망원경을 삭제합니다.204
상태의 빈 응답을 받아야 합니다. - 확인: 망원경이 목록에서 삭제되었는지 확인하려면
GET /spaceships
를 다시 실행합니다.
복습 퀴즈
🚀 장 요약:
당신은 완전한 CRUD 주기를 구현하여 당신의 API를 단순한 "정보판"에서 완전한 함대 제어 센터로 탈바꿈시켰습니다!
- ✅ Create:
POST /spaceships
새로운 기체 출시용. - ✅ Read:
GET /spaceships
및GET /spaceships/{id}
데이터 획득용. - ✅ Update:
PUT /spaceships/{id}
임무 업데이트용. - ✅ Delete:
DELETE /spaceships/{id}
기체 폐기용.
당신의 함대는 완벽하게 통제됩니다! 다음 장에서는 FastAPI가 우리를 위해 상세한 "작동 지침서" — 대화형 Swagger 문서를 자동으로 생성하는 방법을 살펴보겠습니다.
📌 확인:
- 5개의 모든 엔드포인트(GET (2), POST, PUT, DELETE)가
/docs
에서 보이고 작동합니다.- 리소스를 성공적으로 생성, 읽기, 업데이트 및 삭제할 수 있습니다.
- 존재하지 않는 ID를 요청하면
404
오류가 반환됩니다.⚠️ 오류가 발생하면:
NameError
:HTTPException
,Response
,status
를 임포트했는지 확인하세요.KeyError
: 아마도 이미 삭제된 ID에 접근하려고 시도 중일 수 있습니다.PUT
또는POST
작업이 잘못된 경우: 함수 인수에 올바른 Pydantic 모델(SpaceshipCreate
)을 사용하고 있는지 확인하세요.