ESC
Type to search...
S
Soli Docs

Request Parameters

Unified access to route parameters, query strings, and request body data.

One Access Point

The req["all"] field merges parameters from all sources into a single convenient hash. The same value is exposed as the global params variable, so you rarely need to touch req directly.

1 Parameter Sources

Parameters can come from three places in an HTTP request:

Route Params

Embedded in the URL path

/users/:id/posts/:post_id

Query Params

URL query string

?page=1&limit=20

Body Params

Request body (JSON/form)

{"name": "Alice"}

2 The Unified all Field

controllers/items_controller.sl
# Request: PUT /items/42?status=active
# Body: {"status": "urgent", "quantity": "5"}

def update_item(req: Any)    # Unified access to all parameters
  all = req["all"]

  # ID from route params
  print("ID:", all["id"]);           # "42"

  # Status appears in both query and body
  # Body value takes precedence!
  print("Status:", all["status"]);   # "urgent" (from JSON body)

  # Quantity from body only
  print("Quantity:", all["quantity"]); # "5"

  {"status": 200, "body": "Updated"}
end

3 The Global params Variable

Before every request is dispatched, the server sets a global params to the same value as req["all"]. This lets controllers, handlers, and views read unified parameters without threading req through their code.

controllers/profile_controller.sl
# Request: POST /users/123/profile?name=alice
# Body: {"bio": "Developer"}

fn update_profile(req: Any) -> Any
  # Dot access works on the global params hash
  print("User ID:", params.id);       # "123" (from route)
  print("Name:", params.name);        # "alice" (from query)
  print("Bio:", params.bio);          # "Developer" (from JSON body)

  # Bracket access is also supported
  limit = params["limit"] or "20";

  {"status": 200, "body": "Profile updated"}
end

params is refreshed per request, so it always matches the current handler's req["all"].

The Global cookies Variable

The server also sets a global cookies variable to the same value as req["cookies"]. This hash contains all cookies parsed from the Cookie header, defaulting to {} when no cookies are present. Like params, the cookies global is refreshed before each request and is available in controllers, middleware, and views.

controllers/profile_controller.sl
fn show(req: Any) -> Any
  # Read cookies directly (no req prefix needed)
  theme = cookies["theme"] or "light";

  # Dot access also works
  session_id = cookies.session_id;

  {"status": 200, "body": "OK"}
end

4 Priority Order

When the same parameter exists in multiple sources, values are merged with this priority (highest wins):

3
Body params Highest priority - overrides everything
2
Query params Overrides route params
1
Route params Base priority

5 Individual Sources Still Work

You can still access individual parameter sources separately:

handlers.sl
def handler(req: Any)    # Route parameters only
  id = req["params"]["id"]

  # Query parameters only
  page = req["query"]["page"]

  # JSON body only
  data = req["json"]

  # Form data only
  form = req["form"]

  # Or unified access
  all = req["all"]

  {"status": 200, "body": "OK"}
end

6 Complete Example: Search API

controllers/search_controller.sl
# GET /api/search?q=2
# orrust&page= POST /api/search with body {"q": "rust", "filters": "recent"}

def search(req: Any)
all = req["all"]

  # Unified params allow flexible API design
  query = all["q"] or ""
  page = all["page"] or "1"
  limit = all["limit"] or "20"

  # Use unified params for filtering
  filters = {
    "query": query,
    "page": page,
    "limit": limit,
    "category": all["category"],      # Optional
    "sort": all["sort"] or "relevance",
    "min_price": all["min_price"],    # Optional
    "max_price": all["max_price"]     # Optional
  }

  # Execute search
  results = execute_search(filters)
  {
    "status": 200,
    "body": json_stringify({
      "results": results,
      "page": page,
      "limit": limit
    })
  }
end

API Reference

Field Type Description
req["method"] String HTTP method (GET, POST, etc.)
req["path"] String Request path
req["params"] Hash Route parameters only
req["query"] Hash Query string parameters only
req["all"] Hash Unified parameters (route + query + body)
params Hash Global shorthand for req["all"], refreshed per request
cookies Hash Global req["cookies"], parsed from the Cookie header. Defaults to {}. Refreshed per request.
req["cookies"] Hash Parsed cookies from the Cookie header
req["json"] Any/Null Parsed JSON body
req["form"] Hash/Null Parsed form data
req["headers"] Hash Request headers
req["body"] String Raw request body

Benefits

Flexibility

Clients can send parameters via URL, query string, or body - your handler doesn't care where they come from.

Simplicity

Single access point for all parameters. No more checking multiple places.

Backward Compatible

Individual sources (req["params"], req["query"]) still work exactly as before.

Intuitive Priority

Body params naturally override URL params. No manual merging required.