https://kotlinlang.org logo
#http4k
Title
# http4k
d

dave

09/14/2020, 12:36 PM
Which reminds me, we've just added a repo of self contained example projects which showcase the various features of http4k. If there's anything you'd like to see then please let us know! https://github.com/http4k/examples
m

Mehdi

09/14/2020, 12:37 PM
so it similar to Query though, thanks @dave
🙂
m

Mehdi

09/14/2020, 12:40 PM
Another question since I am using swagger ui How can I force swagger to get my customised header value and pass it to my API as a header value again?
d

dave

09/14/2020, 12:41 PM
the header will be available on the incoming request - see that example to see how it works
path parameters are extracted and passed to the function which creates the handler
m

Mehdi

09/14/2020, 12:42 PM
I have bundled swagger ui in my project and pointed it into /my api/docs/swagger.json I want swagger to pass my header as well, so could I expect this from swagger?
Copy code
routes += "/foo" meta {
    summary = "my summary"
    description = "my desc"
    headers += Header.string().required("auth_token")
    receiving(myLens to MyDTO())
}
d

dave

09/14/2020, 12:46 PM
do you want to add a Security instead of a header?
m

Mehdi

09/14/2020, 12:47 PM
yes I wanted to do that but for my case security is customised and I need to send auth_token as header value, I did not understand how to do it
could I do it using ApiKeySecurity?
d

dave

09/14/2020, 12:49 PM
I think you want to use an ApiKeySecurity with that Header lense passed to the constructor: https://swagger.io/docs/specification/authentication/
m

Mehdi

09/14/2020, 12:57 PM
yes exactly, this is what I was looking for
Thanks
Another question: What if I want to do Authentication with oauth service provider same as keyCloak?
d

dave

09/14/2020, 1:01 PM
If it's standard oauth then it's built in, although we don't have a ready-made config for keycloak. There is an example of setting up the client config here: https://github.com/http4k/http4k-by-example/blob/master/src/main/kotlin/verysecuresystems/SecuritySystem.kt
m

Mehdi

09/14/2020, 1:04 PM
Perfect I am falling in love with http4k
😀 1
@dave how can I pass multiple headers params in ApiKeySecurity?
d

dave

09/14/2020, 1:47 PM
you can only do one header per ApiKeySecurity
you can compose the security instances with "this.and(that)"
m

Mehdi

09/14/2020, 1:50 PM
but I can not combine two ApiKeySecurity right?
d

dave

09/14/2020, 1:50 PM
you can
I'm not sure what the UI will do TBH
m

Mehdi

09/14/2020, 1:52 PM
UI shows the second one only
d

dave

09/14/2020, 1:52 PM
you need to override the "name" for one of them
Copy code
class ApiKeySecurity<out T>(val param: Lens<Request, T>,
                            validateKey: (T) -> Boolean,
                            authorizeOptionsRequests: Boolean = true,
                            val name: String = "api_key") : Security {
👌 1
m

Mehdi

09/14/2020, 2:37 PM
This one fixed the UI but I do not know why it is not appending the second header
actually the second header for my case should be
origin
d

dave

09/14/2020, 2:43 PM
if works for me in my example of:
Copy code
security = ApiKeySecurity(Header.required("foobar2"), { true}, true, name="bob2").and(ApiKeySecurity(Header.required("foobar"), { true}, true, name="bob"))
you can see what it sends in the curl
Copy code
curl -X GET "<http://localhost:9000/api/whoIsThere>" -H "accept: application/json" -H "foobar2: asd" -H "foobar: dsa"
m

Mehdi

09/14/2020, 2:59 PM
I am trying to send it using swagger UI, I can see two authorise button in the UI because of the two fields
Ah I got it
as the second header name is `origin`as I mentioned and it is being overwritten somewhere
d

dave

09/14/2020, 3:05 PM
cool. FYI: once you "execute" the swagger request, it shows the request that was sent as a curl. so you can see that it was doing the correct thing 🙂
👌 1
m

Mehdi

09/14/2020, 5:19 PM
How can I exclude some urls for the security? let say I want to exclude /ping
d

dave

09/14/2020, 5:25 PM
Override the security for the route with NoSecurity
🙏 1
m

Mehdi

09/15/2020, 11:13 AM
Copy code
fun getMyRoute(): ContractRoute {
    val spec = "foo" / Path.of("name1") /  Path.of(name2) /"bar1" / "bar2" meta {
        summary = "summary"
        description = "description"
    } bindContract Method.PUT
    return spec to { s: String, s1: String, s2: String, s3: String -> ::myhandler() }
}
I do not get why I need to write spec to httpHandler like this to work.
d

dave

09/15/2020, 11:15 AM
short answer - the kotlin type system isn't good enough
🙂
it's because of the way the lenses work
m

Mehdi

09/15/2020, 12:13 PM
yes I guessed that, so I was wondering how does your samples work in the documents?
d

dave

09/15/2020, 12:34 PM
it should all be consistent. can you show me if it's not pls?
m

Mehdi

09/15/2020, 1:15 PM
It does not work on my case, the sample should be consistent
d

dave

09/15/2020, 1:16 PM
so when you've got a suffix, you always end up with a "dead" parameter. This is unavoidable because of how the API works. the value injected into the lambda is always the value in quotes.
for leading parameters, this is not the case
(because it just concatenates the prefix)
but once you have a dynamic parameter, we are forced to split it
m

Mehdi

09/15/2020, 2:42 PM
yes I experienced exactly the same thing
d

dave

09/15/2020, 2:43 PM
then it's working as expected 🙂
2 Views