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

  1. Logging: Register console logger as default for request tracing.
  2. Server: Create server named ‘Responses 9.5’ listening on 127.0.0.1:5000.
  3. Runtime: Add PowerShell runtime for script block route execution.
  4. BSON route (/bson): Serialize objects to BSON binary format with application/bson content type.
  5. CBOR route (/cbor): Serialize objects to CBOR binary format with application/cbor content type.
  6. Comparison route (/plain): JSON equivalent for size comparison.
  7. 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.Bson NuGet package
  • Python: bson or pymongo
  • Node.js: bson npm package
  • Go: go.mongodb.org/mongo-driver/bson

CBOR readers:

  • .NET: PeterO.Cbor NuGet package
  • Python: cbor2 or cbor packages
  • Node.js: cbor npm 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