Route Options (MapRouteOptions)

Use MapRouteOptions / New-KrMapRouteOption to configure routes with richer metadata, different languages, and advanced behaviors.

Prerequisites: see Introduction.

Full source

<#
    Sample Kestrun Server Configuration using MapRouteOptions class.
    These examples demonstrate how to use the MapRouteOptions class to configure routes in a Kestrun server.
    FileName: 2.4-Route-Options.ps1
#>

# Import the Kestrun module
Install-PSResource -Name Kestrun

# Create a new Kestrun server
New-KrServer -Name "Simple Server"

# Add a listener on port 5000 and IP address 127.0.0.1 (localhost)
Add-KrListener -Port 5000 -IPAddress ([IPAddress]::Loopback)

# Add the PowerShell runtime
# !!!!Important!!!! this step is required to process PowerShell routes and middlewares
Add-KrPowerShellRuntime

# Enable Kestrun configuration
Enable-KrConfiguration

# Map the route
Add-KrMapRoute -Verbs Get -Pattern "/xml/{message}" -ScriptBlock {
    $message = Get-KrRequestRouteParam -Name 'message'
    Write-KrXmlResponse -InputObject @{ message = $message } -StatusCode 200
}

# YAML Route using MapRouteOption
Add-KrMapRoute -Options (New-KrMapRouteOption -Property @{
        Pattern = "/yaml"
        HttpVerbs = 'Get'
        Code = {
            $message = Get-KrRequestRouteParam -Name 'message'
            Write-KrYamlResponse -InputObject @{ message = $message } -StatusCode 200
        }
        Language = 'PowerShell'
        DisableAntiforgery = $true
    }
)

# JSON Route using MapRouteOption
$options = [Kestrun.Hosting.Options.MapRouteOptions]::new()
$options.Pattern = "/json"
$options.HttpVerbs = [Kestrun.Utilities.HttpVerb[]] @('get')
$options.Code = {
    $message = Get-KrRequestHeader -Name 'message'
    Write-KrJsonResponse -InputObject @{ message = $message } -StatusCode 200
}
$options.Language = 'PowerShell'
Add-KrMapRoute -Options $options

# Text Route using MapRouteOption and Pipeline
New-KrMapRouteOption -Property @{
    Pattern = "/txt"
    HttpVerbs = 'Get'
    Code = @"
            var message= Context.Request.Query["message"];
            Context.Response.WriteTextResponse($"message = {message}");
"@
    Language = 'CSharp'
} | Add-KrMapRoute

# Start the server asynchronously
Start-KrServer

Step-by-step

  1. Base setup (module install, server, listener, PowerShell runtime, configuration) matches earlier samples. It invokes Add-KrPowerShellRuntime then Enable-KrConfiguration.
  2. XML route (PowerShell script block):
  3. YAML route (hashtable -> New-KrMapRouteOption):
    • Demonstrates composing an options object with a property bag.
    • Sets DisableAntiforgery = $true (bypasses antiforgery if globally enabled).
    • Pattern is /yaml.
    • Because there is no {message} segment the route value lookup returns $null — change pattern to /yaml/{message} if you want a route parameter.
  4. JSON route (explicit .NET object):
    • Creates a [Kestrun.Hosting.Options.MapRouteOptions] instance for strongly typed control.
    • Demonstrates supplying verbs as an enum array ([Kestrun.Utilities.HttpVerb[]]).
  5. Text route (pipeline style + C#):
    • Builds an option with Language = 'CSharp' and multiline code (a here‑string) that accesses Context.Request.Query.
    • Writes plain text using the synchronous Context.Response.WriteTextResponse helper (C# extension method).
  6. Mixed construction styles: you can mix -ScriptBlock, hashtable + New-KrMapRouteOption, manually instantiated MapRouteOptions, and C#/VB code.
  7. Language selection: Each option sets Language; when omitted PowerShell is assumed if you pass a -ScriptBlock.
  8. Antiforgery: DisableAntiforgery shows how to opt out per route if antiforgery is globally active.
  9. Retrieving data: - Route parameters: Get-KrRequestRouteParam. - Headers: Get-KrRequestHeader.
    • Query string (from C# here): Context.Request.Query["name"].

When to use MapRouteOptions

Use MapRouteOptions when you need more than the simple -Verbs -Path -ScriptBlock shape:

  • Provide inline code in another language (Language, Code).
  • Configure route-level features like : DisableAntiforgery, CORS, or OpenAPI metadata.
  • Programmatically build routes (e.g., in loops) using strongly typed objects.
  • Share a common options template and adjust per route.

For quick, minimal routes the simple Add-KrMapRoute -Verbs Get -Path ... -ScriptBlock {} form remains fine.

Try it

Start the server

. .\examples\PowerShell\Tutorial\2.4-Route-Options.ps1

Invoke routes (curl)

curl http://127.0.0.1:5000/xml/HelloXml
curl http://127.0.0.1:5000/yaml            # will show null message unless you change pattern
curl -H "message: HelloHeader" http://127.0.0.1:5000/json
curl http://127.0.0.1:5000/txt?message=HelloQuery

Invoke routes (PowerShell)

Invoke-WebRequest -Uri 'http://127.0.0.1:5000/xml/HelloXml' | Select-Object -ExpandProperty Content
Invoke-WebRequest -Uri 'http://127.0.0.1:5000/yaml'         | Select-Object -ExpandProperty Content
Invoke-WebRequest -Uri 'http://127.0.0.1:5000/json' -Headers @{ message = 'HelloHeader' } | Select-Object -ExpandProperty Content
Invoke-WebRequest -Uri 'http://127.0.0.1:5000/txt?message=HelloQuery' | Select-Object -ExpandProperty Content

Cmdlet / API references

Troubleshooting

Symptom Cause Fix
$message is $null on /yaml Pattern lacks {message} Change pattern to /yaml/{message} or use query/header instead
Header message not found on /json Missing message header Add -H "message: value" or use Get-KrRequestRouteParam/query
C# route errors Typos or missing semicolon in here‑string Validate C# snippet; keep indentation simple
404 Not Found Route not mapped or verb mismatch Confirm verb list includes the HTTP method (e.g., GET)

Next

Continue to Route Groups or explore more advanced patterns with middleware later in the tutorial.