Special Formats (BSON / CBOR)
Use Write-KrBsonResponse and Write-KrCborResponse for compact binary object encodings, ideal for IoT, embedded systems, or high-throughput APIs where bandwidth matters.
Full source
File: pwsh/tutorial/examples/9.5-Bson-Cbor.ps1
<#
Sample: BSON & CBOR
Purpose: Demonstrate BSON and CBOR binary responses in a Kestrun server.
File: 9.5-Bson-Cbor.ps1
Notes: Shows compact binary object encoding routes.
#>
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.5'
# 3. Listener
Add-KrEndpoint -IPAddress $IPAddress -Port $Port
# Finalize configuration
Enable-KrConfiguration
# BSON route
Add-KrMapRoute -Pattern '/bson' -Verbs GET -ScriptBlock {
@{ kind = 'bson'; ts = (Get-Date).ToUniversalTime(); values = 1..3 } | Write-KrBsonResponse -ContentType 'application/bson'
}
# CBOR route
Add-KrMapRoute -Pattern '/cbor' -Verbs GET -ScriptBlock {
@{ kind = 'cbor'; ts = (Get-Date).ToUniversalTime(); values = 4..6 } | Write-KrCborResponse -ContentType 'application/cbor'
}
# Plain text route (for comparison)
Add-KrMapRoute -Pattern '/plain' -Verbs GET -ScriptBlock {
@{ kind = 'json'; ts = (Get-Date).ToUniversalTime(); values = 4..6 } | Write-KrJsonResponse
}
# Start the server
Start-KrServer -CloseLogsOnExit
Step-by-step
- Logging: Register console logger as default for request tracing.
- Server: Create server named ‘Responses 9.5’ listening on
127.0.0.1:5000. - Runtime: Add PowerShell runtime for script block route execution.
- BSON route (
/bson): Serialize objects to BSON binary format withapplication/bsoncontent type. - CBOR route (
/cbor): Serialize objects to CBOR binary format withapplication/cborcontent type. - Comparison route (
/plain): JSON equivalent for size comparison. - Start: Enable configuration and start server.
Try it
curl http://127.0.0.1:5000/bson --output payload.bson
curl http://127.0.0.1:5000/cbor --output payload.cbor
curl http://127.0.0.1:5000/plain | jq # Compare JSON size
PowerShell equivalents:
# BSON binary data
Invoke-WebRequest -Uri http://127.0.0.1:5000/bson -OutFile payload.bson
Get-Item payload.bson | Select-Object Name, Length
# CBOR binary data
Invoke-WebRequest -Uri http://127.0.0.1:5000/cbor -OutFile payload.cbor
Get-Item payload.cbor | Select-Object Name, Length
# JSON text for comparison
Invoke-RestMethod -Uri http://127.0.0.1:5000/plain
What is BSON?
BSON (Binary JSON) is a binary representation of JSON-like documents. Originally developed for MongoDB, BSON extends JSON with additional data types and is optimized for speed and storage efficiency.
BSON Features
- Binary encoding: More compact than JSON text for certain data types
- Rich data types: Supports dates, binary data, ObjectIds, and more beyond JSON
- Fast traversal: Self-describing format enables quick field skipping
- Preservation: Maintains type information (int32 vs int64, dates vs strings)
BSON Use Cases
- Database storage: MongoDB’s native format
- Network protocols: Reduced bandwidth vs JSON text
- Cross-language APIs: Type-safe object exchange
- Caching: Binary serialization for performance
What is CBOR?
CBOR (Concise Binary Object Representation) is a data format based on JSON but with binary encoding. It’s defined in RFC 8949 and designed for constrained environments.
CBOR Features
- Minimal overhead: Extremely compact encoding
- Self-describing: No schema required
- Streaming: Can process without loading entire payload
- Extensible: Tagged values for custom data types
- Standards-based: IETF RFC with wide library support
CBOR Use Cases
- IoT devices: Minimal bandwidth and processing power
- Web of Things: CoAP protocol data encoding
- Embedded systems: Memory-constrained environments
- Real-time systems: Low-latency binary protocols
BSON Route
Add-KrMapRoute -Pattern '/bson' -Verbs GET -ScriptBlock {
@{
kind = 'bson'
timestamp = (Get-Date).ToUniversalTime()
values = 1..3
metadata = @{ version = '1.0'; compressed = $false }
} | Write-KrBsonResponse -ContentType 'application/bson'
}
Custom content type
Add-KrMapRoute -Pattern '/custom-bson' -Verbs GET -ScriptBlock {
$data = @{ sensor = 'temp'; reading = 23.5; unit = 'C' }
$data | Write-KrBsonResponse -ContentType 'application/x-custom-bson' -StatusCode 200
}
CBOR Route
Add-KrMapRoute -Pattern '/cbor' -Verbs GET -ScriptBlock {
@{
kind = 'cbor'
timestamp = (Get-Date).ToUniversalTime()
values = 4..6
config = @{ enabled = $true; retries = 3 }
} | Write-KrCborResponse -ContentType 'application/cbor'
}
Streaming scenarios
Add-KrMapRoute -Pattern '/cbor-stream' -Verbs GET -ScriptBlock {
# Ideal for real-time data streams
1..100 | ForEach-Object {
@{ id = $_; value = Get-Random; ts = Get-Date }
} | Write-KrCborResponse -ContentType 'application/cbor'
}
Format Comparison
| Aspect | JSON | BSON | CBOR |
|---|---|---|---|
| Encoding | Text (UTF-8) | Binary | Binary |
| Size | Largest | Medium | Smallest |
| Human readable | Yes | No | No |
| Type preservation | Limited | Good | Excellent |
| Browser support | Native | Libraries | Libraries |
| Parsing speed | Fast | Very fast | Very fast |
| Use case | Web APIs | Databases | IoT/Embedded |
Size comparison example
For the same object @{ id=1; name="test"; active=$true }:
- JSON:
{"id":1,"name":"test","active":true}(34 bytes) - BSON: Binary representation (~45 bytes with field names and type info)
- CBOR: Binary representation (~25 bytes, most compact)
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| Binary garbled in browser | Browser displaying binary as text | Use curl --output or PowerShell OutFile |
| Client can’t parse | Missing BSON/CBOR library | Install appropriate decoder library |
| Large file size | Inefficient object structure | Optimize nested objects and arrays |
| Encoding errors | Complex PowerShell objects | Convert to simple hashtables/arrays first |
Client libraries
BSON readers:
- .NET:
MongoDB.BsonNuGet package - Python:
bsonorpymongo - Node.js:
bsonnpm package - Go:
go.mongodb.org/mongo-driver/bson
CBOR readers:
- .NET:
PeterO.CborNuGet package - Python:
cbor2orcborpackages - Node.js:
cbornpm package - Go:
github.com/fxamacker/cbor
When to use
Choose BSON when
- Working with MongoDB or document databases
- Need rich data type preservation (dates, ObjectIds, binary)
- Building .NET applications with existing BSON infrastructure
- Moderate bandwidth optimization over JSON
Choose CBOR when
- Extreme bandwidth constraints (IoT, mobile, satellite)
- Building embedded or real-time systems
- Need streaming binary protocol
- Standards compliance important (IETF RFC)
- Cross-platform binary interchange
Stick with JSON when
- Browser-based applications
- Human-readable logs or debugging
- Simple data structures
- Wide client compatibility required
References
Previous / Next
- Previous: HTML Templates & Files
- Next: Redirects