NEW: Fenrir v1.2.2 is now available — Logo & Favicon Patch! Read the changelog
routing.md
docs routing.md

Routing

Basic Routing

1
2
3
4
5
6
7
8
9
# Simple route
@app.get("/hello")
async def hello():
    return {"message": "Hello, World!"}

# Multiple methods
@app.route("/resource", methods=["GET", "POST"])
async def resource():
    return {"message": "Resource"}

Path Parameters

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# String parameter (default)
@app.get("/users/<username>")
async def get_user(username: str):
    return {"username": username}

# Integer parameter
@app.get("/posts/<post_id:int>")
async def get_post(post_id: int):
    return {"post_id": post_id}

# Float parameter
@app.get("/prices/<price:float>")
async def get_price(price: float):
    return {"price": price}

# Path parameter (matches anything including slashes)
@app.get("/files/<file_path:path>")
async def get_file(file_path: str):
    return {"file_path": file_path}

# Regex parameter
@app.get("/items/<re:([a-z]+):item_name>")
async def get_item(item_name: str):
    return {"item_name": item_name}

Query Parameters

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
from fenrir import Query

@app.get("/search")
async def search(q: str = Query(default=None)):
    return {"query": q}

# With validation
@app.get("/items")
async def list_items(
    skip: int = Query(0, ge=0),
    limit: int = Query(10, le=100)
):
    return {"skip": skip, "limit": limit}

Named Routes

1
2
3
4
5
6
7
@app.get("/users/<user_id:int>", name="get_user")
async def get_user(user_id: int):
    return {"user_id": user_id}

# In templates or helpers
from fenrir import url_for
user_url = url_for("get_user", user_id=123)
Edit on GitHub Last Updated: Jun 04, 2026
© 2026 Fenrir Project.
main*
v1.2.2
Ln 1, Col 1
UTF-8
Prettier
Light Mode
Markdown