Open tib opened 3 months ago
Hi @tib,
Converter
, setResponseBodyAsJSON
, are SPIs that you shouldn't be calling directly. They're there only for the generated code to call.
Can you describe what you're trying to do first, and we can help you achieve it without using SPIs, which are not guaranteed to be stable?
I'm simply trying to implement a HEAD response and return the Content-Length.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/HEAD
I'm using a JSON response for the GET query (MyCodableJSONObject
) and I'm trying to calculate the length of that response, so I can use the number in my HEAD handler.
I was not able to find a corresponding calculate method that I could use for this purpose.
I'm looking for a solution something like this (maybe a bit more generic, since this only works with JSON responses):
import HTTPTypes
@_spi(Generated) import OpenAPIRuntime
extension APIGateway {
func calculateContentLength<T: Encodable>(_ value: T) throws -> Int64 {
var headerFields = HTTPFields()
let res =
try OpenAPIRuntime.Converter(
configuration: .init()
)
.setResponseBodyAsJSON(
value,
headerFields: &headerFields,
contentType: ""
)
switch res.length {
case .known(let value):
return value
case .unknown:
return 0
}
}
}
Could you share the OpenAPI definition for the operation you're implementing?
From the top of my head, a ServerMiddleware
that throws away response bodies should do the trick, and in it you can verify that the content-length is present (it should be there already: https://github.com/apple/swift-openapi-runtime/blob/76951d77a0609599d2dc233e7e40808a74767c6a/Sources/OpenAPIRuntime/Conversion/CurrencyExtensions.swift#L604).
That said, HEAD request support might be something we need to add first class support for. Would that help you here?
Hi @tib, are you still interested in this? I think we should consider adding first class support for HEAD requests.
Yes, this is still an issue for us. 👍
@tib Can you share the OpenAPI doc (or at least the snippet) that includes the operation you'd like to implement HEAD for? Just to make sure we focus on the right example.
openapi: 3.1.0
info:
title: Example API
description: 'Example'
contact:
name: Binary Birds
url: https://binarybirds.com
email: info@binarybirds.com
version: 1.0.0
tags:
- name: Example
description: ''
servers:
- url: http://localhost:8080
description: dev
paths:
/example:
head:
tags:
- Example
summary: Example head
description: Example head request
operationId: headOperation
responses:
200:
$ref: '#/components/responses/ExampleResponse'
components:
schemas:
ExampleContentLength:
type: integer
description: Content length
responses:
ExampleResponse:
description: Ok
headers:
Content-Length:
$ref: '#/components/headers/Content-Length'
headers:
Content-Length:
schema:
$ref: '#/components/schemas/ExampleContentLength'
description: Content length header
Interesting, so what's the reason to include $ref: '#/components/responses/ExampleResponse'
in the 200 response, if it'll never get returned, because it's a HEAD request? Should it be a GET instead, and the ask here would be that all GET requests also support HEAD requests? (Maybe that should be done by the concrete transport, not sure.)
Question
Hello,
I'm currently trying to implement a HEAD endpoint, using the Swift OpenAPI generator & runtime. I'm using the following snippet, but I'm aware that it's far from ideal:
Is there a better way to calculate the Content-Length header for HEAD requests? 🤔
Many thanks.
Tib