Closed khajavi closed 5 months ago
I think there's a room for improvement in stream body encoding.
For example, maybe SSE deserves a dedicated HttpContentCodec
rather than the hidden Schema comparison.
I think I've spotted the cause:
Endpoint#outStream[A]
summons an implicit HttpContentCodec
(code)HttpContentCodec
is created using the existing schema, with application/json
as the first candidate (code)Body.StreamBody
assumes it contains a byte streamapplication/json
has been treated as binary since 2022, unlike the other JSON variants. I think it's just a mistake.
For SSE, I took a workaround with a custom codec that might be added to the upstream once there is a proper decoder implementation.
val binaryCodec: BinaryCodec[ServerSentEvent] =
new BinaryCodec[ServerSentEvent] {
override def encode(value: ServerSentEvent): Chunk[Byte] =
Chunk.fromArray(value.encode.getBytes)
override def streamEncoder: ZPipeline[Any, Nothing, ServerSentEvent, Byte] =
ZPipeline.fromFunction(_.mapChunks(_.flatMap(encode)))
override def decode(whole: Chunk[Byte]): Either[DecodeError, ServerSentEvent] =
Left(DecodeError.UnsupportedSchema(ServerSentEvent.schema, "ServerSendEvent"))
override def streamDecoder: ZPipeline[Any, DecodeError, Byte, ServerSentEvent] =
ZPipeline.fromSink(ZSink.fail(DecodeError.UnsupportedSchema(ServerSentEvent.schema, "ServerSendEvent")))
}
val httpContentCodec: HttpContentCodec[ServerSentEvent] =
HttpContentCodec(
ListMap(
MediaType.text.`event-stream` -> binaryCodec
),
ServerSentEvent.schema
)
val httpCodec: HttpCodec[HttpCodecType.Content, ZStream[Any, Nothing, ServerSentEvent]] =
HttpCodec.contentStream(httpContentCodec)
Describe the bug Encountered a
ClassCastException
in ZIO HTTP's streaming endpointTo Reproduce Steps to reproduce the behaviour:
curl -X 'GET' 'http://127.0.0.1:8080/events'
Expected behaviour I expect the curl method to return events properly
Current Behaviour The app throws the following exception: