Skip to content

Commit

Permalink
zio-http updates
Browse files Browse the repository at this point in the history
  • Loading branch information
justcoon committed Dec 25, 2023
1 parent 668e57d commit ffd04ab
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 51 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,30 +21,29 @@ import zio.http.codec.PathCodec.{ literal, string }
import zio.http.codec.{ Doc, HttpCodec, PathCodec }
import zio.http.endpoint.EndpointMiddleware.None
import zio.http.endpoint._
import zio.logging.api.http.ApiDomain.Error

object ApiEndpoints {
import ApiDomain.logLevelSchema

def rootPathCodec(rootPath: Seq[String]): PathCodec[Unit] =
if (rootPath.isEmpty) {
HttpCodec.empty
PathCodec.empty
} else {
rootPath.map(literal).reduce(_ / _)
}

def getLoggerConfigs(
rootPath: Seq[String] = Seq.empty
): Endpoint[Unit, ApiDomain.Error.Internal, List[ApiDomain.LoggerConfig], None] =
Endpoint
.get(rootPathCodec(rootPath) / literal("logger"))
): Endpoint[Unit, Unit, Error.Internal, List[ApiDomain.LoggerConfig], None] =
Endpoint(Method.GET / rootPathCodec(rootPath) / literal("logger"))
.out[List[ApiDomain.LoggerConfig]]
.outError[ApiDomain.Error.Internal](Status.InternalServerError)

def getLoggerConfig(
rootPath: Seq[String] = Seq.empty
): Endpoint[String, ApiDomain.Error, ApiDomain.LoggerConfig, None] =
Endpoint
.get(rootPathCodec(rootPath) / literal("logger") / string("name"))
): Endpoint[String, String, Error, ApiDomain.LoggerConfig, None] =
Endpoint(Method.GET / rootPathCodec(rootPath) / literal("logger") / string("name"))
.out[ApiDomain.LoggerConfig]
.outErrors[ApiDomain.Error](
HttpCodec.error[ApiDomain.Error.Internal](Status.InternalServerError),
Expand All @@ -53,9 +52,8 @@ object ApiEndpoints {

def setLoggerConfig(
rootPath: Seq[String] = Seq.empty
): Endpoint[(String, LogLevel), ApiDomain.Error.Internal, ApiDomain.LoggerConfig, None] =
Endpoint
.put(rootPathCodec(rootPath) / literal("logger") / string("name"))
): Endpoint[String, (String, LogLevel), Error.Internal, ApiDomain.LoggerConfig, None] =
Endpoint(Method.PUT / rootPathCodec(rootPath) / literal("logger") / string("name"))
.in[LogLevel]
.out[ApiDomain.LoggerConfig]
.outError[ApiDomain.Error.Internal](Status.InternalServerError)
Expand Down
51 changes: 28 additions & 23 deletions examples/core/src/main/scala/zio/logging/api/http/ApiHandlers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,44 +15,49 @@
*/
package zio.logging.api.http

import zio.ZIO
import zio.http.endpoint.EndpointMiddleware.None
import zio.http.endpoint.Routes
import zio.http.{ Handler, Route, Routes }
import zio.logging.LoggerConfigurer
import zio.logging.api.http.ApiDomain.Error
import zio.{ LogLevel, ZIO }

object ApiHandlers {

def getLoggerConfigs(rootPath: Seq[String] = Seq.empty): Routes[LoggerConfigurer, Error.Internal, None] =
def getLoggerConfigs(rootPath: Seq[String] = Seq.empty): Route[LoggerConfigurer, Nothing] =
ApiEndpoints
.getLoggerConfigs(rootPath)
.implement(_ =>
LoggerConfigurer
.getLoggerConfigs()
.map(_.map(ApiDomain.LoggerConfig.from))
.mapError(_ => Error.Internal())
)
.implement {
Handler.fromFunctionZIO[Unit] { _ =>
LoggerConfigurer
.getLoggerConfigs()
.map(_.map(ApiDomain.LoggerConfig.from))
.mapError(_ => Error.Internal())
}
}

def getLoggerConfig(rootPath: Seq[String] = Seq.empty): Routes[LoggerConfigurer, Error, None] =
def getLoggerConfig(rootPath: Seq[String] = Seq.empty): Route[LoggerConfigurer, Nothing] =
ApiEndpoints
.getLoggerConfig(rootPath)
.implement { name =>
LoggerConfigurer.getLoggerConfig(name).mapError(_ => Error.Internal()).flatMap {
case Some(r) => ZIO.succeed(ApiDomain.LoggerConfig.from(r))
case _ => ZIO.fail(Error.NotFound())
.implement {
Handler.fromFunctionZIO[String] { name =>
LoggerConfigurer.getLoggerConfig(name).mapError(_ => Error.Internal()).flatMap {
case Some(r) => ZIO.succeed(ApiDomain.LoggerConfig.from(r))
case _ => ZIO.fail(Error.NotFound())
}
}
}

def setLoggerConfigs(rootPath: Seq[String] = Seq.empty): Routes[LoggerConfigurer, Error.Internal, None] =
def setLoggerConfigs(rootPath: Seq[String] = Seq.empty): Route[LoggerConfigurer, Nothing] =
ApiEndpoints
.setLoggerConfig(rootPath)
.implement { case (name, logLevel) =>
LoggerConfigurer
.setLoggerConfig(name, logLevel)
.map(ApiDomain.LoggerConfig.from)
.mapError(_ => Error.Internal())
.implement {
Handler.fromFunctionZIO[(String, LogLevel)] { case (name, logLevel) =>
LoggerConfigurer
.setLoggerConfig(name, logLevel)
.map(ApiDomain.LoggerConfig.from)
.mapError(_ => Error.Internal())
}
}

def routes(rootPath: Seq[String] = Seq.empty): Routes[LoggerConfigurer, ApiDomain.Error, None] =
getLoggerConfigs(rootPath) ++ getLoggerConfig(rootPath) ++ setLoggerConfigs(rootPath)
def routes(rootPath: Seq[String] = Seq.empty): Routes[LoggerConfigurer, Nothing] =
Routes(getLoggerConfigs(rootPath), getLoggerConfig(rootPath), setLoggerConfigs(rootPath))
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
*/
package zio.logging.example

import zio.http.HttpAppMiddleware.basicAuth
import zio.http._
import zio.logging.api.http.ApiHandlers
import zio.logging.{
Expand Down Expand Up @@ -86,8 +85,8 @@ object ConfigurableLoggerApp extends ZIOAppDefault {
_ <- ZIO.logDebug("Done") @@ LogAnnotation.TraceId(traceId)
} yield ()

val httpApp: Http[LoggerConfigurer, Response, Request, Response] =
ApiHandlers.routes("example" :: Nil).toApp[LoggerConfigurer] @@ basicAuth("admin", "admin")
val httpApp: HttpApp[LoggerConfigurer] =
ApiHandlers.routes("example" :: Nil).toHttpApp @@ Middleware.basicAuth("admin", "admin")

override def run: ZIO[Scope, Any, ExitCode] =
(for {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,13 @@ object ApiEndpointsSpec extends ZIOSpecDefault {
def spec: Spec[Environment with TestEnvironment with Scope, Any] = suite("ApiEndpointsSpec")(
test("rootPathCodec") {
def testRootPathCodec(rootPath: Seq[String], expected: PathCodec[Unit]) =
assertTrue(ApiEndpoints.rootPathCodec(rootPath).encodeRequest(()).url == expected.encodeRequest(()).url)
assertTrue(
ApiEndpoints.rootPathCodec(rootPath).encode(()).getOrElse(zio.http.Path.empty) == expected
.encode(())
.getOrElse(zio.http.Path.empty)
)

testRootPathCodec(Nil, HttpCodec.empty) && testRootPathCodec(
testRootPathCodec(Nil, PathCodec.empty) && testRootPathCodec(
"example" :: Nil,
literal("example")
) && testRootPathCodec("v1" :: "example" :: Nil, literal("v1") / literal("example"))
Expand All @@ -21,7 +25,9 @@ object ApiEndpointsSpec extends ZIOSpecDefault {

def testPath(rootPath: Seq[String], expected: PathCodec[Unit]) =
assertTrue(
ApiEndpoints.getLoggerConfigs(rootPath).input.encodeRequest(()).url == expected.encodeRequest(()).url
ApiEndpoints.getLoggerConfigs(rootPath).input.encodeRequest(()).path == expected
.encode(())
.getOrElse(zio.http.Path.empty)
)

testPath(Nil, literal("logger")) && testPath(
Expand All @@ -33,9 +39,9 @@ object ApiEndpointsSpec extends ZIOSpecDefault {

def testPath(rootPath: Seq[String], expected: PathCodec[Unit]) =
assertTrue(
ApiEndpoints.getLoggerConfig(rootPath).input.encodeRequest("my-logger").url == expected
.encodeRequest(())
.url
ApiEndpoints.getLoggerConfig(rootPath).input.encodeRequest("my-logger").path == expected
.encode(())
.getOrElse(zio.http.Path.empty)
)

testPath(Nil, literal("logger") / literal("my-logger")) && testPath(
Expand All @@ -51,9 +57,9 @@ object ApiEndpointsSpec extends ZIOSpecDefault {
.setLoggerConfig(rootPath)
.input
.encodeRequest(("my-logger", LogLevel.Info))
.url == expected
.encodeRequest(())
.url
.path == expected
.encode(())
.getOrElse(zio.http.Path.empty)
)

testPath(Nil, literal("logger") / literal("my-logger")) && testPath(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ object ApiHandlersSpec extends ZIOSpecDefault {

for {
request <- ZIO.attempt(Request.get(URL.decode("/example/logger").toOption.get))
response <- routes.toApp.runZIO(request)
response <- routes.toHttpApp.runZIO(request)
content <- HttpCodec.content[List[ApiDomain.LoggerConfig]].decodeResponse(response)
} yield assertTrue(response.status.isSuccess) && assertTrue(
content == List(ApiDomain.LoggerConfig("root", LogLevel.Info))
Expand All @@ -42,7 +42,7 @@ object ApiHandlersSpec extends ZIOSpecDefault {
val routes = ApiHandlers.routes("example" :: Nil)
for {
request <- ZIO.attempt(Request.get(URL.decode("/example/logger/example.Service").toOption.get))
response <- routes.toApp.runZIO(request)
response <- routes.toHttpApp.runZIO(request)
content <- HttpCodec.content[ApiDomain.LoggerConfig].decodeResponse(response)
} yield assertTrue(response.status.isSuccess) && assertTrue(
content == ApiDomain.LoggerConfig("example.Service", LogLevel.Info)
Expand All @@ -55,11 +55,11 @@ object ApiHandlersSpec extends ZIOSpecDefault {
request <- ZIO.attempt(
Request
.put(
HttpCodec.content[LogLevel].encodeRequest(LogLevel.Warning).body,
URL.decode("/example/logger/example.Service").toOption.get
URL.decode("/example/logger/example.Service").toOption.get,
HttpCodec.content[LogLevel].encodeRequest(LogLevel.Warning).body
)
)
response <- routes.toApp.runZIO(request)
response <- routes.toHttpApp.runZIO(request)
content <- HttpCodec.content[ApiDomain.LoggerConfig].decodeResponse(response)
} yield assertTrue(response.status.isSuccess) && assertTrue(
content == ApiDomain.LoggerConfig("example.Service", LogLevel.Warning)
Expand Down
2 changes: 1 addition & 1 deletion project/Versions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ object Versions {
val zioConfig = "4.0.0-RC16"
val zioParser = "0.1.9"
val zioPrelude = "1.0.0-RC19"
val zioHttp = "3.0.0-RC2"
val zioHttp = "3.0.0-RC4"
val log4jVersion = "2.19.0"
}

0 comments on commit ffd04ab

Please sign in to comment.