Hey everyone, I started working with http4k recent...
# http4k
a
Hey everyone, I started working with http4k recently, and I noticed there's no way to chain contracts together like you can with regular routes. With regular routes I could do something like
Copy code
class A {
   fun getHandler(): RoutingHttpHandler {.....}
}

fun main() {
    val app = routes(
        "/A" bind A.getHandler()
}
In looking to replicate that with contracts, I found you can't really. Looking into making a contribution to the codebase, how would you guys want that to look? I can PR the repo fairly easily with my first thought which was a
withRoutesFrom
method that would look like
Copy code
class A {
    fun getHandler(): ContractRoutingHandler {...}
}

fun main() {
    val app = contract {...}.withRoutesFrom("/A" bind A.getHandler(), "/B" bind B.getHandler()...
}
Is this something interesting, or is there another solution you guys have had in mind that would be preferred? Maybe I can tackle it
d
The contract is just a routing http handler, and hence you can just compose them into any other routes block. The semantics are slightly different when it comes to filter handling - for that you should know how filters are applied in routing http handlers Vs standard http handlers (in the former they are applied after matching by default).
But overall if you explain the route structure you want then we can probably help you to get there .
a
My thought process is I'd have a bunch of classes that expose something, either a list of ContractRoutes, or ContractRoutingHttpHandler, and then in the final app composition, I could preface the exposed item with a name, similar to how I have it in the first example. The problem I noticed was if I expose a
List<ContractRoutes>
, I can't
"/prefix" bind
them. I'd have to manually write out something like
Copy code
contract {
    routes.plusAssign(A.getRoutes())
    routes.plusAssing(B.getRoutes())
    ...
}
And in the routes themselves, I'd have to put the prefix every time. A minor grievance, but one that's not present in non-contract routing, and would be alleviated if I could somehow reference the actual routes from a contract. If I expose a
ContractRoutingHttpHandler
I can't compose them without losing the OpenAPI spec since
routes("prefix" bind ContractRoutingHttpHandler)
strips the spec off, and I can't just do
Copy code
contract {
    routes.plusAssign(("/prefix" bind someOtherContract).routes)
}
Since the route object is private
d
Could you longer form that slightly into a gist? Even if it doesnt compile? 🙃
a
No problem, sorry for my poor wording 🙂 https://gist.github.com/albertcabello/3f042d81ef6d10950db8e6e392fae681
Googling around before I came up with this led me to [this thread](https://kotlinlang.slack.com/archives/C5AL3AKUY/p1555993080080100). Seems the solution then was to iterate over a list of routes and
plusAssign
them all, I was just hoping to get something nicer and more inline with how it is with non-contract routes
d
It's not especially your wording - its that it's easier for people to play with when it's already code. 🙃 . The contract stuff is a bit limited right now- it will be reworked at some point when we get the inspiration.
a
It's not especially your wording - its that it's easier for people to play with when it's already code.
That's true!
when we get the inspiration
Totally get it, I figured I'd ask if the proposed
withRoutesFrom
was something you'd be interested in before I put in a PR for it