REST API 만들기
FastAPI로 완전한 RESTful API를 설계하고 구현하는 방법을 배워봅시다.
REST API란?
REST (Representational State Transfer)는 웹 서비스를 설계하기 위한 아키텍처 스타일입니다. RESTful API는 HTTP 프로토콜을 활용하여 리소스를 관리합니다.
REST의 핵심 원칙
- 클라이언트-서버 분리 - 독립적인 개발과 확장
- 무상태성 (Stateless) - 각 요청은 독립적
- 캐시 가능 - 응답은 캐시 가능 여부 명시
- 계층화 시스템 - 중간 서버 사용 가능
- 인터페이스 일관성 - 통일된 인터페이스
HTTP 메서드
| 메서드 | 용도 | 예시 |
|---|---|---|
| GET | 리소스 조회 | GET /users |
| POST | 리소스 생성 | POST /users |
| PUT | 리소스 전체 수정 | PUT /users/1 |
| PATCH | 리소스 부분 수정 | PATCH /users/1 |
| DELETE | 리소스 삭제 | DELETE /users/1 |
HTTP 상태 코드
적절한 상태 코드를 사용하는 것이 중요합니다.
from fastapi import FastAPI, status
from fastapi.responses import JSONResponse
app = FastAPI()
# 2xx: 성공
# 200 OK - 일반적인 성공
@app.get("/items/{item_id}", status_code=status.HTTP_200_OK)
def read_item(item_id: int):
return {"item_id": item_id}
# 201 Created - 리소스 생성 성공
@app.post("/items/", status_code=status.HTTP_201_CREATED)
def create_item(item: dict):
return item
# 204 No Content - 성공했지만 반환할 내용 없음
@app.delete("/items/{item_id}", status_code=status.HTTP_204_NO_CONTENT)
def delete_item(item_id: int):
return None
# 4xx: 클라이언트 오류
# 400 Bad Request
@app.post("/invalid/")
def invalid_request():
return JSONResponse(
status_code=status.HTTP_400_BAD_REQUEST,
content={"detail": "Invalid request"}
)
# 401 Unauthorized
@app.get("/protected/")
def protected_route():
return JSONResponse(
status_code=status.HTTP_401_UNAUTHORIZED,
content={"detail": "Authentication required"}
)
# 403 Forbidden
@app.get("/admin/")
def admin_only():
return JSONResponse(
status_code=status.HTTP_403_FORBIDDEN,
content={"detail": "Access denied"}
)
# 404 Not Found
@app.get("/items/{item_id}")
def get_item(item_id: int):
return JSONResponse(
status_code=status.HTTP_404_NOT_FOUND,
content={"detail": "Item not found"}
)
# 5xx: 서버 오류
# 500 Internal Server Error
@app.get("/error/")
def server_error():
return JSONResponse(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
content={"detail": "Internal server error"}
)
URL 설계 베스트 프랙티스
좋은 URL 설계
# ✅ 명사 사용, 복수형
GET /users # 모든 사용자 조회
GET /users/123 # 특정 사용자 조회
POST /users # 사용자 생성
PUT /users/123 # 사용자 전체 수정
PATCH /users/123 # 사용자 부분 수정
DELETE /users/123 # 사용자 삭제
# ✅ 계층 구조
GET /users/123/posts # 사용자의 게시글 목록
GET /users/123/posts/456 # 특정 게시글
POST /users/123/posts # 게시글 작성
DELETE /users/123/posts/456 # 게시글 삭제
# ✅ 필터링, 정렬, 페이징
GET /users?role=admin # 역할별 필터
GET /users?sort=created_at&order=desc # 정렬
GET /users?page=2&limit=10 # 페이징
# ✅ 검색
GET /users/search?q=john # 검색
# ❌ 피해야 할 패턴
GET /getUser/123 # 동사 사용 (X)
POST /createUser # 동사 사용 (X)
GET /user # 단수형 (X)
GET /users/delete/123 # 메서드를 URL에 포함 (X)