FastAPI는 python으로 만든 웹 프레임워크로 주로 REST API 서버를 쉽고 빠르게 만들기 위해 사용된다.
✅ REST API(REpresentational State Transfer API) 는 HTTP를 통해 자원에 접근하고 조작할 수 있도록 만든 규칙 기반의 API다.
| 개념 | 설명 |
| Resource (자원) | 서버에 존재하는 데이터 (예: 사용자, 뉴스, 상품 등) |
| URI | 자원의 위치를 나타냄 (/users, /news/1 등) |
| HTTP 메서드 | 자원에 대한 행동 정의 (GET, POST, PUT, DELETE) |
| Representation | 자원의 표현 방식. 주로 JSON 형식 사용 |
HTTP 각 메서드의 역할은 다음과 같다.
- GET : 자원 조회 (ex 뉴스 목록 가져오기)
- POST : 자원 생성 (ex 새 사용자 등록)
- PUT : 자원 전체 수정
- PATCH : 자원 부분 수정
- DELETE : 자원 삭제
간단하고 직관적이라서 프론트엔드와 통신이 용이하고 언어에 상관없이 HTTP만 알면 쓸 수 있고 클라이언트/서버 분리 구조라 유지보수가 편하다는 장점이 있다.
✅ REST API 중 REST의 원칙을 엄격하게 지켜서 만든 API를 RESTful API라 한다. 실무에서는 통용되는 말이지만 실제로는 차이가 있다는 점을 알아두면 좋을 것 같다.
REST의 6가지 원칙은 다음과 같다.
- Client-Server 구조
- Stateless (무상태성)
- Cacheable (캐싱 가능)
- Uniform Interface (일관된 인터페이스)
- Layered System (계층 구조)
- Code on Demand (선택적)
REST의 원칙을 지키지 않은 예시도 한 번 확인해보자
| REST 원칙 | 의미 | 지키지 않은 예시 | 잘못된 이유 |
| 1. Client-Server 구조 | 클라이언트와 서버는 역할이 분리되어야 함 | 클라이언트가 DB에 직접 SQL 날림 → SELECT * FROM users | 서버 역할을 클라이언트가 대신함 (역할 분리 실패) |
| 2. Stateless (무상태) | 요청 간에 상태를 저장하지 않음 | GET /users/1 ← 이전 요청 결과를 서버가 기억해서 다르게 응답 | 서버가 세션을 기억하면 REST 위반 (모든 요청은 독립적이어야 함) |
| 3. Cacheable (캐싱 가능) | 응답은 캐시가 가능해야 함 | GET /news/1인데 항상 Cache-Control: no-store 헤더 포함 | 읽기 전용 응답에 캐시를 허용하지 않으면 네트워크 낭비 |
| 4. Uniform Interface (일관된 인터페이스) | URI는 자원을 표현하고, HTTP 메서드는 동작을 표현해야 함 | POST /deleteUser?id=3 또는 GET /doSomethingNow | URI에 동사(delete, do)가 있음. 자원이 아니라 행동을 표현 |
| 5. Layered System (계층 구조) | 클라이언트는 중간 서버(프록시, 게이트웨이)를 인지하지 않아야 함 | 클라이언트가 중간 API 게이트웨이 주소를 직접 처리 → /proxy/api/users | 프록시나 게이트웨이가 API 설계에 노출됨 (구현이 드러남) |
| 6. Code on Demand (선택 사항) | 클라이언트가 서버로부터 스크립트를 받아 실행할 수 있음 | 서버에서 코드 전송 기능 없음 | 원칙이긴 하지만 선택사항이라 반드시 지킬 필요는 없음 |
이러한 RESTful API는 구조가 직관적이고 익히기 쉽지만 데이터 과다/과소 전달 문제가 존재하고 복잡한 요청은 여러 번 API를 호출해야한다는 단점이 있다.
✅ GraphQL은 이러한 단점을 해결할 수 있는 정확히 원하는 데이터를 명시해서 요청하는 쿼리 언어 기반 API이다.
여러개의 URL 즉, 엔드포인트를 직접 지정할 수 있는 REST API와 달리 하나의 엔드포인트 (/graphql)만 존재하고 데이터 구조를 클라이언트가 직접 요청한다.
query {
user(id: 1) {
name
email
posts {
title
}
}
}
위의 예시는 유저의 이름, 이메일, 작성한 글 제목만 가져오게 데이터 구조를 직접 설정한 것으로 필요한 데이터만 요청 가능하므로 과소/과잉 전달이 없고 하나의 요청으로 중첩된 여러 데이터가 조회 가능하다. 하지만 학습 난이도가 높고 캐싱이나 보안 이슈에 신경을 써야하며 단순한 API에서는 과한 구조일 수 있다.
| 상황 | 추천 방식 |
| 단순 CRUD 시스템 | RESTful |
| 복잡한 관계형 데이터, 모바일 최적화 필요 | GraphQL |
| 데이터 구조가 자주 바뀌는 경우 | GraphQL |
| 백엔드 자원이 제한된 경우 | RESTful (간단함) |
다시 FastAPI로 돌아와서 FastAPI는 내부적으로 3가지 핵심 라이브러리 위에 만들어져 있다.
- Starlette : 웹 서버 엔진으로 비동기 처리, 라우팅, 미들웨어 등을 제공한다.
- Pydantic : 데이터 검증 및 직렬화 (요청 데이터 타입 자동 검사)
- Uvicorn : ASGI 서버 (비동기 웹서버)
코드를 이용해서 동작 구조를 파악해보자
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
price: float
@app.post("/items/")
async def create_item(item: Item):
return {"name": item.name, "price": item.price}
- app = FastAPI()를 통해FastAPI 앱의 인스턴스를 생성, 인스턴스에 API 라우트를 등록하면 웹 서버가 실행될 떄 해당 라우트들이 활성화 된다. 내부적으로 Starlette 프레임워크를 기반으로 작동하고 Uvicorn과 같은 ASGI 서버에서 실행된다..
- BaseModel을 상속한 Item 클래스, Pydantic이 JSON body를 Item 객체로 자동 변환 + 검증
- 클라이언트가 /items/로 POST 요청 (JSON body 포함) { "name" : "pen" , "price" : 1.5 }
- async def - 비동기로 처리됨 (DB, 외부 API와 충돌 안 생김)
- dictionary 형식{}으로 반환하면 결과를 JSON 응답으로 자동 직렬화
- /docs 접속 시 이 API가 자동 문서화되어 인터페이스 제공 됨 (Swagger)
비동기로 처리된다는 것은 어떤 작업을 요청한 다음, 그 작업이 끝날 때까지 기다리지 않고 다른 일을 먼저 처리하는 방식을 의미한다.
다음은 FastAPI를 쓰면 좋은 상황들이다.
| 쓰기 좋은 상황 | 이유 |
| AI/머신러닝 모델 API화 | Python 기반 모델을 그대로 wrapping 가능 |
| 빠른 프로토타이핑 | 코드 짧고 직관적, 문서 자동화 덕분에 개발 속도 ↑ |
| 마이크로서비스 API | 성능 좋고 구조 가벼워서 작은 단위의 API 서버에 적합 |
| 비동기 처리가 중요한 시스템 | async def로 많은 동시 요청을 처리 가능 |
| JSON 기반 백엔드 필요할 때 | 모든 요청/응답이 JSON이라 모바일/웹과 호환성 ↑ |
✅ Swaager란 REST API를 문서화하고 테스트할 수 있게 도와주는 도구로 정식 명칭은 OpenAPI 이다.
| 기능 | 설명 |
| API 문서 자동 생성 | 어떤 경로, 어떤 요청, 어떤 응답이 있는지 자동 문서화 |
| API 직접 테스트 | 브라우저에서 버튼 클릭만으로 API 요청 가능 |
| JSON 스펙 제공 | OpenAPI 형식으로 다른 시스템과 연동 가능 |
| 팀 협업 효율 ↑ | 프론트엔드, 앱 개발자와 명확하게 API 소통 가능 |
위의 FastAPI 예시에서
from fastapi import FastAPI
app = FastAPI()
@app.get("/hello")
def say_hello():
return {"message": "hello"}
/docs로 접속 시 다음과 같은 Swagger UI가 자동 생성된다.
- 📄 /hello: GET 요청
- 🔍 응답: {"message": "hello"}
FastAPI는 Python 기반이기 때문에 Java(Spring)처럼 빌드를 하지않고 코드 실행을 위한 준비가 빌드 역할을 대신한다.
| Java(Spring)에서의 빌드 | FastAPI(Python)에서의 대응 |
| .jar 생성 (Gradle) | .py 파일 실행 환경 구성 |
| 의존성 설정 (build.gradle) | requirements.txt 또는 pyproject.toml |
| ./gradlew build | pip install -r requirements.txt |
| 실행: java -jar | 실행: uvicorn main:app --reload (개발 모드) uvicorn main:app --host 0.0.0.0 --port 8000 (프로덕션 모드) |
| 패키징 + 배포 | Docker 이미지로 패키징하거나 zip 업로드 |

