Skip to content

Request

The Request struct provides access to all HTTP request data including path parameters, query strings, headers, and body.

#[allow(warnings)]
mod bindings;
use bindings::exports::mik::core::handler::{self, Guest, Response};
use mik_sdk::prelude::*;

The Request type is included in mik_sdk::prelude::*.

fn handler(req: &Request) -> Response {
// HTTP method
let method = req.method(); // Method::Get, Method::Post, etc.
// Path
let full_path = req.path(); // "/users?page=2"
let path_only = req.path_without_query(); // "/users"
ok!({ "method": format!("{:?}", method), "path": path_only })
}

Path parameters are extracted from route patterns like /users/{id}:

routes! {
GET "/users/{id}" => get_user,
GET "/orgs/{org}/users/{id}" => get_org_user,
}
fn get_user(req: &Request) -> Response {
// Access via param_or()
let id = req.param_or("id", ""); // &str
if !id.is_empty() {
ok!({ "id": id })
} else {
bad_request!("ID required")
}
}
fn search(req: &Request) -> Response {
// Single value (first occurrence) with default
let q = req.query_or("q", ""); // &str
let page = req.query_or("page", "1"); // &str
// All values for multi-value params
// Example: /search?tag=rust&tag=wasm&tag=http
let tags = req.query_all("tag"); // &[String] -> ["rust", "wasm", "http"]
ok!({
"query": q,
"tags": tags
})
}
fn handler(req: &Request) -> Response {
// Single header (case-insensitive) with default
let content_type = req.header_or("content-type", "");
let auth = req.header_or("authorization", ""); // Case doesn't matter
// All values for multi-value headers
let cookies = req.header_all("set-cookie"); // Vec<&str>
// All headers
let all_headers = req.headers(); // &[(String, String)]
// Common header shortcuts with defaults
let trace_id = req.trace_id_or(""); // traceparent header
let token = req.bearer_token_or(""); // Bearer token from Authorization
let content_type = req.content_type_or(""); // Content-Type header
ok!({ "auth": auth })
}
fn create_user(req: &Request) -> Response {
// Check if body exists
if !req.has_body() {
return bad_request!("Request body required");
}
// Raw bytes
let bytes = req.body(); // Option<&[u8]>
// As UTF-8 text
let text = req.text(); // Option<&str>
// Parse as JSON
let json = req.json(); // Option<JsonValue>
if let Some(parsed) = json {
let name = parsed.path_str(&["name"]);
ok!({ "name": name })
} else {
bad_request!("Invalid JSON")
}
}
fn handler(req: &Request) -> Response {
if req.is_json() {
// Handle JSON
let body = req.json();
} else if req.is_form() {
// Handle form data
let name = req.form("name");
} else if req.is_html() {
// Handle HTML
}
ok!({})
}

For application/x-www-form-urlencoded requests:

fn submit_form(req: &Request) -> Response {
guard!(req.is_form(), 415, "Expected form data");
// Single value with default
let name = req.form_or("name", ""); // &str
let email = req.form_or("email", ""); // &str
// Multi-value fields
// Example: checkboxes with same name
let roles = req.form_all("role"); // &[String]
ok!({
"name": name,
"email": email,
"roles": roles
})
}
fn handler(req: &Request) -> Response {
if req.accepts("json") {
// Return JSON
ok!({ "format": "json" })
} else if req.accepts("html") {
// Return HTML response
// ...
} else {
// Default response
ok!({ "format": "default" })
}
}
use mik_sdk::prelude::Method;
fn handler(req: &Request) -> Response {
match req.method() {
Method::Get => { /* ... */ }
Method::Post => { /* ... */ }
Method::Put => { /* ... */ }
Method::Patch => { /* ... */ }
Method::Delete => { /* ... */ }
Method::Head => { /* ... */ }
Method::Options => { /* ... */ }
}
ok!({})
}
fn create_item(req: &Request) -> Response {
// Validate content type
guard!(req.is_json(), 415, "Content-Type must be application/json");
// Parse body
let body = ensure!(req.json(), 400, "Invalid JSON");
// Extract fields
let name = ensure!(
body.path_str(&["name"]),
400,
"name is required"
);
// Get trace ID with default
let trace_id = req.trace_id_or("unknown");
// Log the request
log!(info, "creating item", name: &name, trace_id: trace_id);
// Create item...
let id = random::uuid();
created!(format!("/items/{}", id), {
"id": id,
"name": name
})
}
MethodReturnsDescription
method()MethodHTTP method
path()&strFull path with query
path_without_query()&strPath only
param_or(name, def)&strPath parameter
query_or(name, def)&strFirst query param value
query_all(name)&[String]All query param values
header_or(name, def)&strHeader (case-insensitive)
header_all(name)Vec<&str>All header values
headers()&[(String, String)]All headers
trace_id_or(def)&strtraceparent header
bearer_token_or(def)&strBearer token from Authorization
body()Option<&[u8]>Raw body bytes
text()Option<&str>Body as UTF-8
json()Option<JsonValue>Parse body as JSON
json_with(f)Option<T>Parse body with custom parser
has_body()boolTrue if body is non-empty
content_type_or(def)&strContent-Type header
is_json()boolContent-Type is JSON
is_html()boolContent-Type is HTML
is_form()boolContent-Type is form
accepts(mime)boolAccept header contains
form_or(name, def)&strForm field value
form_all(name)&[String]All form field values