InvokeResponse
InvokeResponse is the fluent response builder passed as the second parameter to every entry point handler. Methods can be chained.
[EntryPoint]
public static Task EntryPoint(InvokeRequest req, InvokeResponse res)
{
res.Status(200).Json(new JsonObject { ["message"] = "Hello" });
return Task.CompletedTask;
}
Status Methods
Status(code)
Set the HTTP status code. Returns this for chaining.
public InvokeResponse Status(int statusCode)
res.Status(201).Json(new JsonObject { ["created"] = true });
res.Status(404).Json(new JsonObject { ["error"] = "Not Found" });
SendStatus(code)
Set the status code and end the response immediately with the status text as the body.
public void SendStatus(int statusCode)
res.SendStatus(204); // 204 No Content
res.SendStatus(404); // 404 Not Found
Response Body Methods
Json(object)
Serialize an object to JSON and send it with Content-Type: application/json.
public void Json(object value)
res.Status(200).Json(new JsonObject
{
["name"] = "Alice",
["age"] = 30
});
Json<T>(T value, JsonTypeInfo<T> typeInfo)
AOT-safe JSON serialization using a JsonTypeInfo<T> from a source-generated JsonSerializerContext.
public void Json<T>(T value, JsonTypeInfo<T> typeInfo)
[JsonSerializable(typeof(MyResponse))]
internal partial class MyContext : JsonSerializerContext { }
record MyResponse(string Name, int Age);
res.Status(200).Json(new MyResponse("Alice", 30), MyContext.Default.MyResponse);
Json(JsonNode value)
Send a JsonNode (e.g., JsonObject or JsonArray) as JSON.
public void Json(JsonNode value)
var items = new JsonArray();
items.Add(new JsonObject { ["id"] = 1, ["name"] = "Item 1" });
items.Add(new JsonObject { ["id"] = 2, ["name"] = "Item 2" });
res.Status(200).Json(items);
Send(string text)
Send a plain text response with Content-Type: text/plain.
public void Send(string text)
res.Status(200).Send("Hello, World!");
Send(byte[] data)
Send raw bytes. Use Type() first to set the correct content type.
public void Send(byte[] data)
var pdfBytes = File.ReadAllBytes("report.pdf");
res.Status(200).Type("application/pdf").Send(pdfBytes);
Redirect(string url, int statusCode = 302)
Redirect the client to another URL.
public void Redirect(string url, int statusCode = 302)
res.Redirect("/new-path"); // 302 Found
res.Redirect("/new-path", 301); // 301 Moved Permanently
End()
End the response with no body.
public void End()
res.Status(204).End();
Header Methods
SetHeader(name, value)
Set a response header. Returns this for chaining.
public InvokeResponse SetHeader(string name, string value)
res.SetHeader("x-request-id", Guid.NewGuid().ToString())
.Status(200)
.Json(new JsonObject { ["ok"] = true });
AppendHeader(name, value)
Append a value to a response header (useful for multi-value headers). Returns this for chaining.
public InvokeResponse AppendHeader(string name, string value)
res.AppendHeader("cache-control", "no-cache")
.AppendHeader("cache-control", "no-store");
Type(contentType)
Set the Content-Type header. Returns this for chaining.
public InvokeResponse Type(string contentType)
res.Type("text/html").Send("<h1>Hello</h1>");
res.Type("application/xml").Send("<result>ok</result>");
File Response Methods
SendFile(filePath, options?)
Send a file as the response body, detecting its MIME type automatically. Returns this for chaining.
public InvokeResponse SendFile(string filePath, SendFileOptions? options = null)
// Absolute path
res.SendFile("/var/task/public/index.html");
// Relative path resolved from a root directory
res.SendFile("images/logo.png", new SendFileOptions { Root = "/var/task/public" });
Responds with 404 if the file is not found, 403 if access is denied, 500 on any other I/O error.
Download(filePath, filename?, options?)
Prompt the browser to download a file as an attachment. Sets Content-Disposition: attachment and delegates to SendFile.
public InvokeResponse Download(string filePath, string? filename = null, SendFileOptions? options = null)
res.Download("/var/task/reports/report.pdf", "monthly-report.pdf");
Attachment(filename?)
Set the Content-Disposition header to attachment, optionally with a filename. Non-ASCII filenames are RFC 5987–encoded. Returns this for chaining.
public InvokeResponse Attachment(string? filename = null)
res.Attachment("résumé.pdf").SendFile("/var/task/files/cv.pdf");
SendFileOptions
Options accepted by SendFile and Download:
| Property | Type | Default | Description |
|---|---|---|---|
Root | string? | "/" | Root directory to resolve the file path against |
MaxAge | int? | null | Cache max-age in milliseconds for Cache-Control: public, max-age=N |
CacheControl | bool | true | Whether to emit a Cache-Control header when MaxAge is set |
LastModified | bool | true | Whether to set the Last-Modified header from the file's mtime |
Headers | Dictionary<string, string>? | null | Additional response headers to merge into the response |
res.SendFile("/var/task/public/style.css", new SendFileOptions
{
MaxAge = 31_536_000_000, // 1 year in ms
Headers = new Dictionary<string, string>
{
["x-served-by"] = "invoke"
}
});
Common Patterns
Success with data
res.Status(200).Json(new JsonObject
{
["success"] = true,
["data"] = new JsonObject { ["id"] = 42, ["name"] = "Alice" }
});
Created resource
res.Status(201)
.SetHeader("location", $"/users/{newId}")
.Json(new JsonObject { ["id"] = newId });
Error response
res.Status(400).Json(new JsonObject
{
["error"] = "Validation failed",
["details"] = "name is required"
});
No content
res.Status(204).End();