템플릿

템플릿 (Templates)

HTML을 문자열로 하드코딩해서 응답하지 말고, 템플릿(template)을 쓰면 훨씬 깔끔해요. FastAPI는 원하는 템플릿 엔진을 아무거나 쓸 수 있어요. 가장 흔한 선택은 Flask 같은 도구에서도 쓰는 Jinja2죠. 설정을 쉽게 해 주는 유틸리티도 Starlette에서 제공해요.

출처: 공식문서

의존성 설치하기

프로젝트에 jinja2를 추가해요:

$ uv add jinja2

---> 100%

Jinja2Templates 사용하기

사용 순서는 이렇게 돼요:

  • Jinja2Templates를 임포트해요.
  • 나중에 재사용할 templates 객체를 만들어요.
  • 템플릿을 반환할 경로 연산Request 파라미터를 선언해요.
  • 만든 templates로 템플릿을 렌더링하고 TemplateResponse를 반환해요. 템플릿 이름, request 객체, 그리고 Jinja2 템플릿 안에서 쓸 "context" 사전(키-값 쌍)을 넘겨요.
from fastapi import FastAPI, Request
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates

app = FastAPI()

app.mount("/static", StaticFiles(directory="static"), name="static")


templates = Jinja2Templates(directory="templates")


@app.get("/items/{id}", response_class=HTMLResponse)
async def read_item(request: Request, id: str):
    return templates.TemplateResponse(
        request=request, name="item.html", context={"id": id}
    )

참고 — FastAPI 0.108.0, Starlette 0.29.0 이전에는 name이 첫 번째 파라미터였어요. 그리고 그 전 버전에서는 request 객체를 context의 키-값 쌍 일부로 전달했었어요.

response_class=HTMLResponse를 선언하면 문서 UI가 응답이 HTML이라는 걸 알 수 있어요.

참고 | 기술적 세부사항from starlette.templating import Jinja2Templates로 쓸 수도 있어요. FastAPI는 개발자인 여러분을 위해 같은 starlette.templatingfastapi.templating으로도 제공할 뿐이에요. 대부분의 응답은 Starlette에서 그대로 오고, RequestStaticFiles도 마찬가지예요.

템플릿 작성하기

templates/item.html에 템플릿을 이렇게 작성해 볼게요:

<html>
<head>
    <title>Item Details</title>
    <link href="{{ url_for('static', path='/styles.css') }}" rel="stylesheet">
</head>
<body>
    <h1><a href="{{ url_for('read_item', id=id) }}">Item ID: {{ id }}</a></h1>
</body>
</html>

템플릿 context 값

HTML 안의 이 부분:

Item ID: {{ id }}

...은 여러분이 넘긴 "context" dict에서 가져온 id를 보여줘요:

{"id": id}

예를 들어 ID가 42라면 이렇게 렌더링돼요:

Item ID: 42

템플릿 url_for 인자

템플릿 안에서 url_for()를 쓸 수도 있어요. 인자는 경로 연산 함수에서 쓰던 것과 같은 인자를 받아요.

그래서 이 부분:

<a href="{{ url_for('read_item', id=id) }}">

...은 경로 연산 함수 read_item(id=id)가 처리했을 바로 그 URL을 가리키는 링크를 생성해요.

예를 들어 ID가 42라면 이렇게 렌더링돼요:

<a href="/items/42">

템플릿과 정적 파일

템플릿 안에서 url_for()를 써서, name="static"으로 마운트한 StaticFiles를 가리킬 수도 있어요. 위 item.html에서 <link href="{{ url_for('static', path='/styles.css') }}">로 스타일시트를 연결한 부분이죠.

이 예제는 static/styles.css의 CSS 파일을 연결해요:

h1 {
    color: green;
}

StaticFiles를 쓰고 있으니, 이 CSS 파일은 FastAPI 앱에서 /static/styles.css URL로 자동으로 제공돼요.

더 자세한 내용

템플릿 테스트 방법을 포함한 더 자세한 내용은 Starlette의 템플릿 문서에서 확인할 수 있어요.

더 알아보기 (Learn more)