본문으로 건너뛰기
김신건의 로그

[Flask] Routing (URL Rules, Converters, url_for)

· 수정 · 📖 약 2분 · 563자/단어 #python #flask #web-framework #routing
Flask Routing, Flask URL Rules, Flask Converters, Flask url_for, Flask 라우팅, add_url_rule

정의

Flask Routing 은 Werkzeug 의 Rule 시스템에 기반한 URL 매핑입니다. 데코레이터 (@app.route, @app.get, …) 로 URL 패턴을 뷰 함수에 연결하고, converter 로 세그먼트 파싱, url_for 로 역방향 URL 생성을 지원합니다.

기본 데코레이터

@app.route("/")
def index():
    return "Home"

@app.route("/about", methods=["GET"])
def about():
    return "About"

# Flask 2.0+ method-specific
@app.get("/hello")
def hello():
    return "hi"

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

@app.put("/items/<int:id>")
def update_item(id):
    return f"updated {id}"

@app.delete("/items/<int:id>")
def delete_item(id):
    return "", 204

URL Converters

URL 세그먼트를 파라미터로 변환. <converter:name> 형식.

Converter매칭예시
string (기본)슬래시 제외 문자열/user/<name>
int양의 정수/user/<int:id>
float음/양 실수/rate/<float:v>
path슬래시 포함 문자열/files/<path:filepath>
uuidUUID 형식/orders/<uuid:oid>
any(a,b,c)나열된 값 중 하나/lang/<any(en,ko,ja):lang>
@app.get("/user/<name>")
def show_user(name: str):
    return f"User {name}"

@app.get("/post/<int:id>")
def show_post(id: int):
    return f"Post #{id}"

@app.get("/files/<path:filepath>")
def show_file(filepath: str):
    return f"File: {filepath}"

@app.get("/api/<any(v1,v2):version>/users")
def api_users(version: str):
    return f"API {version}"

int:id/post/abc 를 404 로 처리 (매칭 실패).

Custom Converter

from werkzeug.routing import BaseConverter

class ListConverter(BaseConverter):
    def to_python(self, value: str):
        return value.split("+")

    def to_url(self, values: list) -> str:
        return "+".join(str(v) for v in values)

app.url_map.converters["list"] = ListConverter

@app.get("/tags/<list:tags>")
def by_tags(tags: list[str]):
    return {"tags": tags}
# GET /tags/python+web+api  ->  tags = ["python", "web", "api"]

Trailing Slash

Flask 는 URL 을 두 가지로 정규화:

@app.get("/projects/")  # 슬래시 있음 (canonical)
def projects():
    return "..."

@app.get("/about")       # 슬래시 없음 (canonical)
def about():
    return "..."
  • /projects/ 정의 -> /projects 접근 시 308 redirect/projects/
  • /about 정의 -> /about/ 접근 시 404

Trailing slash 를 통일해서 관리하는 것이 관용.

url_for (역방향 URL 생성)

뷰 함수 이름으로 URL 생성. 하드코딩 회피.

from flask import url_for

@app.get("/")
def index():
    return f'<a href="{url_for("user", name="kim")}">Kim</a>'
    # 결과: <a href="/user/kim">Kim</a>

@app.get("/user/<name>")
def user(name):
    return f"Hi {name}"

url_for 인자

url_for("user", name="kim")                    # /user/kim
url_for("user", name="kim", _external=True)    # https://example.com/user/kim
url_for("user", name="kim", _anchor="section") # /user/kim#section
url_for("user", name="kim", _scheme="https")   # scheme 강제
url_for("static", filename="css/main.css")     # /static/css/main.css

Blueprint URL

Blueprint 안에서는 bp_name.endpoint:

url_for("auth.login")     # blueprint "auth" 의 login 뷰
url_for(".sub_route")     # 현재 blueprint 내 상대 참조

여러 rule 을 한 뷰에

@app.route("/")
@app.route("/home")
def index():
    return "home"

혹은 명시적:

def index():
    return "home"

app.add_url_rule("/", endpoint="index", view_func=index)
app.add_url_rule("/home", endpoint="index", view_func=index)

Endpoint 이름 커스터마이제이션

@app.route 는 뷰 함수명을 endpoint 이름으로 사용. 다른 이름을 원하면:

@app.route("/", endpoint="root")
def home():
    return "..."

url_for("root")   # /

Class-based view 나 여러 blueprint 에서 같은 함수를 라우팅할 때 필요.

Subdomain routing

app.config["SERVER_NAME"] = "example.com:5000"

@app.get("/", subdomain="<user>")
def user_home(user):
    return f"{user}'s subdomain"

# alice.example.com:5000/  ->  user = "alice"

SERVER_NAME 필수. Wildcard DNS 설정 필요.

Redirect / Abort

from flask import redirect, url_for, abort

@app.get("/old")
def old():
    return redirect(url_for("new"), code=308)

@app.get("/secret")
def secret():
    if not authorized():
        abort(403)
    return "secret"

@app.get("/user/<int:id>")
def user(id):
    if not exists(id):
        abort(404, description="User not found")
    return "..."

URL Map 조회

print(app.url_map)
# Map([
#   <Rule '/static/<filename>' (HEAD, GET, OPTIONS) -> static>,
#   <Rule '/' (HEAD, GET, OPTIONS) -> index>,
#   ...
# ])

CLI:

flask routes
# Endpoint    Methods  Rule
# --------    -------  ----
# index       GET      /
# user        GET      /user/<name>
# static      GET      /static/<path:filename>

Method Override

REST 폼에서 PUT/DELETE 를 흉내내려면 _method 필드 + 미들웨어:

from werkzeug.middleware.method_override import MethodOverride
app.wsgi_app = MethodOverride(app.wsgi_app)

HTML 폼:

<form method="post" action="/items/1">
  <input type="hidden" name="_method" value="DELETE">
  <button>Delete</button>
</form>

Regular Expression 라우팅

기본 converter 로 부족하면 custom regex converter:

from werkzeug.routing import BaseConverter

class RegexConverter(BaseConverter):
    def __init__(self, url_map, *items):
        super().__init__(url_map)
        self.regex = items[0]

app.url_map.converters["regex"] = RegexConverter

@app.get("/pattern/<regex(r'[A-Z]{3}-\d{4}'):code>")
def by_code(code: str):
    return f"code {code}"

함정

WARNING

Trailing slash 정책을 프로젝트 전체에서 통일. 반반 섞이면 관용 지식 무너지고 SEO 도 나쁨.

CAUTION

Endpoint 충돌. 같은 endpoint 이름을 다른 URL 에 붙이면 예상 밖 동작. Blueprint 로 격리.

WARNING

url_for 는 request context 필요. 뷰 함수 밖에서 호출 시 app.test_request_context() 필요.

IMPORTANT

_external=True + SERVER_NAME 없으면 절대 URL 이 request 헤더 기반. 프록시 뒤 배포 시 ProxyFix 미들웨어로 X-Forwarded-* 신뢰.

CAUTION

path: converter 는 슬래시 포함. 뒷 세그먼트가 다른 라우트를 삼킴. URL map 순서에 유의.

관련 위키

이 글의 용어 (6개)
[FastAPI] Routing (Path Operations)fastapi
정의 FastAPI Routing 은 HTTP method + URL 을 Python 함수 (path operation) 에 매핑하는 시스템입니다. Starlette 의 라우팅 …
[Flask] Application Factory Patternflask
정의 Application Factory 는 Flask 앱 인스턴스를 함수 안에서 생성 하는 패턴입니다. 모듈 스코프에 를 두는 대신 함수를 정의해 반환합니다. 이 패턴은 사실상…
[Flask] Blueprintsflask
정의 Blueprint 는 Flask 앱을 여러 모듈로 나누는 표준 도구입니다. 라우트, 정적파일, 템플릿, before/after hook, error handler 를 그룹화…
[Flask] Request & Responseflask
정의 Flask Request/Response 는 Werkzeug 의 / 래퍼를 확장한 것입니다. Thread-local 프록시 로 뷰 함수 어디서든 현재 요청에 접근하고, re…
[Flask] Templates (Jinja2)flask
정의 Flask Templates 는 Jinja2 템플릿 엔진의 Flask 통합입니다. 로 컨텍스트 (변수) 를 넘겨 HTML/텍스트를 렌더링하고, template inherit…
[Python] Flaskflask
정의 Flask 는 Armin Ronacher 가 2010년 발표한 WSGI 기반 Python 마이크로프레임워크 입니다. Pallets Projects 가 유지관리하고, 2026…

💬 댓글

사이트 검색 / 명령어

검색

스크롤 = 확대/축소 · 드래그 = 이동 · 0 = 원래 크기 · ESC = 닫기