https://kotlinlang.org logo
Join Slack
Powered by
# http4k
  • c

    Cies

    06/02/2025, 2:53 PM
    I want to deserialize a form submission from a
    www-form-urlencoded
    POST body received by a http4k server to a
    data class
    , preferably with
    kotlinx.serialization
    . I've done this before (when not using http4k) with Jackson, using quite some self written code, to (1) create a little language for adding structure to the form's
    name
    values (this allowed me to have nested data structures, and list/arrays, like
    .user.permissions[5]
    ) and to parse the data directly to Jackson's internal JSON representation (in order to skip a JSON format step: Jackson was mainly used for it's "type coercion" since all values are received in one big
    www-form-urlencoded
    string). Is there anything in http4k to make this easier? I've seen the body lens feature, but I have not been able to use it for form submissions.
    d
    • 2
    • 2
  • a

    andyg

    06/09/2025, 2:50 AM
    Saw these errors in my logs today - what is PROPFIND? Well it appears to be an obscure HTTP verb for getting info from a WebDav server. In other words, these requests are most likely hackers poking around. I could catch the IllegalArgumentException however this is likely to be universal - I think it would be preferable for http4k to return a 501 or 404 (without raising an error) if it doesn't recognize the HTTP method. Thoughts?
    d
    • 2
    • 2
  • c

    Cies

    06/10/2025, 11:37 PM
    Small demo. I created a small SSR web application PoC for using http4k with Supabase and Jdbi. It uses Supabase's authentication (JWT+refresh token), stored in cookies (so they can effectively be used in an SSR setup. I've decided to only use RLS for the reads (all writes are supposed to be blocked through RLS for the
    authenticated
    role, you simply need the
    service_role
    for writes); this to keep RLS dead simple and still useful (as an extra safety against data leaks and to allow Supabase goodness like GraphQL and realtime to be used later on). Both JWT-from-cookie and db-connection-with-supabase-auth are implemented as http4k `Filter`s. The idea is: start SSR, because it is just waaay simpler, then add little browser apps on top later where it adds maximum value (and for that Supabase is really nice with GraphQL and realtime). It used kotlinx.html for template rendering (with a layouting system) and Konform for FormDto validation. Jdbi was chosen as I want to be able to write "just SQL". I might one day convert it to terpal-sql (the basis of ExoQuery) but it did not work out of the box, so I went with time-tested Jdbi. Feel free to AMA, and if you have a look at the code and see any room for improvement: please let me know! I'm really hungry for feedback. https://github.com/cies/supabase-http4k-ssr-jdbi
    d
    • 2
    • 20
  • d

    DanielZ

    06/11/2025, 9:24 AM
    Hey, I'm running into issues while deployment when using
    helidon
    as server. In my service I have multiple calls to upstream services (using
    okhttp
    ). But during deployment in k8s I'm facing that
    helidon
    will kill all running requests (
    Closed by interrupt
    ) even when I sleep first in my shutdown hook. So far I understand
    helidon
    has it's own shutdown hook registered by default. Would be nice to support in addition graceful stopmode to overcome that kind of issue.
    d
    • 2
    • 4
  • c

    Cies

    06/12/2025, 8:40 AM
    Any good suggestions for a light weight (many JWT libs depend on kotlin-reflect and/or jackson!) JWT lib that supports the
    hs256
    algorithm that Supabase uses?
    d
    c
    • 3
    • 5
  • c

    Cies

    06/12/2025, 8:42 AM
    Or should I just parse it myself (I've learned to lean on established libs when it comes to auth stuff, but decrypting a JSON string cannot be thát hard...)
  • p

    Paul Reijbroek

    06/13/2025, 6:52 PM
    Hello, Because the company I’m working for is looking to do some operations on CloudWatch that are not supported (yet), I’m working on a PR to include a new CloudWatch module for http4k-connect to support some of those operations. I’ve written functionality in particular for alarms, metric data and metric streams (considering these look like the most common use cases and/or are the operations we need to have), but I’m running into a couple of issues for the fake implementations and the tests. Please see 🧵 for a list of the issues I’m running into. What would be a good approach for them?
    j
    d
    • 3
    • 10
  • d

    DanielZ

    06/13/2025, 8:23 PM
    Hi, I'm struggling using http4k-connect. I try to use S3 with an ARN role based authentication but failing with a lens error of a missing AWS_ACCESS_KEY_ID. Wondering where I miss something?
    Copy code
    const val USE_REAL_CLIENT = false
    fun main() {
        val env = Environment.defaults(
            AWS_REGION of Region.EU_WEST_1,
            AWS_ROLE_ARN of ARN.of("arn:aws:sts:us-east-1:000000000001:role:myrole")
        )
        val http: HttpHandler = if (USE_REAL_CLIENT) JavaHttpClient() else FakeS3().debug()
        val credentialsProvider = CredentialsProvider.STS(env, FakeSTS().debug())
        val s3 = S3.Http(credentialsProvider = credentialsProvider, http)
    
        val sourceName = BucketName.of("source-bucket")
        val targetName = BucketName.of("target-bucket")
        s3.createBucket(sourceName, env[AWS_REGION]).recover(RemoteFailure::throwIt) // <<< fails here: env 'AWS_ACCESS_KEY_ID' is required
        s3.createBucket(targetName, env[AWS_REGION]).recover(RemoteFailure::throwIt)
    
        val source = S3Bucket.Http(sourceName, env[AWS_REGION], credentialsProvider, http)
        source.putObject(BucketKey.of("hello"), "hello ".byteInputStream()).recover(RemoteFailure::throwIt)
    
        val target = S3Bucket.Http(targetName, env[AWS_REGION], credentialsProvider, http)
        target.copyObject(source.bucketName, BucketKey.of("hello"), BucketKey.of("copy"))
            .recover(RemoteFailure::throwIt)
    }
    d
    a
    • 3
    • 6
  • t

    Tudor Luca

    06/14/2025, 7:14 PM
    Stupid question incoming: if http4k is a pure kotlin framework, why doesn’t it support kotlin/native or js/wasm as targets? Context: I’m looking into enabling our experienced mobile devs to reach and contribute to “the server”. We’re already supporting both Android & iOS platforms with a KMP shared module for business logic, networking & sqlite, so we’re experimenting what’s the smoothest path to enable feature contributions to the server too. We’re using the Ktor client on mobile, but I always had a soft spot for arrow & sane fp patterns so I’m seriously looking at http4k, ktor or smth full-blown like Quarkus. Our current server stack is dotnet-core, don’t ask why 😅.
    d
    • 2
    • 2
  • d

    dave

    06/18/2025, 12:27 PM
    👋 Happy Wednesday to all you http4k fans! We've got some news about what we've been cooking up at http4k towers... https://http4k.org/news/ai_without_tests_is_just_expensive_random_number_generation/
    http4k 2
  • d

    dave

    06/20/2025, 9:10 PM
    For those of you that didn't catch the livestream at KotlinConf, @s4nchez's great talk about http4k's support fo Streaming Protocols (and a history of the web browser) is now available:

    https://www.youtube.com/watch?v=vewgb-vyJME▾

    (as a bonus: @dmcg and @Dmitry Kandalov’s refactoring talk is also amazing 🙂

    https://www.youtube.com/watch?v=SwNTpgp262o▾

    )
    http4k 4
    K 3
    d
    • 2
    • 1
  • l

    leonhardt

    06/30/2025, 4:02 AM
    Can the
    singlePageApp
    helper be used on a subpath? When it's configured on the root path, it works as expected. But when it's configured on a subpath, it still seems to match any path, even ones outside the subpath.
    d
    s
    • 3
    • 9
  • m

    Marco Garofalo

    06/30/2025, 3:42 PM
    Hi, I am trying to understand whether the oauth module does provide a way to fetch the authenticated user information somehow (e.g.
    <http://whatever/me>
    ) or propagate the token down the handlers chain/stack once the authFilter is satisfied.
    s
    • 2
    • 2
  • l

    leonhardt

    07/12/2025, 5:38 PM
    Hey @s4nchez! Thanks to its mention on the approval testing docs page my team has been using
    org.http4k:http4k-testing-approval
    in conjunction with your Okey-doke plugin for a couple months now. The tool + plugin has definitely a huge improvement over renaming the generated files manually, but now that we've been living with the process for a while a few DX issues have surfaced: 1. It's hard to know if the keyboard shortcut (Ctrl + F11) worked. You have to have the cursor focused in the right place. Precise placement in the editor on the test or in the project viewer on the file both work, but (perhaps unintuitively) the test execution's run window/console does not work. And there's no visual indication if it worked, beyond navigating to the file in the project viewer. As a result I've noticed we just hit Ctrl + F11 obsessively in every window "just to make sure." 2. When we rename tests, the generated approval files get abandoned. We often don't notice initially, and only after some time notice when there's many more approval files than tests. The process to clean up the clutter is tricky. We usually make sure all our tests are passing, commit, delete all the approval files, rerun tests, approve all the approval files, and commit again. But this is a little error-prone and tedious. When we only had 1-20 tests, these weren't big issues. But now that we're in the 100s it's painful enough issue we're looking to address it. Thought we'd check with the community here. Can anybody recommend any better ways to work with
    org.http4k:http4k-testing-approval
    that we might have missed?
    d
    s
    • 3
    • 6
  • t

    ted

    07/28/2025, 11:29 AM
    Hello, planning to fetch items from dynamodb using http4k-connect. I’m wondering if there will be an issue if we fetch too many items e.g. is there a maximum chunk size? Will also have a look at the code later today, thanks! 🙂
    a
    • 2
    • 2
  • c

    Cies Breijs

    08/07/2025, 3:42 AM
    The previous framework that I used had some authorization by annotation feature. The permissions were represented with a list of an enum, and passed with a vararg to the annotation:
    Copy code
    @RequiredPermissions(Perm.SEE_GOD, Perm.HEAR_GOD, Perm.FEEL_LOVE) // or: @RequiresNoPermissions
    fun ultimateExperienceGetHandler(req: Request): Resposne { /* ... */ }
    The were serialized to the db's
    user_permissions
    table (with columns: userId, permEnum). Kind of worked well. I liked that all handlers required such annotation (created some test for that in the test suite). It feels like in http4k the best place to implement this is simply in the handler body. Functional. No annofuzz... (But please correct me if I'm wrong about this)
    Copy code
    fun ultimateExperienceGetHandler(req: Request): Resposne {
      if (!currentUserCtx(req).permissions.contains(Perm.SEE_GOD)) return Response(FORBIDDEN)
      // ...
    }
    But there's one thing I miss: the "closed by default" that I had with the annotations. So I wondered, would it be possible to have some sort of "closed by default" back by somehow specifying them in the router... Then:
    Copy code
    val portalRouter = routes(
      Paths.dashboard bind GET to ::dashboardGetHandler,
      Paths.profileEdit bind POST to ::profilePostHandler,
      Paths.profileEdit bind GET to ::profileGetHandler,
      Paths.retailerList bind GET to ::retailerListGetHandler,
      Paths.retailerView bind GET to ::retailerViewGetHandler,
      // ...
    )
    Would become something like:
    Copy code
    val portalRouter = authorizedRoutes(
      Triple(Paths.dashboard, GET to ::dashboardGetHandler, listOf(Perm.SEE_DASHBOARD)),
      Triple(Paths.profileEdit, POST to ::profilePostHandler, listOf(Perm.MODIFY_MY_PROFILE)),
      Triple(Paths.profileEdit, GET to ::profileGetHandler, listOf(Perm.MODIFY_MY_PROFILE)),
      // ...
    )
    Or even methods on the UserPermissions object like:
    Copy code
    val portalRouter = authorizedRoutes(
      Triple(Paths.dashboard, GET to ::dashboardGetHandler, listOf(::seeDashboard)),
      Triple(Paths.profileEdit, POST to ::profilePostHandler, listOf(::modifyMyProfile)),
      Triple(Paths.profileEdit, GET to ::profileGetHandler, listOf(::userHasOrganizationWithTypeX)), // <--
      // ...
    )
    Maybe my question is: how are y'all implementing authorization? (give that i need a very simple scheme for the foreseeable future)
    m
    a
    • 3
    • 8
  • c

    Cies Breijs

    08/08/2025, 10:29 AM
    I'm using the generate function from
    UriTemplate
    to build paths in a slightly more typesafe way. When looking at it's implementation I kind of wish for there to be a version of this function that throws an error if not all parameters are filled. Like
    generateOrThrow
    . This may help in some cases where you forget to pass a parameter (and I cannot forsee any situation where you do not want a parameter filled in). Am I on to something, or is this is stupid idea? Here the original function:
    s
    • 2
    • 3
  • s

    Slackbot

    08/14/2025, 2:10 PM
    This message was deleted.
    j
    s
    • 3
    • 2
  • m

    Marco Garofalo

    08/22/2025, 11:12 AM
    Hi, when using OAuthProvider is there a way to configure it so that the filter validates the (previously) "persisted" token? (e.g. token received from a secure cookie) From what I can see it just seems to check whether there is a non-null token, then is happy to continue the filter chain, what am I missing?
    d
    • 2
    • 3
  • a

    Andrew O'Hara

    09/03/2025, 5:09 PM
    Happy to see the maven central upgrade is finally complete! 🥳 Except I don't see one of my changes in the latest release, even though it's still present on master. Was the latest release not for master/HEAD? UPDATE: The MC upgrade isn't finished after all. This was just an "older" release that went out.
    🎉 1
    d
    l
    • 3
    • 12
  • a

    Alessandro Ciccimarra

    09/08/2025, 8:10 PM
    Hello team! 🙂 Looking at
    JavaHttpClient
    , some
    IOExceptions
    are caught (
    UnknownHostException
    ,
    ConnectException
    ,
    HttpTimeoutException
    ). Other exceptions, for example a
    SocketException
    caused by a connection reset, need to be handled at call site. What’s the reason for that?
    d
    • 2
    • 5
  • a

    almeydajuan

    09/09/2025, 2:05 PM
    Hello all, it seems that the tooling under https://toolbox.http4k.org/ is not working. Anything that I try(f.e. https://toolbox.http4k.org/dataclass), I get redirected to a 404
    d
    • 2
    • 5
  • a

    almeydajuan

    09/10/2025, 7:03 AM
    Good morning, I have a question about a behaviour in the security framework. I did not find so intuitive. We are working with
    BearerAuthSecurity
    . I have 2 example implementations:
    Copy code
    class Lookup(lookup: (String) -> String?) : Security by BearerAuthSecurity({ lookup(it) != null }), TokenSecurity
    class WithKey(lookup: (String) -> String?) :
        Security by BearerAuthSecurity(key = Header.required("Authorization"), lookup = { lookup(it) }), TokenSecurity
    Then if I do:
    Copy code
    val http1: HttpHandler = newBackend(tokenSecurity = WithKey { "hello" })
    val http2: HttpHandler = newBackend(tokenSecurity = Lookup { "hello" })
    
    Request(GET, "/hello").header("Authorization", "Bearer 123").use(http1)
    Request(GET, "/hello").header("Authorization", "Bearer 123").use(http2)
    The backend which uses security in with only
    lookup
    receives the bearer header, but the in the call to the 2nd backend (with the required header)
    Authorization
    headers is overriden and I get
    Authorization hello
    instead of
    Authorization Bearer 123
    For me it is unintuitive because we are using the same
    BearerAuthSecurity
    but depending on which parameter we pass, the request that arrives to our system comes already modified. Is this how this should behave? If so, what is the rational behind it? cc: @Michal Wachowski
    d
    m
    • 3
    • 4
  • m

    Mikael Ståldal

    09/11/2025, 6:50 PM
    Is there any support for dealing with Structured Field Values in http4k?
    a
    • 2
    • 2
  • a

    Andrew O'Hara

    09/14/2025, 12:17 AM
    Warning: the latest http4k artifacts now require all the optional dependencies. Bug logged. https://github.com/http4k/http4k/issues/1417 Update: Fixed! Upgrade to 4.18.0.1
    d
    • 2
    • 1
  • c

    Cies Breijs

    09/22/2025, 1:58 PM
    I'm now working with http4k for a couple of weeks. The app is shaping up nicely. And http4k has been an absolute joy to work with! A big thank you to all involved inr open sourcing this. I use it together with terpal-sql and kotlinx.html, to build an SSR app on top of Supabase (which is clearly not Supabase's design goal, but still works nicely). I want to share a few details and questions that i have (casual sharing, no urgent needs/dramas).
    🔥 2
    a
    d
    • 3
    • 33
  • d

    dave

    10/01/2025, 2:01 PM
    Hey http4k fans! We didn't ever really get around to telling you here about the new modules that we've recently introduced to http4k since the switch to Maven Central over the summer. A couple of highlights if you're upgrading from versions <= 6.15.1.0 to the newest shiny v6.18.1.0: • New module: http4k-testing-powerassert - Power Assert is now bundled with Kotlin, so it’s the perfect assertions library to use • New module: http4k-template-htmlflow - typesafe HTML builders in code • New module: http4k-connect-amazon-route53 - Basic hosted zone and record set management • http4k-web-datastar - D* was update to V1 recently and we've kept up with the quite reasonaly significant changes to the library since the betas were released. • http4k-format-dataframe - New v1 version of the Kotlin DF library • http4k-client-okhttp - Update to v5 of OkHttp - which takes advantages of java's Virtual threads and has support http4k-ai-mcp-sdk: We have consolidated all of the MCP modules into the http4k AI ecosystemfor GraalVM built in • http4k-connect-amazon-cognito: Better support for various auth challenge modes • http4k-core: Support for lenses and content negoriation, and accept-like headers • Misc: Upgrades to Kotlin 2.2.20 • Misc: Fixed a gnarly bug with SPA routes to improve support for SPAs hosted at non-route paths You can see the full changelog here: https://www.http4k.org/ecosystem/changelog/ Things on the radar: • There is a new version of OpenAPI (3.2.0), which adds a fair amount of new features including SSE event schemas: https://spec.openapis.org/oas/v3.2.0.html • Jackson v3 is on the horizon: https://github.com/FasterXML/jackson/wiki/Jackson-Release-3.0 so expect eventual changes to http4k-format-jackson, and maybe we'll get around to the rewrite of the http4k-api-openapi module
    http4k 4
    💪 1
    🎉 1
    a
    c
    • 3
    • 4
  • r

    Rafael Diaz

    10/05/2025, 12:59 AM
    Hi all. I'm currently trying to declare a list of type
    List<ContractRoute>
    . However, I'm ending up with the type
    List<Pair<ContractRouteSpec2<Int, String>.Binder, (Request) -> Response>>
    when I add lenses to the route path. I want to add the list of routes to an api contract, which accepts the former type but not the latter, so I was wondering how I could fix it. More details inside: Edit: Found the solution. https://stackoverflow.com/questions/53278208/how-do-you-model-a-path-parameter-in-the-middle-with-http4k
    d
    • 2
    • 4
  • r

    Rafael Diaz

    10/05/2025, 5:36 AM
    Another question, this time regarding OpenAPI V3 and Swagger integration.
    m
    d
    • 3
    • 4
  • a

    Andrew O'Hara

    10/07/2025, 1:43 AM
    Is there any consensus on the most effective way to perform SSR testing nowadays? • approval tests verify the exact outputted HTML, but can't test form submissions • webdriver tests are slower, more finicky, flakey, but can test form submissions Is the answer a bit of both?
    s
    c
    • 3
    • 2