타입 힌트(type hint)는 프로그래밍에서 변수나 함수의 예상 타입을 명시적으로 표시하는 기술이다.
FastAPI에서는 이 기능을 활용해서 별도의 검증 로직 없이도 안정적인 API를 구현할 수 있다.
1. 기본 타입 힌트
FastAPI에서 [경로 매개변수]나 [쿼리 매개변수]에 타입 힌트를 추가혀면, 해당 타입에 맞지 않는 요청은 자동으로 거부된다. 또한, 매개변수에 기본값을 설정하여 선택적으로 만들 수있다.
# main.py로 작성
from fastapi import FastAPI # FastAPI 라이브러리를 import 한다.
app = FastAPI() # FastAPI 인스턴스를 생성한다.
@app.get("/")
def read_root():
return {'message':'Hello World!!'}
# 경로 매개변수 사용 예시
@app.get("/items/{item_id}")
def read_item(item_id: int): # item_id는 기본값이 None인 쿼리 매개변수
return {"item_id": item_id}
# 쿼리 매개변수 사용 예시
@app.get("/getdata/")
def read_items(data: str = "example"): # data의 기본값은 'example'
return {"data": data}
브라우저에서 http://127.0.0.1:8000/items/88 로 접속하면 아래와 같이 출력된다.
만약 http://127.0.0.1:8000/items/test 과 같이 item_id 자리에 해당되는 부분이 정수(int) 타입이 아니라면
아래와 같이 에러가 출력된다.
그리고, 두번째로 http://127.0.0.1:8000/getdata/?data=somequery와 같이 data 쿼리 매개변수를 넣으면 아래와 같이 출력된다.
http://127.0.0.1:8000/getdata/ 를 입력하면 소스에 설정한 data의 기본값인 example 을 출력하게 된다.
만약 http://127.0.0.1:8000/getdata/?data=11 와 같이 data 값에 숫자를 입력한다면 에러가 날 것이라고 생각할 수 도 있겠으나 11을 문자로 생각하고 아래와 같이 출력을 하게 된다.
2. 고급 타입 힌트
FastAPI는 typing 모듈에서 제공하는 List, Dict 같은 고급 타입 힌트를 사용하여 요청 데이터를 쉽게 다룰 수 있다.
# main.py로 작성
from fastapi import FastAPI # FastAPI 라이브러리를 import 한다.
from typing import List, Dict # 고급 타입 힌트 사용을 위한 typeing 모듈 사용
app = FastAPI() # FastAPI 인스턴스를 생성한다.
@app.get("/")
def read_root():
return {'message':'Hello World!!'}
# List 데이터 타입을 위해 쿼리 매개변수로 받은 라우트 예제
@app.get("/items/")
def read_items(q: List[int] = Query([])): # 빈 리스트를 기본값으로 설정
return {"q": q}
# Dict 데이터 타입을 요청 바디로 받는 라우트 예제
@app.post("/create-item/")
def crate_item(item: Dict[str, int]): # data의 기본값은 'example'
return item
위 소스중 Query는 쿼리 매개변수의 기본값을 설정하는 데 사용되고, 유효성 검사 및 메타데이터 선언에서도 사용된다
여기서 Query([])는 해당 쿼리 매개변수가 필수가 아님을 나타내고, 기본값으로 빈 리스트를 제공한다.
Dict와 달리 List 타입 힌트의 경우 List[int] = Query([])와 같이 반드시 query() 관련 구문을 함께 넣어주어야 타입 힌트 유효성 검사가 정상 동작한다.
웹브라우저에 http://127.0.0.1:8000/items/?q=1&q=2&q=3 을 입력하면 아래와 같이 출력된다.
만약 1,2,3 숫자가 아닌 문자열을 입력하면 어떻게 될까? 아래처럼 List[int] 타입 힌트가 맞지 않아 에러가 출력된다.
http://127.0.0.1:8000/create-item/ 주소에서 HTTP POST 요청을 전송하기 위해 웹브라우저 방식이 아닌 curl 명령어로 테스트 해보자
아래와 같이 입력하면 예제와 같은 결과를 얻을 수 있다
]# curl -X POST "http://127.0.0.1:8000/create-item/" -H "accept: application/json" -H "Content-Type: application/json" -d "{\"name\": 1}"
3. 타입 힌트로 사용 가능한 데이터 타입
● 기본 데이터 타입
- int : 정수
- float : 부동소수점 숫자
- str : 문자열
- bool : 불리언(True 또는 False)
● 컬렉션 타입
- List : 변경 가능한 순서가 있는 컬렉션 (예 : List[int]는 정수의 리스트이다)
- Tuple : 변경 불가능한 순사가 있는 컬렉션 (예: Tuple[str, int]는 문자열과 정수의 튜플이다)
- Dict : 키와 값의 쌍을 갖는 컬렉션 (예: Dict[str, float]는 문자열 키와 부동소수점 숫자 값의 딕셔너리이다)
- Set : 중복 없는 항목의 컬렉션 (예: Set[bool]은 불리언 값의 세트이다)
● 특수 타입
- None : 아무런 값을 갖지 않음
- Any : 모든 타입을 허용, 타입 검사 무시할때 사용
● typing 모듈의 고급 타입
- Optional : 값이 있거나 None일 수 있는 타입 (예: Optional[str]은 문자열이거나 None일 수 있다)
- Union : 여러 타입 중 하나일 수 있는 값 (예 : Union[int, str]은 정수 또는 문자열이 될 수 있다)
- Callable : 호출 가능한 객체(함수 등)을 나타냄
(예 : Callable[[int, int], int]는 두 정수 매개변수를 받고 정수를 반환하는 함수)
- Iterable : 반복 가능한 객체를 나타냄 (예 : Iterable[str]은 문자열을 항목으로 갖는 반복 가능한 객체
- Sequence : 시퀀스 타입을 나타냄 (예 : Sequence[float]는 부동소수점 숫자의 시퀀스)
● 사용자 정의 타입
- 클래스나 다른 타입 힌트를 사용하여 사용자 정의 타입을 생성할 수 있다.
(예: 클래스 Person을 정의하고 def get_person() -> Person:과 같이 사용할 수 있다.
이러한 타입은 단독으로 사용하거나 typing 모듈의 다양한 기능과 결합하여 더 복잡한 타입 힌트를 만드는데 사용할 수 있다.
예를 들면, List[Dict[str, Union[int, Str]]]은 문자열을 키로하고 정수 또는 문자열을 값으로 하는 딕셔너리의 리스트를 나타낸다.
FastAPI는 이러한 타입 힌트를 사용하여 요청에서 받은 데이터의 형식을 검증하고, 응답 데이터를 적절한 형식으로 변환하여 API에 대한 문서를 자동으로 생성한다.