honojs / middleware

monorepo for Hono third-party middleware/helpers/wrappers
https://hono.dev
395 stars 138 forks source link

[zod-openapi] Question: How to use .body()/binary data with openapi #641

Open elliotnash opened 1 month ago

elliotnash commented 1 month ago

I have a route that returns an object with a custom binary encoding. I want to use zod-openapi to document that route, but I'm having trouble with using Context.body() with an openapi route.

For reference, this is how I have my schema defined

const TrailAllSchema = z.instanceof(Uint8Array).openapi({
  description: "Binary data",
  format: "binary",
  example: new Uint8Array()
});

export const trailAllRoute = createRoute({
  summary: "Gets all trail data.",
  method: "get",
  path: "/all",
  responses: {
    200: {
      description: "Test",
      content: {
        "application/octet-stream": {
          schema: TrailAllSchema
        }
      }
    }
  }
});

And then my route is defined as

  .openapi(trailAllRoute, (ctx) => {
    const trailList = new TrailList(trailsService.trails.values());
    ctx.header("Content-Type", "application/octet-stream")
    return ctx.body(trailList.encode().bytes())
  })

This gives an error that Response is not assignable to type TypedResponse<{}, 200, string> Casting the response to TypedResponse<Uint8Array, 200, string> seems to work fine, but I'm wondering if there's a better built in way to serve binary data.

Shyrogan commented 1 month ago

I'm not sure if that will help but I return a XLSX without any typing error using something like that:

  .openapi(trailAllRoute, (ctx) => {
    const trailList = new TrailList(trailsService.trails.values());
    return ctx.body(trailList.encode().bytes(), 200, {
      "Content-Type": "application/octet-stream"
    })
  })