How to get access to the request payload in Tapir/ZIOHttp DefaultServerLog?

218 views Asked by At

We build a REST microservice with Scala 3, ZIO 2, ZIO logging and Tapir.

For context specific logging we want to use the MDC and set an attribute there which is taken from the request payload.

Is it possible to get access to the request payload in DefaultServerLog to extract the MDC attribute and then use it for ZIO logging feature MDC logging, i.e. create a LogAnnotation from the extracted attribute, so it will also be logged by all DefaultServerLog methods (doLogWhenHandled etc.). Currently it works for our own log statements, but not for those of Tapir/ZIO-HTTP.

1

There are 1 answers

0
Chris W. On

See answer here https://softwaremill.community/t/how-to-get-access-to-the-request-payload-in-tapir-ziohttp-defaultserverlog/84/3.

Adam Warski:

"This is usually problematic as the body of the request is a stream of bytes, which is read from the socket as it arrives. That is, the request isn’t loaded into memory by default.

You can work-around this by reading the whole request into memory using serverRequest.underlying.asInstanceOf[zio.http.Request].body.asArray, extracting the required info and enriching the fiber-locals appropriately. You might also need to substitute the Request with a copy, which has the body provided as a byte array (in a “strict” form), so that the “proper” body parser doesn’t try to re-read from the network (where nothing will be available).

However, this has some downsides: the body will be parsed twice (once by your interceptor, once by the parsing that’s defined later); and it will be read into memory (which might be problematic if you don’t have a limit on the size of the body)."