OpenAPI: multipart/mixed
Document ordered multipart/mixed payloads with OpenAPI.
Full source
File: pwsh/tutorial/examples/22.11-Multipart-Mixed-OpenAPI.ps1
<#!
22.4 multipart/mixed (ordered parts)
Client example (PowerShell):
$boundary = 'mixed-boundary'
$body = @(
"--$boundary",
"Content-Type: text/plain",
"",
"first",
"--$boundary",
"Content-Type: application/json",
"",
'{"value":42}',
"--$boundary--",
""
) -join "`r`n"
Invoke-RestMethod -Method Post -Uri "http://127.0.0.1:$Port/mixed" -ContentType "multipart/mixed; boundary=$boundary" -Body $body
Cleanup:
Remove-Item -Recurse -Force (Join-Path ([System.IO.Path]::GetTempPath()) 'kestrun-uploads-22.4-multipart-mixed')
#>
param(
[int]$Port = 5000,
[IPAddress]$IPAddress = [IPAddress]::Loopback
)
New-KrLogger |
Set-KrLoggerLevel -Value Debug |
Add-KrSinkConsole |
Register-KrLogger -Name 'console' -SetAsDefault
New-KrServer -Name 'Forms 22.4'
Add-KrEndpoint -Port $Port -IPAddress $IPAddress | Out-Null
# =========================================================
# TOP-LEVEL OPENAPI
# =========================================================
Add-KrOpenApiInfo -Title 'Uploads 22.4 - Multipart Mixed' `
-Version '1.0.0' `
-Description 'multipart/mixed parsing using Add-KrFormRoute.'
Add-KrOpenApiContact -Email 'support@example.com'
$uploadRoot = Join-Path ([System.IO.Path]::GetTempPath()) 'kestrun-uploads-22.4-multipart-mixed'
# Add Rules
# Note: multipart/mixed is parsed as ordered parts. Rules apply when a part includes a Content-Disposition name.
# Opt-in: only multipart/form-data is enabled by default
New-KrFormPartRule -Name 'outer' -MaxBytes 1024 |
New-KrFormPartRule -Name 'nested' -MaxBytes (1024 * 1024) |
Add-KrFormOption -Name 'MixedForm' -DefaultUploadPath $uploadRoot -AllowedRequestContentTypes 'multipart/mixed'
<#
.SYNOPSIS
Form route for multipart/mixed using OpenAPI annotations.
.DESCRIPTION
This function defines a form route that accepts multipart/mixed data using OpenAPI annotations.
It responds with a JSON object containing the parsed parts' content types.
.PARAMETER FormPayload
The form data payload containing the uploaded parts.
#>
function mixed {
[OpenApiPath(HttpVerb = 'post', Pattern = '/mixed')]
[KrBindForm(Template = 'MixedForm')]
[OpenApiResponse( StatusCode = '200', Description = 'Parsed fields and files', ContentType = 'application/json')]
param(
[OpenApiRequestBody(contentType = ('multipart/mixed'), Required = $true)]
$FormPayload
)
$contentTypes = $FormPayload.Parts | ForEach-Object { $_.ContentType }
Write-KrJsonResponse -InputObject @{ count = $FormPayload.Parts.Count; contentTypes = $contentTypes } -StatusCode 200
}
Enable-KrConfiguration
# =========================================================
# OPENAPI DOC ROUTE / UI
# =========================================================
Add-KrOpenApiRoute -SpecVersion OpenApi3_2
Add-KrApiDocumentationRoute -DocumentType Swagger -OpenApiEndpoint '/openapi/v3.2/openapi.json'
Add-KrApiDocumentationRoute -DocumentType Redoc -OpenApiEndpoint '/openapi/v3.2/openapi.json'
# Start the server asynchronously
Start-KrServer
Step-by-step
- Logger: Register a console logger for visibility.
- Server: Create the host and bind a listener.
- OpenAPI: Add document info and contact metadata.
- Rules: Define multipart rules and opt in to
multipart/mixed. - Route: Bind
/mixedwithKrBindFormand[OpenApiRequestBody]. - Response: Emit content type summaries for the ordered parts.
- Docs: Register the OpenAPI route and documentation UIs.
- Start: Launch the server.
Try it
$boundary = 'mixed-boundary'
$body = @(
"--$boundary",
'Content-Type: text/plain',
'',
'first',
"--$boundary",
'Content-Type: application/json',
'',
'{"value":42}',
"--$boundary--",
''
) -join "`r`n"
Invoke-RestMethod -Method Post -Uri 'http://127.0.0.1:5000/mixed' -ContentType "multipart/mixed; boundary=$boundary" -Body $body
boundary="mixed-boundary"
body="--$boundary\r\nContent-Type: text/plain\r\n\r\nfirst\r\n--$boundary\r\nContent-Type: application/json\r\n\r\n{\"value\":42}\r\n--$boundary--\r\n"
curl -H "Content-Type: multipart/mixed; boundary=$boundary" --data-binary "$body" http://127.0.0.1:5000/mixed
Troubleshooting
- 415 / Unsupported Content-Type: Ensure the route opts into
multipart/mixed. - Empty parts: Verify your body uses a matching boundary and proper CRLF line endings.
References
- New-KrFormPartRule
- Add-KrFormOption
- Add-KrOpenApiInfo
- Add-KrOpenApiContact
- Add-KrOpenApiRoute
- Add-KrApiDocumentationRoute
- New-KrServer
- Add-KrEndpoint
- Enable-KrConfiguration
- Write-KrJsonResponse
Previous / Next
Previous: OpenAPI: urlencoded forms Next: OpenAPI: nested multipart