diff --git a/zio-http/src/main/scala/zio/http/endpoint/Endpoint.scala b/zio-http/src/main/scala/zio/http/endpoint/Endpoint.scala index cf84ad6f49..08fad670ad 100644 --- a/zio-http/src/main/scala/zio/http/endpoint/Endpoint.scala +++ b/zio-http/src/main/scala/zio/http/endpoint/Endpoint.scala @@ -27,7 +27,7 @@ import zio.schema._ import zio.http.Header.Accept.MediaTypeWithQFactor import zio.http._ -import zio.http.codec.{HttpCodec, _} +import zio.http.codec._ import zio.http.endpoint.Endpoint.{OutErrors, defaultMediaTypes} /** @@ -583,6 +583,41 @@ final case class Endpoint[PathInput, Input, Err, Output, Middleware <: EndpointM combiner: Combiner[Input, A], ): Endpoint[PathInput, combiner.Out, Err, Output, Middleware] = copy(input = self.input ++ codec) + + /** + * Transforms the input of this endpoint using the specified functions. This + * is useful to build from different http inputs a domain specific input. + * + * For example + * {{{ + * case class ChangeUserName(userId: UUID, name: String) + * val endpoint = + * Endpoint(Method.POST / "user" / uuid("userId") / "changeName").in[String] + * .transformIn { case (userId, name) => ChangeUserName(userId, name) } { + * case ChangeUserName(userId, name) => (userId, name) + * } + * }}} + */ + def transformIn[Input1](f: Input => Input1)( + g: Input1 => Input, + ): Endpoint[PathInput, Input1, Err, Output, Middleware] = + copy(input = self.input.transform(f)(g)) + + /** + * Transforms the output of this endpoint using the specified functions. + */ + def transformOut[Output1](f: Output => Output1)( + g: Output1 => Output, + ): Endpoint[PathInput, Input, Err, Output1, Middleware] = + copy(output = self.output.transform(f)(g)) + + /** + * Transforms the error of this endpoint using the specified functions. + */ + def transformError[Err1](f: Err => Err1)( + g: Err1 => Err, + ): Endpoint[PathInput, Input, Err1, Output, Middleware] = + copy(error = self.error.transform(f)(g)) } object Endpoint {