[Flask] Routing (URL Rules, Converters, url_for)
정의
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> |
uuid | UUID 형식 | /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 순서에 유의.
관련 위키
- Flask - 상위 개요
- Flask Request/Response
- Flask Blueprints - URL prefix
- Flask Templates - url_for 사용
- Flask App Factory
- FastAPI Routing - 대비
이 글의 용어 (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…
💬 댓글