Inspired by one of <@U01V2S2HGRK>'s <recent videos...
# http4k
l
Inspired by one of @Andrew O'Hara's recent videos, I'm exploring the
http4k-api-openapi
module. When using a path lens, I've got a route working when the lens is at the end of a route, but I'm stuck on how to place one in the middle of a route. Any tips?
❤️ 1
Here's an example.
Copy code
import org.http4k.contract.contract
import org.http4k.contract.div
import org.http4k.contract.meta
import org.http4k.core.Method
import org.http4k.core.Response
import org.http4k.core.Status
import org.http4k.lens.Path
import org.http4k.lens.uuid
import org.http4k.routing.RoutingHttpHandler

val productIdPathLens = Path.uuid().of("productId")

fun createRoutes(): RoutingHttpHandler = contract {

  // ✅ this route compiles
  routes += "/v1/products" / productIdPathLens meta {
    // ...
  } bindContract Method.GET to { productId ->
    { request ->
      // ...
      Response(Status.OK)
    }
  }

  // ❌ this route does not compile
  routes += "/v1/products" / productIdPathLens / "status" meta {
    // ...
  } bindContract Method.POST to { productId ->
    { request ->
      // ...
      Response(Status.OK)
    }
  }
}
d
The reason is that the lens system does not know that the last of the fragments is "fixed". To fix this you need to add another arg to the receiving function, so
{ productId, _ -> }
so "status" in this case is a lens - just one that only matches "status"
🍻 1
🎉 1
a
I wish I had covered this case in the video. But the cats API just isn't complicated enough to warrant a route like this. 😅
❤️ 1
😸 1
l
I forgot to reply earlier. Thanks for the help @dave! That was exactly it. Since then, I've been thinking about how the API here wasn't intuitive in this case. It's simple enough once you know it, but was hard to discover (at least for me). An extra example in the docs might've helped, but I also keep wondering whether the API itself could be more intuitive. Maybe all the path segments (fixed or from lens) could be passed into an outer lambda, including the first. It would be more verbose for cases where you don't need a path variable, but at least it would be explicit and consistent. Any thoughts?
d
The entire API does need a revamp really if we're going to break stuff. It was quite an early addition and I'd prefer to concentrate on doing something like the TypedRequest https://github.com/http4k/http4k/blob/90a5fbee69a6593ebbaa1396e48e41352fa676e5/core/incubator/src/test/kotlin/org/http4k/lens/TypedHttpMessageTest.kt
amaze 1
l
I've never noticed your incubator package before! I just browsed it a little, very cool. A more fully typed HTTP message could be really beneficial. Current-state http4k is already fantastic, but there's still a bit of boilerplate I end up needing in handlers that I wish could be pushed down into the lens/serialization layer. This concept looks like it could help with that. And yeah, totally makes sense that exploring an incremental change (like what I suggested) might not be the right move if something like this is already in the works. Thanks for hearing me out and sharing the context!