개발/FastAPI

FastAPI Swagger 문서 자동 생성, `/docs` 화면이 만들어지는 원리

notebase 2026. 5. 26. 14:49

FastAPI에서 Swagger UI 문서가 자동으로 생성되는 원리를 초보자도 이해하기 쉽게 정리했습니다. /docs, /redoc, /openapi.json의 역할과 실제 API 테스트 방법까지 함께 설명합니다.

 

FastAPI를 실행한 뒤 /docs에 접속하면 API 문서 화면이 자동으로 열립니다. 따로 문서 파일을 만들지 않았는데도 엔드포인트, 요청값, 응답 구조가 정리되어 나오죠. 이 기능이 FastAPI의 Swagger 문서 자동 생성입니다.

처음 보면 꽤 신기합니다.

“내가 한 건 함수 하나 만든 것뿐인데, 왜 문서가 생기지?”

이 부분을 이해하면 FastAPI가 왜 입문자에게도 편하고, 협업용 API 서버를 만들 때 왜 자주 언급되는지 감이 잡힙니다.

2026년 5월 기준 FastAPI 공식 문서에 따르면, FastAPI는 기본적으로 Swagger UI를 /docs에서 제공하고, ReDoc을 /redoc에서 제공합니다. OpenAPI 스키마는 기본적으로 /openapi.json에서 확인할 수 있습니다.


 

FastAPI에서 Swagger 문서가 자동으로 생긴다는 뜻

API 문서는 보통 이런 내용을 담습니다.

  • 어떤 주소로 요청해야 하는지
  • GET, POST 같은 HTTP 메서드는 무엇인지
  • 요청할 때 어떤 값을 보내야 하는지
  • 응답은 어떤 형태로 돌아오는지
  • 에러가 발생하면 어떤 상태 코드가 나오는지

FastAPI는 이 정보를 코드에서 읽어 자동으로 문서를 만듭니다.

예를 들어 아래와 같은 코드가 있다고 해보겠습니다.

main.py

from fastapi import FastAPI

app = FastAPI()


@app.get("/hello")
def read_hello():
    return {"message": "Hello FastAPI"}

 

여기서 FastAPI는 다음 정보를 알 수 있습니다.

@app.get("/hello")를 보고 /hello라는 GET API가 있다는 것을 압니다.

read_hello() 함수가 이 API를 처리한다는 것도 압니다.

그리고 반환값을 통해 이 API가 어떤 응답을 줄 수 있는지 문서에 표시할 수 있습니다.

물론 단순한 예제에서는 정보가 많지 않습니다. 하지만 타입 힌트와 Pydantic 모델을 함께 사용하면 문서가 훨씬 구체적으로 만들어집니다.


 

Swagger UI는 어디에서 확인할 수 있을까

FastAPI 앱을 실행하면 기본적으로 아래 주소에서 Swagger UI를 볼 수 있습니다.

http://127.0.0.1:8000/docs

 

개발 서버를 실행하는 명령어는 보통 아래처럼 사용합니다.

fastapi dev main.py

 

또는 Uvicorn을 직접 사용한다면 이렇게 실행할 수 있습니다.

uvicorn main:app --reload

 

실행 후 브라우저에서 /docs에 접속하면 API 목록이 자동으로 정리된 화면이 나옵니다.

여기서 끝이 아닙니다.

Swagger UI는 단순히 읽기만 하는 문서가 아닙니다. 화면에서 바로 API 요청을 보내고 응답을 확인할 수 있습니다.

입문자 입장에서는 Postman 같은 별도 도구 없이도 API를 테스트할 수 있어서 꽤 편합니다.


 

FastAPI가 문서를 자동으로 만드는 원리

FastAPI의 자동 문서 생성은 크게 세 가지 요소를 바탕으로 동작합니다.

첫 번째는 라우터 정보입니다.

@app.get("/items")

 

이 코드를 보면 FastAPI는 /items라는 주소와 GET 메서드를 문서에 추가합니다.

두 번째는 타입 힌트입니다.

@app.get("/items/{item_id}")
def read_item(item_id: int):
    return {"item_id": item_id}

 

여기서 item_id: int라고 적으면 FastAPI는 item_id가 정수여야 한다는 것을 압니다.

그래서 Swagger UI 문서에도 item_id가 integer 타입으로 표시됩니다.

세 번째는 Pydantic 모델입니다.

from pydantic import BaseModel


class Item(BaseModel):
    name: str
    price: int

 

이런 모델을 요청 본문에 사용하면, Swagger UI는 nameprice가 필요한 값이라는 것을 문서에 보여줍니다.

즉, FastAPI 문서는 별도의 문서 작성 도구가 아니라 코드 구조를 바탕으로 자동 생성되는 API 명세에 가깝습니다.


 

직접 확인해보는 간단한 예제

아래 예제를 main.py 파일에 작성해보겠습니다.

main.py

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()


class ItemCreate(BaseModel):
    name: str
    price: int
    description: str | None = None


@app.get("/")
def read_root():
    return {"message": "FastAPI 문서 자동 생성 예제입니다."}


@app.get("/items/{item_id}")
def read_item(item_id: int):
    return {
        "item_id": item_id,
        "name": "keyboard",
        "price": 30000,
    }


@app.post("/items")
def create_item(item: ItemCreate):
    return {
        "message": "상품이 생성되었습니다.",
        "item": item,
    }

 

서버를 실행합니다.

fastapi dev main.py

 

브라우저에서 아래 주소로 접속합니다.

http://127.0.0.1:8000/docs

 

그러면 Swagger UI 화면에 API가 세 개 보입니다.

  • GET /
  • GET /items/{item_id}
  • POST /items

여기서 중요한 부분은 POST /items입니다.

ItemCreate 모델에 작성한 name, price, description 필드가 Swagger UI에 자동으로 표시됩니다.

코드에 타입을 잘 적어두면 문서도 그만큼 정확해집니다.


 

요청값과 응답값이 문서에 표시되는 방식

FastAPI에서 문서 품질을 높이려면 타입 힌트를 대충 쓰면 안 됩니다.

예를 들어 아래 코드는 문서 입장에서 정보가 부족합니다.

@app.post("/items")
def create_item(item):
    return item

 

item이 어떤 구조인지 알 수 없기 때문입니다.

반면 아래처럼 Pydantic 모델을 사용하면 문서가 훨씬 명확해집니다.

from pydantic import BaseModel


class ItemCreate(BaseModel):
    name: str
    price: int
    description: str | None = None

 

이 모델을 API에 연결하면 FastAPI는 다음 내용을 문서에 반영합니다.

필드 타입 필수 여부
name string 필수
price integer 필수
description string 또는 null 선택

 

여기서 description: str | None = None은 초보자가 자주 헷갈리는 부분입니다.

str | None은 “문자열이거나 None일 수 있다”는 뜻입니다.

뒤의 = None은 “값을 보내지 않아도 된다”는 기본값입니다.

즉, 이 필드는 선택값으로 문서에 표시됩니다.


 

Field()로 문서 설명과 예시 추가하기

자동 생성된 문서를 조금 더 친절하게 만들고 싶다면 Pydantic의 Field()를 사용할 수 있습니다.

타입만 적으면 Swagger UI에 필드 이름과 타입 중심으로 표시됩니다. 여기에 description이나 examples를 넣으면 문서 화면에서 해당 필드가 어떤 값인지 더 쉽게 이해할 수 있습니다.

main.py

from fastapi import FastAPI
from pydantic import BaseModel, Field

app = FastAPI()


class ItemCreate(BaseModel):
    name: str = Field(
        description="상품의 이름입니다.",
        examples=["무선 마우스"],
    )
    price: int = Field(
        description="상품의 가격(원)입니다.",
        examples=[15000],
    )
    description: str | None = Field(
        default=None,
        description="상품 설명입니다.",
        examples=["블루투스 연결을 지원하는 무선 마우스"],
    )


@app.post("/items")
def create_item(item: ItemCreate):
    return {
        "message": "상품이 생성되었습니다.",
        "item": item,
    }

 

이렇게 작성하면 Swagger UI에서 각 필드의 설명과 예시를 함께 확인할 수 있습니다.

여기서 default=None은 이 필드가 선택값이라는 뜻입니다. 앞에서 봤던 description: str | None = None과 같은 역할을 하지만, Field()를 사용할 때는 기본값과 설명을 한곳에 묶어 적을 수 있습니다.

실제로는 이 차이가 협업할 때 꽤 큽니다.

프론트엔드 개발자나 API를 사용하는 사람이 문서를 봤을 때 “이 값에 뭘 넣어야 하지?”라고 덜 헷갈리기 때문입니다.

다만 처음부터 모든 필드에 설명을 길게 붙일 필요는 없습니다. 외부에 공유되는 API이거나, 이름만 보고 의미를 알기 어려운 필드부터 설명을 추가하는 정도면 충분합니다.

쿼리 파라미터나 경로 파라미터 설명을 더 자세히 넣고 싶다면 FastAPI의 Query(), Path()를 사용할 수도 있습니다. 이 글에서는 Swagger 문서 자동 생성 흐름이 핵심이므로, 여기서는 Pydantic 모델의 Field() 정도만 알아두면 됩니다.


 

Swagger UI에서 API를 테스트하는 방법

Swagger UI의 장점은 문서 화면에서 바로 API를 실행해볼 수 있다는 점입니다.

예를 들어 POST /items를 테스트하려면 아래 순서로 진행하면 됩니다.

  1. /docs 화면에서 POST /items를 클릭합니다.
  2. Try it out 버튼을 누릅니다.
  3. 요청 본문에 JSON 값을 입력합니다.
  4. Execute 버튼을 누릅니다.
  5. 응답 코드와 응답 본문을 확인합니다.

예시 요청값은 아래처럼 넣을 수 있습니다.

{
  "name": "mouse",
  "price": 15000,
  "description": "무선 마우스"
}

 

실행하면 응답 결과가 화면 아래에 표시됩니다.

이 방식은 API 입문자에게 특히 좋습니다.

코드를 작성하고, 브라우저에서 바로 테스트하고, 응답까지 확인할 수 있기 때문입니다.


 

/openapi.json은 무엇일까

Swagger UI 뒤에는 OpenAPI 스키마가 있습니다.

FastAPI는 기본적으로 아래 주소에서 OpenAPI JSON을 제공합니다.

http://127.0.0.1:8000/openapi.json

 

이 파일에는 API 구조가 JSON 형태로 정리되어 있습니다.

Swagger UI는 이 JSON 정보를 읽어서 사람이 보기 좋은 문서 화면으로 보여줍니다.

흐름을 단순하게 정리하면 이렇습니다.

 

FastAPI 코드
→ OpenAPI 스키마 생성
/openapi.json 제공
→ Swagger UI가 이 정보를 읽어서 /docs 화면 구성

 

그래서 Swagger UI는 문서 화면이고, OpenAPI는 문서의 원본 데이터에 가깝다고 보면 됩니다.

FastAPI 공식 문서에서도 기본 OpenAPI 스키마 URL이 /openapi.json이라고 안내합니다. 이 URL은 openapi_url 설정으로 바꿀 수 있고, openapi_url=None으로 설정하면 OpenAPI 스키마와 이를 사용하는 문서 UI가 비활성화됩니다.


 

ReDoc과 Swagger UI의 차이

FastAPI는 Swagger UI뿐 아니라 ReDoc도 기본으로 제공합니다.

ReDoc은 아래 주소에서 확인할 수 있습니다.

http://127.0.0.1:8000/redoc

 

둘 다 API 문서를 보여주지만 느낌이 조금 다릅니다.

구분 Swagger UI ReDoc
기본 주소 /docs /redoc
특징 API를 직접 실행해보기 좋음 문서를 읽기 좋게 정리
용도 개발 중 테스트 외부 공유용 문서 확인
입문자 추천 먼저 볼 만함 구조 파악용으로 좋음

 

개발하면서 API를 직접 눌러보고 테스트하려면 Swagger UI가 편합니다.

반대로 전체 API 구조를 문서처럼 읽고 싶다면 ReDoc이 더 깔끔하게 느껴질 수 있습니다.


 

문서 제목과 설명 추가하기

기본 문서도 충분히 쓸 수 있지만, 프로젝트 이름과 설명을 넣으면 더 보기 좋아집니다.

main.py

from fastapi import FastAPI

app = FastAPI(
    title="상품 관리 API",
    description="상품 등록, 조회 기능을 제공하는 FastAPI 예제입니다.",
    version="1.0.0",
)

 

이렇게 작성하면 Swagger UI 상단에 API 제목, 설명, 버전 정보가 표시됩니다.

작은 차이지만 협업할 때는 꽤 중요합니다.

API 문서를 보는 사람이 이 서버가 어떤 역할을 하는지 바로 이해할 수 있기 때문입니다.


 

문서 주소를 바꾸는 방법

기본 Swagger UI 주소는 /docs입니다.

하지만 프로젝트에 따라 문서 주소를 바꾸고 싶을 수 있습니다.

main.py

from fastapi import FastAPI

app = FastAPI(
    docs_url="/api-docs",
    redoc_url="/api-redoc",
)

 

이렇게 설정하면 Swagger UI는 아래 주소에서 열립니다.

http://127.0.0.1:8000/api-docs

 

ReDoc은 아래 주소에서 열립니다.

http://127.0.0.1:8000/api-redoc

 

FastAPI 공식 문서에서도 Swagger UI 주소는 docs_url, ReDoc 주소는 redoc_url로 설정할 수 있다고 안내합니다. 각각 None으로 설정하면 해당 문서 UI를 끌 수도 있습니다.


 

운영 환경에서는 문서를 그대로 열어둬도 될까

개발 중에는 /docs가 매우 편합니다.

하지만 운영 환경에서는 한 번 더 생각해야 합니다.

API 문서가 열려 있으면 외부 사용자가 서버의 엔드포인트 구조를 쉽게 볼 수 있습니다. 물론 문서가 열려 있다고 해서 바로 보안 문제가 생기는 것은 아닙니다. 인증과 권한 처리가 제대로 되어 있다면 실제 데이터 접근은 막을 수 있습니다.

다만 내부 관리자 API, 테스트용 API, 아직 공개하면 안 되는 API가 문서에 노출될 수 있습니다.

그래서 운영 환경에서는 보통 아래 중 하나를 선택합니다.

  • 문서 UI를 비활성화한다.
  • 관리자나 내부망에서만 접근 가능하게 제한한다.
  • 공개 가능한 API와 내부 API를 분리한다.
  • 인증이 필요한 API는 보안 스키마를 명확히 설정한다.

문서를 끄고 싶다면 이렇게 작성할 수 있습니다.

main.py

from fastapi import FastAPI

app = FastAPI(
    docs_url=None,
    redoc_url=None,
)

 

OpenAPI 스키마 자체까지 끄고 싶다면 아래처럼 설정할 수 있습니다.

main.py

from fastapi import FastAPI

app = FastAPI(
    openapi_url=None,
)

 

이 설정을 하면 /openapi.json이 비활성화되고, 이를 기반으로 동작하는 Swagger UI와 ReDoc도 함께 비활성화됩니다.


 

문서 자동 생성이 편하려면 코드도 명확해야 한다

FastAPI의 Swagger 문서 자동 생성은 코드를 대신 설명해주는 기능입니다.

하지만 코드 자체가 애매하면 문서도 애매해집니다.

예를 들어 함수 이름, 모델 이름, 필드 이름을 대충 적으면 문서에서도 그대로 보입니다.

class Data(BaseModel):
    a: str
    b: int

 

이런 모델은 동작은 할 수 있지만, 문서를 보는 사람 입장에서는 ab가 무엇인지 알기 어렵습니다.

조금 더 명확하게 작성하는 편이 좋습니다.

class ProductCreate(BaseModel):
    name: str
    price: int

 

API 함수도 마찬가지입니다.

@app.post("/products")
def create_product(product: ProductCreate):
    return product

 

이렇게 작성하면 문서만 봐도 “상품을 생성하는 API”라는 느낌이 훨씬 분명해집니다.

FastAPI 문서 자동 생성 기능을 잘 쓰려면 결국 코드의 이름을 잘 짓는 습관이 중요합니다.


 

입문자가 자주 헷갈리는 부분

/docs가 실제 API 주소는 아니다

/docs는 API 테스트와 문서 확인을 위한 화면입니다.

실제 API 주소는 /items, /products, /users처럼 직접 만든 엔드포인트입니다.

Swagger UI가 데이터베이스를 만들어주는 것은 아니다

Swagger UI는 API를 보여주고 테스트하는 화면입니다.

데이터 저장, DB 연결, 로그인 처리 같은 기능은 직접 구현해야 합니다.

타입 힌트를 적으면 검증과 문서화가 함께 좋아진다

FastAPI에서는 타입 힌트가 단순한 메모가 아닙니다.

요청값 검증에도 쓰이고, 문서 자동 생성에도 반영됩니다.

그래서 FastAPI를 배울 때는 타입 힌트를 함께 익히는 편이 좋습니다.


 

마무리

FastAPI의 Swagger 문서 자동 생성은 단순한 편의 기능이 아닙니다.

API를 만들고, 테스트하고, 다른 사람에게 설명하는 흐름을 하나로 이어주는 기능에 가깝습니다.

입문 단계에서는 /docs에 접속해서 직접 요청을 보내보는 것만으로도 FastAPI 구조를 훨씬 빨리 이해할 수 있습니다.

여기서 중요한 기준은 하나입니다.

문서가 잘 나오게 하려면 코드도 명확해야 합니다.

경로 이름, 함수 이름, 타입 힌트, Pydantic 모델을 신경 써서 작성하면 Swagger UI 문서도 자연스럽게 좋아집니다. FastAPI를 처음 배운다면 API 기능을 하나 만들 때마다 /docs에서 어떻게 보이는지 같이 확인해보는 습관을 들이는 게 좋습니다.