InvokeRequest
InvokeRequest represents the incoming HTTP request. It is passed as the first parameter to every entry point handler.
[EntryPoint]
public static Task EntryPoint(InvokeRequest req, InvokeResponse res)
{
// req is available here
return Task.CompletedTask;
}
Properties
Method
The HTTP method of the request as an uppercase string.
public string Method { get; }
switch (req.Method)
{
case "GET": /* ... */ break;
case "POST": /* ... */ break;
case "PUT": /* ... */ break;
case "DELETE": /* ... */ break;
}
Values: "GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS", "HEAD"
Path
The path portion of the URL, without query string.
public string Path { get; }
// Request: /api/users/123
Console.WriteLine(req.Path); // "/api/users/123"
Url
The full URL including query string.
public string Url { get; }
// Request: /api/users?sort=name
Console.WriteLine(req.Url); // "/api/users?sort=name"
OriginalUrl
The original unmodified URL.
public string OriginalUrl { get; }
Query
Parsed query string parameters as a case-insensitive dictionary.
public IReadOnlyDictionary<string, string> Query { get; }
// Request: /api/users?name=Alice&page=2
var name = req.Query.TryGetValue("name", out var n) ? n : "World";
var page = req.Query.TryGetValue("page", out var p) ? int.Parse(p) : 1;
res.Status(200).Json(new JsonObject { ["name"] = name, ["page"] = page });
Params
Route parameters extracted from path patterns (set by the Router).
public IReadOnlyDictionary<string, string> Params { get; }
// Route: [HttpGet("/users/:id")]
// Request: /users/42
var id = req.Params["id"]; // "42"
Body
The parsed request body as a JsonNode. For requests with Content-Type: application/json, the body is automatically deserialized. Returns null for requests with no body.
public JsonNode? Body { get; }
// POST with JSON body: { "name": "Alice", "age": 30 }
var name = req.Body?["name"]?.GetValue<string>() ?? "";
var age = req.Body?["age"]?.GetValue<int>() ?? 0;
res.Status(201).Json(new JsonObject { ["created"] = true, ["name"] = name });
Headers
Request headers as a case-insensitive dictionary.
public IReadOnlyDictionary<string, string> Headers { get; }
if (req.Headers.TryGetValue("authorization", out var auth))
{
// validate auth...
}
Cookies
Parsed cookies from the Cookie request header.
public IReadOnlyDictionary<string, string> Cookies { get; }
if (req.Cookies.TryGetValue("session", out var sessionId))
{
// use sessionId...
}
Ip
The client IP address.
public string Ip { get; }
Ips
Array of IP addresses from the X-Forwarded-For header (proxied requests).
public string[] Ips { get; }
Protocol
The protocol string: "http" or "https".
public string Protocol { get; }
Hostname
The hostname from the Host header.
public string Hostname { get; }
Secure
true if the connection uses HTTPS.
public bool Secure { get; }
Methods
GetHeader(name)
Get a single header value by name (case-insensitive). Returns null if not present.
public string? GetHeader(string name)
var contentType = req.GetHeader("content-type");
var apiKey = req.GetHeader("x-api-key");
Common Patterns
Parsing a JSON POST body
[EntryPoint]
public static Task EntryPoint(InvokeRequest req, InvokeResponse res)
{
if (req.Method != "POST")
{
res.Status(405).Json(new JsonObject { ["error"] = "Method Not Allowed" });
return Task.CompletedTask;
}
var name = req.Body?["name"]?.GetValue<string>();
if (string.IsNullOrEmpty(name))
{
res.Status(400).Json(new JsonObject { ["error"] = "name is required" });
return Task.CompletedTask;
}
res.Status(201).Json(new JsonObject { ["created"] = true, ["name"] = name });
return Task.CompletedTask;
}
Bearer token authentication
[EntryPoint]
public static Task EntryPoint(InvokeRequest req, InvokeResponse res)
{
var auth = req.GetHeader("authorization");
if (auth == null || !auth.StartsWith("Bearer "))
{
res.Status(401).Json(new JsonObject { ["error"] = "Unauthorized" });
return Task.CompletedTask;
}
var token = auth["Bearer ".Length..];
// validate token...
res.Status(200).Json(new JsonObject { ["ok"] = true });
return Task.CompletedTask;
}