
"The request for its API val request = Request[IO](Method.POST, uri"/jobs")val api = new AsyncJobApi // this will not compile since AsyncJobApi is not defined yet Minimal implementation to make it green: class AsyncJobApi Red test: The API should return a 202 Accepted response: "POST /jobs returns Accepted" in { val request = Request[IO](Method.POST, uri"/jobs") val api = new AsyncJobApi api.routes.orNotFound.run(request).asserting : response => response.status shouldBe Status.Accepted} Make it green: class AsyncJobApi { val routes: HttpRoutes[IO] = HttpRoutes.of[IO] : case req @ POST -> Root / "jobs" => Accepted()} 5.2 Add headers (Trivial Implementation) Red test: add X-Total-Count and Location headers with job ID (only the assertion is shown)"
"val jobId = UUID.fromString("48bf7b76-00aa-4583-b8d6-d63c1830696f")response.status shouldBe Status.Acceptedresponse.headers.get(ci"X-Total-Count").map(_.head.value) shouldBe Some("42")response.headers.get(ci"Location").map(_.head.value) shouldBe Some(s"/jobs/$jobId") Make the test green. Trivial implementation: case req @ POST -> Root / "jobs" => for resp <- Accepted() yield resp.headers.put( Header.Raw(ci"X-Total-Count", "42"), Location(uri"/jobs/48bf7b76-00aa-4583-b8d6-d63c1830696f") ) Refactor: remove duplication by using the standard library to extract Headers. The Location header from http4s is a standard library class: object Location { // ... implicit val headerInstance: Header[Location, Header.Single] = Header.create( ci"Location", _.uri.toString, parse, )}final case class Location(uri: Uri) This gives us the advantage of type-safe header extraction: response.headers.get[Location].map(_.uri) shouldBe (uri"/jobs" / jobId).some"
An AsyncJobApi class implements an HTTP POST /jobs endpoint that initially returns a 202 Accepted response. The minimal routes match POST /jobs and respond with Accepted. Tests require adding a Location header containing a job UUID and an X-Total-Count header with value 42. The http4s library exposes a typed Location header class for safe extraction of Uri values. A custom header definition is required to represent and extract X-Total-Count in a type-safe manner. Responses can be constructed by adding Header.Raw or typed header instances to the response.headers.
Read at Medium
Unable to calculate read time
Collection
[
|
...
]