Skip to content

v3.0.0-RC10

Compare
Choose a tag to compare
@987Nabil 987Nabil released this 30 Aug 22:24
· 71 commits to main since this release
16e2e2f

Breaking changes

Query Codec

QueryCodec is now Schema based. Therefore calls that would before look like HttpCodec.queryInt or HttpCodec.queryTo[Int] become HttpCodec.query[Int]. (See the docs for more details)
This also enables using a case class to extract multiple parameters.

Client

The ZClient got some rework done. Most important is, that there is now an explicit streaming and non-streaming API.
The reason is, that for streaming bodies we depended on Scope for which some users used the default application scope.
To reduce possible errors, we offer now batched requests. They do not need a scope. For the streaming ones, please use for example ZIO.scoped to set boundaries in which the streaming body is available. See the docs for more details.

Replaced Endpoint Middleware with explicit security concept

An example says more then 1000 words.

  private val basicAuthContext = HandlerAspect.customAuthProviding[AuthContext] { r =>
    {
      r.headers.get(Header.Authorization).flatMap {
        case Header.Authorization.Basic(uname, password) if Secret(uname.reverse) == password =>
          Some(AuthContext(uname))
        case _                                                                                =>
          None
      }

    }
  }
  
    val endpoint = Endpoint(Method.GET / "test").out[String](MediaType.text.`plain`).auth(AuthType.Basic)
    val routes   =
      Routes(
        endpoint.implementHandler(handler((_: Unit) => withContext((ctx: AuthContext) => ctx.value))),
      ) @@ basicAuthContext

    val response = for {
      client <- ZIO.service[Client]
      locator    = EndpointLocator.fromURL(url"http://localhost:8080")
      executor   = EndpointExecutor(client, locator, Header.Authorization.Basic("admin", "admin".reverse))
      invocation = endpoint(())
      response <- ZIO.scoped(executor(invocation))
    } yield response

This endpoint has a clear auth requirement and uses an aspect to extract information from the headers to be provided to the handler.
Note that the providing works on the level of Routes, so multiple routes can request AuthContext and you need to add the aspect only once.

The endpoint client call requires an EndpointExecutor, that can provide the authentication requirement set on the endpoint.
Either via a value like in the example or an effect.

Replaced Warning header and beautifyErrors with more explicit error config

The default way to handover errors has been the warning header so far. That had multiple problems.
Therefore we replaced it with ErrorResponseConfig. Which should be set globally in the application bootstrap via ErrorResponseConfig.configLayer and can be locally overwritten via the handler aspects ErrorResponseConfig.debug or ErrorResponseConfig.withConfig.

What's Changed

New Contributors

Full Changelog: v3.0.0-RC9...v3.0.0-RC10