Skip to content

Routing

Ushka uses a simple but powerful convention-based routing system. You don't need to manually register your routes with decorators. Just name your functions correctly in a views.py file, and Ushka will discover them.

Convention-Based Routing

The core idea is to name your functions METHOD_endpoint.

  • METHOD: The HTTP method in lowercase (e.g., get, post, put, delete).
  • endpoint: The URL path. Use index for the root (/) of your app, and underscores (_) to represent slashes (/) in the URL.

Ushka automatically discovers any function matching this pattern in any apps/<app_name>/views.py file (for apps listed in your ushka.toml).

Examples

Let's assume these are in apps/products/views.py, and this app has a prefix of /products defined in apps/products/app.toml.

Function Name HTTP Method Resulting URL Path
get_index GET /products/
post_index POST /products/
get_all GET /products/all
get_featured_items GET /products/featured/items
delete_item DELETE /products/item

Dynamic Routes (Path Parameters)

To capture segments from the URL, you can add parameters to your view function's signature. Ushka will automatically map these to dynamic parts of the URL.

You can also add type hints to the parameters, and Ushka will use a matching regex and attempt to cast the value. Currently, int is supported for digit-only matching.

Example:

# in apps/users/views.py

from ushka.http import Request

async def get_by_id(request: Request, user_id: int):
  # Because of the `user_id: int` type hint, this will only match
  # URLs like /users/by/id/123, but not /users/by/id/abc.
  # The value of `user_id` will be an integer.
  return {"user": {"id": user_id, "name": "Test User"}}

async def get_by_username(request: Request, username: str):
  # Without a type hint (or with `str`), this will match any value
  # in that URL segment. The value of `username` will be a string.
  return {"user": {"username": username}}
Function Name HTTP Method Example URL
get_by_id(request: Request, user_id: int) GET /users/by/id/123
get_by_username(request: Request, username: str) GET /users/by/username/neo

The path is constructed by appending the parameter names to the function's endpoint name.

Listing Routes

To see a complete list of all registered routes in your application, you can use the routes list command:

ushka routes list

This is very useful for debugging and getting a quick overview of all your application's endpoints.

App Prefixes

Routes for an app are automatically prefixed with the prefix defined in that app's app.toml configuration file.

For example, if apps/products/app.toml contains:

[app]
name = "products"
prefix = "/api/v1/products"

Then a view function named get_all in apps/products/views.py will be mapped to GET /api/v1/products/all.