Text & JSON

Use Write-KrTextResponse for plain UTF-8 text and Write-KrJsonResponse for structured object data.

Full source

File: pwsh/tutorial/examples/9.1-Text-Json.ps1

<#
    Sample: Text and JSON Responses
    Purpose: Demonstrate the use of text and JSON responses in a Kestrun server.
    File:    9.1-Text-Json.ps1
    Notes:   Shows basic text responses and structured JSON responses.
#>
param(
    [int]$Port = 5000,
    [IPAddress]$IPAddress = [IPAddress]::Loopback
)
# 1. Logging
New-KrLogger | Add-KrSinkConsole | Register-KrLogger -Name 'console' -SetAsDefault

# 2. Server
New-KrServer -Name 'Responses 9.1'

# 3. Listener
Add-KrEndpoint -IPAddress $IPAddress -Port $Port -SelfSignedCert

# 4. Finalize configuration
Enable-KrConfiguration

# 5. Add routes demonstrating text responses
Add-KrMapRoute -Pattern '/ping' -Verbs GET -ScriptBlock {
    Write-KrTextResponse 'pong'
}

# 6. Created text with custom content type
Add-KrMapRoute -Pattern '/created' -Verbs POST -ScriptBlock {
    Write-KrTextResponse -InputObject 'resource created' -StatusCode 201 -ContentType 'text/plain; charset=utf-8'
}

# 7. JSON basic
Add-KrMapRoute -Pattern '/time' -Verbs GET -ScriptBlock {
    @{ utc = (Get-Date).ToUniversalTime(); version = 1 } | Write-KrJsonResponse -Compress
}

# 8. JSON depth + pretty (no -Compress)
Add-KrMapRoute -Pattern '/config' -Verbs GET -ScriptBlock {
    $cfg = @{ name = 'demo'; nested = @{ a = 1; b = 2; c = @(1, 2, 3) } }
    $cfg | Write-KrJsonResponse -Depth 5
}

# 9. Start the server
Start-KrServer -CloseLogsOnExit

Step-by-step

  1. Server & listener: create server and listen on 127.0.0.1:5000.
  2. Runtime: add PowerShell runtime so script block routes execute.
  3. /ping: returns plain text using Write-KrTextResponse.
  4. /created: shows custom status code (201) + explicit content type.
  5. /time: pipes PSCustomObject into Write-KrJsonResponse -Compress producing compact JSON.
  6. /config: demonstrates deeper nested object with default pretty JSON (no -Compress).
  7. Start: Enable-KrConfiguration then Start-KrServer.

Try it

curl http://127.0.0.1:5000/ping
curl -X POST http://127.0.0.1:5000/created
curl http://127.0.0.1:5000/time | jq
curl http://127.0.0.1:5000/config | jq

PowerShell equivalents:

Invoke-WebRequest -Uri http://127.0.0.1:5000/ping | Select-Object -ExpandProperty Content
Invoke-WebRequest -Uri http://127.0.0.1:5000/created -Method Post | Select-Object -ExpandProperty Content
Invoke-RestMethod -Uri http://127.0.0.1:5000/time   # auto-converts JSON
Invoke-RestMethod -Uri http://127.0.0.1:5000/config | Format-List

Text

Add-KrMapRoute -Path '/ping' -Method GET -ScriptBlock {
    Write-KrTextResponse 'pong'
}

Custom status & content type

Add-KrMapRoute -Path '/plain' -Method GET -ScriptBlock {
    Write-KrTextResponse -InputObject 'Created' -StatusCode 201 -ContentType 'text/plain; charset=utf-8'
}

JSON

Pipe any object to Write-KrJsonResponse.

Add-KrMapRoute -Path '/time' -Method GET -ScriptBlock {
    [pscustomobject]@{ utc = (Get-Date).ToUniversalTime(); version = 1 } | Write-KrJsonResponse -Compress
}

Depth and compression

-Depth controls nested object traversal (default 10). -Compress removes whitespace for minimal payload.

Add-KrMapRoute -Path '/config' -Method GET -ScriptBlock {
    $cfg = [pscustomobject]@{ name='demo'; features = @(1,2,3) }
    $cfg | Write-KrJsonResponse -Depth 5 -Compress -StatusCode 200
}

Troubleshooting

Symptom Cause Fix
Empty body Wrote outside a route Ensure inside Add-KrMapRoute -ScriptBlock {}
Truncated JSON Depth too small Increase -Depth
Unexpected content type Overridden upstream Explicitly pass -ContentType 'application/json'

References


Previous / Next