Both input and output bodies can be mapped to a stream, by using
stream[*]Body(streams). The parameter
must implement the
Streams[S] capability, and determines the precise type of the binary stream supported by the given
non-blocking streams implementation. The interpreter must then support the given capability. Refer to the documentation
of server/client interpreters for more information.
Here, streams refer to asynchronous, non-blocking, “reactive” stream implementations, such as akka-streams,
fs2 or zio-streams. If you’d like to use
blocking streams (such as
InputStream), these are available through e.g.
inputStreamBody without any
additional requirements on the interpreter.
Adding a stream body input/output influences both the type of the input/output, as well as the 4th type parameter
Endpoint, which specifies the requirements regarding supported stream types for interpreters.
When using a stream body, a schema must be provided for documentation. By default, when using
the schema will simply be that of a binary body. If you have a textual stream, you can use
streamTextBody. In that
case, you’ll also need to provide the default format (media type) and optional charset to be used to determine the
If your application later deserializes the body as a list of values, you can use the
For example, to specify that the output is an akka-stream, which is a (presumably large) serialised list of json objects
mapping to the
import sttp.tapir._ import sttp.tapir.generic.auto._ import sttp.capabilities.akka.AkkaStreams import akka.stream.scaladsl._ import akka.util.ByteString case class Person(name: String) // copying the derived json schema type endpoint.out(streamListBody(AkkaStreams)(Schema.derived[List[Person]], CodecFormat.Json()))
See also the runnable streaming example.