https://kotlinlang.org logo
Join the conversationJoin Slack
Channels
100daysofcode
100daysofkotlin
100daysofkotlin-2021
advent-of-code
aem
ai
alexa
algeria
algolialibraries
amsterdam
android
android-architecture
android-databinding
android-studio
androidgithubprojects
androidthings
androidx
androidx-xprocessing
anime
anko
announcements
apollo-kotlin
appintro
arabic
argentina
arkenv
arksemdevteam
armenia
arrow
arrow-contributors
arrow-meta
ass
atlanta
atm17
atrium
austin
australia
austria
awesome-kotlin
ballast
bangladesh
barcelona
bayarea
bazel
beepiz-libraries
belgium
berlin
big-data
books
boston
brazil
brikk
budapest
build
build-tools
bulgaria
bydgoszcz
cambodia
canada
carrat
carrat-dev
carrat-feed
chicago
chile
china
chucker
cincinnati-user-group
cli
clikt
cloudfoundry
cn
cobalt
code-coverage
codeforces
codemash-precompiler
codereview
codingame
codingconventions
coimbatore
collaborations
colombia
colorado
communities
competitive-programming
competitivecoding
compiler
compose
compose-android
compose-desktop
compose-hiring
compose-ios
compose-mp
compose-ui-showcase
compose-wear
compose-web
connect-audit-events
corda
cork
coroutines
couchbase
coursera
croatia
cryptography
cscenter-course-2016
cucumber-bdd
cyprus
czech
dagger
data2viz
databinding
datascience
dckotlin
debugging
decompose
decouple
denmark
deprecated
detekt
detekt-hint
dev-core
dfw
docs-revamped
dokka
domain-driven-design
doodle
dsl
dublin
dutch
eap
eclipse
ecuador
edinburgh
education
effective-kotlin
effectivekotlin
emacs
embedded-kotlin
estatik
event21-community-content
events
exposed
failgood
fb-internal-demo
feed
firebase
flow
fluid-libraries
forkhandles
forum
fosdem
fp-in-kotlin
framework-elide
freenode
french
fritz2
fuchsia
functional
funktionale
gamedev
ge-kotlin
general-advice
georgia
geospatial
german-lang
getting-started
github-workflows-kt
glance
godot-kotlin
google-io
gradle
graphic
graphkool
graphql
graphql-kotlin
graviton-browser
greece
grpc
gsoc
gui
hackathons
hacktoberfest
hamburg
hamkrest
helios
helsinki
hexagon
hibernate
hikari-cp
hire-me
hiring
hongkong
hoplite
http4k
hungary
hyderabad
image-processing
india
indonesia
inkremental
intellij
intellij-plugins
intellij-tricks
internships
introduce-yourself
io
ios
iran
israel
istanbulcoders
italian
jackson-kotlin
jadx
japanese
jasync-sql
java-to-kotlin-refactoring
javadevelopers
javafx
javalin
javascript
jdbi
jhipster-kotlin
jobsworldwide
jpa
jshdq
juul-libraries
jvm-ir-backend-feedback
jxadapter
k2-early-adopters
kaal
kafka
kakao
kalasim
kapt
karachi
karg
karlsruhe
kash_shell
kaskade
kbuild
kdbc
kgen-doc-tools
kgraphql
kinta
klaxon
klock
kloudformation
kmdc
kmm-español
kmongo
knbt
knote
koalaql
koans
kobalt
kobweb
kodein
kodex
kohesive
koin
koin-dev
komapper
kondor-json
kong
kontent
kontributors
korau
korean
korge
korim
korio
korlibs
korte
kotest
kotest-contributors
kotless
kotlick
kotlin-asia
kotlin-beam
kotlin-by-example
kotlin-csv
kotlin-data-storage
kotlin-foundation
kotlin-fuel
kotlin-in-action
kotlin-inject
kotlin-latam
kotlin-logging
kotlin-multiplatform-contest
kotlin-mumbai
kotlin-native
kotlin-pakistan
kotlin-plugin
kotlin-pune
kotlin-roadmap
kotlin-samples
kotlin-sap
kotlin-serbia
kotlin-spark
kotlin-szeged
kotlin-website
kotlinacademy
kotlinbot
kotlinconf
kotlindl
kotlinforbeginners
kotlingforbeginners
kotlinlondon
kotlinmad
kotlinprogrammers
kotlinsu
kotlintest
kotlintest-devs
kotlintlv
kotlinultimatechallenge
kotlinx-datetime
kotlinx-files
kotlinx-html
kotrix
kotson
kovenant
kprompt
kraph
krawler
kroto-plus
ksp
ktcc
ktfmt
ktlint
ktor
ktp
kubed
kug-leads
kug-torino
kvision
kweb
lambdaworld_cadiz
lanark
language-evolution
language-proposals
latvia
leakcanary
leedskotlinusergroup
lets-have-fun
libgdx
libkgd
library-development
linkeddata
lithuania
london
losangeles
lottie
love
lychee
macedonia
machinelearningbawas
madrid
malaysia
mathematics
meetkotlin
memes
meta
metro-detroit
mexico
miami
micronaut
minnesota
minutest
mirror
mockk
moko
moldova
monsterpuzzle
montreal
moonbean
morocco
motionlayout
mpapt
mu
multiplatform
mumbai
munich
mvikotlin
mvrx
myndocs-oauth2-server
naming
navigation-architecture-component
nepal
new-mexico
new-zealand
newname
nigeria
nodejs
norway
npm-publish
nyc
oceania
ohio-kotlin-users
oldenburg
oolong
opensource
orbit-mvi
osgi
otpisani
package-search
pakistan
panamá
pattern-matching
pbandk
pdx
peru
philippines
phoenix
pinoy
pocketgitclient
polish
popkorn
portugal
practical-functional-programming
proguard
prozis-android-backup
pyhsikal
python
python-contributors
quasar
random
re
react
reaktive
realm
realworldkotlin
reductor
reduks
redux
redux-kotlin
refactoring-to-kotlin
reflect
refreshversions
reports
result
rethink
revolver
rhein-main
rocksdb
romania
room
rpi-pico
rsocket
russian
russian_feed
russian-kotlinasfirst
rx
rxjava
san-diego
science
scotland
scrcast
scrimage
script
scripting
seattle
serialization
server
sg-user-group
singapore
skia-wasm-interop-temp
skrape-it
slovak
snake
sofl-user-group
southafrica
spacemacs
spain
spanish
speaking
spek
spin
splitties
spotify-mobius
spring
spring-security
squarelibraries
stackoverflow
stacks
stayhungrystayfoolish
stdlib
stlouis
strife-discord-lib
strikt
students
stuttgart
sudan
swagger-gradle-codegen
swarm
sweden
swing
swiss-user-group
switzerland
talking-kotlin
tallinn
tampa
teamcity
tegal
tempe
tensorflow
terminal
test
testing
testtestest
texas
tgbotapi
thailand
tornadofx
touchlab-tools
training
tricity-kotlin-user-group
trójmiasto
truth
tunisia
turkey
turkiye
twitter-feed
uae
udacityindia
uk
ukrainian
uniflow
unkonf
uruguay
utah
uuid
vancouver
vankotlin
vertx
videos
vienna
vietnam
vim
vkug
vuejs
web-mpp
webassembly
webrtc
wimix_sentry
wwdc
zircon
Powered by Linen
http4k
  • r

    Razvan

    10/16/2020, 8:01 AM
    A coworkorker run this test using webdriver on windows:
    @Test
        fun index() {
            val app = routes(
                "/hello" bind Method.GET to {
                    Response(OK).body("<html><title>hello</title></html>")
                }
            )
            val driver = Http4kWebDriver(app)
    
            driver.navigate().to("<http://localhost:10000/hello>")
    
            println(driver.title)
            println(driver.currentUrl)
            println(driver.findElement(By.tagName("title")))
        }
    and gets as result
    <http://localhost:10000/>\hello
    null
    I run it on Linux all is OK
    hello
    <http://localhost:10000/hello>
    JSoupWebElement(navigate=fun org.http4k.webdriver.Http4kWebDriver.navigateTo(org.http4k.core.Request): kotlin.Unit, getURL=() -> kotlin.String?, element=<title>hello</title>)
    Any ideea where that comes from?
    d
    • 2
    • 3
  • r

    Razvan

    10/16/2020, 2:47 PM
    Hi, again. when writing the meta of OpenApi json generation, Is there a way to add description and/or example for the
    headers
    or
    queries
    ? Your examples only cover body and Path but couldn't from that figure it out for queries.
    d
    • 2
    • 9
  • r

    Riku

    10/19/2020, 6:55 AM
    If I use generated jooq Java pojo, I cannot use it in the OpenApi spec. Is this expected?
    returning(Status.OK, courseLocationsLens to exampleResponse)
    s
    d
    r
    • 4
    • 28
  • c

    Cosmin Victor Celea

    10/19/2020, 12:19 PM
    is it expected that the host(request.uri.host) is “” when running in localhost?
    r
    • 2
    • 1
  • r

    Razvan

    10/21/2020, 4:42 PM
    Hello, any reason why if I read the bodyString of a response of a static ressource like html file in a filter then the response is 500 and content-lenght: 0 ? here's a test:
    @Test
        fun `response body string for html`() {
            val logAll = Filter { next: HttpHandler ->
                { request ->
                    println("REQ: ${request.bodyString()}")
                    val response = next(request)
                    println("REP: ${response.bodyString()}")
                    response
                }
            }
    
            val server = logAll
                    .then(routes("/static" bind static(ResourceLoader.Classpath("static"))))
                    .asServer(Undertow(8080)).start()
    
            val client = DebuggingFilters.PrintResponse()
                    .then(OkHttp())
    
            val response = client(Request(GET, "<http://localhost:8080/static/index.html>"))
            response.status shouldBe 200
        }
    static/index.html exists the filter prints it. the result:
    REQ: 
    REP: <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Hello http4k</title>
    </head>
    <body>
        <h1>Hello http4k</h1>
    </body>
    </html>
    
    ***** RESPONSE 500 to GET: <http://localhost:8080/static/index.html> *****
    HTTP/1.1 500 Internal Server Error
    connection: keep-alive
    content-length: 0
    content-type: text/html
    date: Wed, 21 Oct 2020 16:41:37 GMT
    s
    d
    • 3
    • 6
  • d

    dwellman

    10/23/2020, 12:49 PM
    This is unrelated to http4k directly, but I’m wondering what folks are using on the front end (assuming a web browser / JavaScript) that talk to their http4k servers? That is, are there any JavaScript libraries that align with some of http4k’s testing and design philosophies? I ask because I am brushing up on my JavaScript and browser knowledge.
    r
    d
    r
    • 4
    • 8
  • d

    dave

    10/23/2020, 9:17 PM
    (this obviously adds the burden of dealing with errors yourself at the benefit of better performance, which most apps won't generally care about)
    r
    • 2
    • 2
  • r

    Razvan

    10/31/2020, 9:26 AM
    Hi, I read that using contract routes can have some slight impact on performances, so I was wondering if I should keep the contract routes with no renderer for environnements where I don’t want to have the swagger specifications (production) or is it better to build a standard route in that case ? Thanks
    d
    • 2
    • 2
  • r

    Razvan

    10/31/2020, 12:55 PM
    Btw, I saw that I have to ask you before using the logo, I’m doing an inside corporate presentation next friday, and I was planning to use the logo next to the name on a slide am I allowed to use it ?
    d
    • 2
    • 2
  • d

    dave

    11/02/2020, 5:59 PM
    @Paul Martin in order to achieve this you need to use the Jackson annotations in order that the mapper can tell which element to use. @JsonTypeInfo and @JsonSubTypes.Type annotations are your friend here.
    🙏 1
    p
    • 2
    • 1
  • d

    dave

    11/02/2020, 6:44 PM
    Hey everyone. The http4k Toolbox is now (finally) ready for general use - it's a collection of tools to generate code for http4k projects. Try it out and let us know what you think! https://toolbox.http4k.org/ or install
    http4k
    via Brew/SDKman!
    🙌 3
    🎉 8
    k
    r
    • 3
    • 15
  • r

    Razvan

    11/04/2020, 3:13 PM
    Hello, if I copy the swagger specifications generated and paste them in the swagger editor I get a lot of errors because fields description is null. Any way to set them or not generate them if null or set then to empty string ? Ex of json generate par default project
    info:
      title: Test API
      version: v1.0
      description: null
    tags: []
    paths:
      /contract/api/v1/echo:
        post:
          summary: echoes the name and message sent to it
          description: null
          tags:
            - /contract/api/v1
          parameters: []
          requestBody:
            content:
              application/json:
                example:
                  name: jim
                  message: hello!
                schema:
                  $ref: '#/components/schemas/NameAndMessage'
                  description: null
                  example: null
            required: true
          responses:
            '200':
              description: OK
              content:
                application/json:
                  example:
                    name: jim
                    message: hello!
                  schema:
                    $ref: '#/components/schemas/NameAndMessage'
                    description: null
                    example: null
          security:
            - api_key: []
          operationId: postContractApiV1Echo
          deprecated: false
    components:
      schemas:
        NameAndMessage:
          properties:
            name:
              example: jim
              description: null
              type: string
            message:
              example: hello!
              description: null
              type: string
          example:
            name: jim
            message: hello!
          description: null
          type: object
          required:
            - message
            - name
      securitySchemes:
        api_key:
          type: apiKey
          in: query
          name: api
    openapi: 3.0.0
    and the online editor https://editor.swagger.io/
    d
    c
    • 3
    • 16
  • r

    Razvan

    11/05/2020, 11:24 PM
    Got an unexpected behavior on a ContractRoute the route have path lens:
    val btcPath = <http://Path.int|Path.int>().map(::BTC).of("btc")
    val spec = "mine" / btcPath
    it works if i call
    /mine/42
    but if the param is not an int ex:
    /mine/foo
    I get a 404 . I was thinking about la lensFailure so 400 or if not catched 500 but not 404. Is it designed that way or is something not right ?
    d
    • 2
    • 8
  • r

    Razvan

    11/06/2020, 12:16 AM
    And another unexpected behaviour:
    data class Test(val name: Int)
    you declare in meta :
    receiving(Body.auto<Test>().toLens() to Test(3))
    you call in a curl with
    -d "{\"name\":5}"
    it passes (it’s ok is just for reference of a correct call) but you call also with a bad keyname ex:
    -d "{\"ne\":5}"
    the call is valid. if name is a String this works as expected, fails if the key is spelled bad. I don’t use that value so don’t know if the created object would be valid. I’ll try to make a full test tomorrow evening too late for that right now.
    d
    • 2
    • 2
  • v

    Vojtěch Knyttl

    11/08/2020, 8:38 PM
    Is it possible to somehow test the OpenAPI /docs endpoint? It happens to me that I get:
    org.http4k.contract.openapi.v3.NoFieldFound: Could not find XXX in YYY
    	at org.http4k.contract.openapi.v3.FieldRetrieval$Companion$compose$1.invoke(FieldRetrieval.kt:17) ~[http4k-contract-3.249.0.jar:?]
    	at org.http4k.contract.openapi.v3.FieldRetrieval$Companion$compose$1.invoke(FieldRetrieval.kt:9) ~[http4k-contract-3.249.0.jar:?]
    	at org.http4k.contract.openapi.v3.AutoJsonToJsonSchema.toObjectSchema(AutoJsonToJsonSchema.kt:64) ~[http4k-contract-3.249.0.jar:?]
    	at org.http4k.contract.openapi.v3.AutoJsonToJsonSchema.toObjectOrMapSchema(AutoJsonToJsonSchema.kt:60) ~[http4k-contract-3.249.0.jar:?]
    Getting this in runtime is a bit too late 🙂
    s
    d
    • 3
    • 7
  • r

    Razvan

    11/10/2020, 10:06 AM
    Hi if a declare lens asResult can I pass it the meta or I have to make a lens then a result and pass the lens to the receiving .
    d
    • 2
    • 4
  • r

    Razvan

    11/11/2020, 10:32 AM
    Hi just a big 👍 👍 guys for thinking about everything... at work a requirement was to give detailed mapping errors of bodies failure... as I was using a ContractRoute with default error handling I was just getting an standard error: "Invalid body should be an object" which was not enough. Poking around I found the
    preFlightExtraction
    in parameter in the
    meta
    tag which is quite great as it can disable the checks of lens on the contract level and lets you handle the LensFailure exception when you use the lens. So that saved my day. Then while I was going through how the OpenApi render is done, I saw that you even thought about letting the
    errorReponseRenderer
    as a parameter to the constructor. So it's even easier to providing my custom ErrorResponseRender that tries to make sens of Jackson exceptions, to provide the required parameters. So thank you thinking about different use cases and providing so many setting to answer to different (sometimes dumb) requirements !
    👍 1
    d
    • 2
    • 1
  • a

    andyg

    11/12/2020, 9:32 PM
    hi guys... any chance you'll bring back the search box on the documentation website?
    s
    r
    • 3
    • 9
  • a

    araknafobia

    11/12/2020, 10:28 PM
    Hi all, thanks for such a great library. I was wondering something about
    Typesafe RequestContexts
    . In certain level, it makes extraction type safe however it does not guarantee that we won't forget to populate context with data. Isn't there a better approach to handle this situation?
    d
    • 2
    • 3
  • a

    andyg

    11/14/2020, 1:38 AM
    Best way to serve a file download? Not using
    static
    because there's some validation involved (or maybe file created dynamically). Based on an earlier Slack thread, I came up with this:
    return if (<some validation code here>)
      Response(Status.OK)
        .header("Content-Type", "application/zip") // "application/octet-stream")
        .header("Content-Disposition", "attachment; filename=${myFileToServe.file.substringAfterLast("/")}")
        .header("Content-Length", myFileToServe.openConnection().contentLength.toString())
        .body(myFileToServe.openStream())
    else Response(Status.UNAUTHORIZED)
    d
    • 2
    • 3
  • r

    Razvan

    11/17/2020, 7:07 PM
    Hi, I was wandering if the
    OpenApi3ApiRenderer
    should render or not null values giving that OpenAPI specification clearly states that
    null
     is not supported as a type.
    Ok you can disable null from Json but it's not the default, requires a custom config, but I think the OpenApi3Renderer should (at least by default) follow to the specifications of the format it claim to render. Don't you think ?
    d
    • 2
    • 4
  • v

    Vojtěch Knyttl

    11/19/2020, 7:18 AM
    Is there a way to make
    Path.string().of("")
    optional? When I have
    "/events" / Path.of("eventId")
    , it says
    404
    if
    eventId
    is not given. Also, what would be difference between
    .string()
    and
    .nonEmptyString()
    ?
    d
    • 2
    • 3
  • a

    Arnab Datta

    11/19/2020, 12:08 PM
    I keep getting the following error when adding
    implementation group: "org.http4k", name: "http4k-graphql", version: "3.278.0"
    to my
    build.gradle
    file. Any ideas?
    Could not find org.http4k:http4k-format-jackson:3.278.0.
    d
    • 2
    • 27
  • a

    Arnab Datta

    11/19/2020, 3:31 PM
    Question about the http4k-graphql module: I’m looking at the example that is given in the examples repo, and I’m testing the following query against `localhost:8000/graphql/user`:
    {
      search(params: {ids: [1,2]}){
        id
        name 
      }
      s2:search(params: {ids: [1,2]}){
        id
        name 
      }
    }
    and using a small
    .also { println("running some expensive query") }
    I was able to see that this was calling the
    UserQueries.search
    method twice. Since the example specifically has a dataloader, I was wondering why? Isn’t the whole point of dataloaders that regardless of how the query is formed, one only calls the underlying service just once? Or is this specific to nested queries only (i.e. calls to fields of type
    User
    say for instance a
    friends
    field that invokes some kind of function towards the DB)? What am I misunderstanding here?
    d
    • 2
    • 5
  • r

    Riku

    11/19/2020, 6:19 PM
    can someone show an example of how you would add the content and format of a file download with the contract api DSL?
    d
    • 2
    • 1
  • v

    Vojtěch Knyttl

    11/19/2020, 11:37 PM
    is ti possible to test on top of
    ContractRoute
    with
    Path.string()
    parameters? Basically, I can do:
    val response = myContractRoute(request)
    but when accessing
    Path.string()
    parameters I am getting:
    Request was not routed, so no uri-template present
    I tried then with what I found in https://www.http4k.org/cookbook/test_driven_apps/:
    val root = routes(myContractRoute)
    but it seems the
    routes()
    method cannot work with ContractRoute. is there a way?
    d
    • 2
    • 7
  • r

    Razvan

    11/23/2020, 5:40 PM
    Hi, is there a way to do a Principal lookup in the
    security
    definition of a ContractRoute or have do be done apart ?
    d
    • 2
    • 3
  • j

    janvladimirmostert

    11/28/2020, 9:42 AM
    http4k looks very interesting, I like how it focuses on just http instead of trying to do everything few questions, when you do
    val app = { request: Request ->
    
    }
    val server = app.asServer(Netty(9000)).start()
    is the inside of that lambda a single thread or using some kind of event loop or is that server dependent? when load testing (with
    Netty(9000)
    ), I'm seeing nioEventLoopGroup-2-1 and nioEventLoopGroup-3-1..24, I'm assuming those 25 threads are from Netty? how would one execute suspendable functions (or even blocking functions) inside that lambda?
    val app = { request: Request ->
      	GlobalScope.launch {
    		suspendableFunctionThatReturnsResponse()
    	}
    }
    val server = app.asServer(Netty(9000)).start() // obviously doesn't compile since that app lambda doesn't return a Response
    s
    r
    • 3
    • 7
  • n

    Nikky

    11/30/2020, 6:50 PM
    does http4k have examples of how to set it up on kotlin-native ? if thats possible at all
    d
    • 2
    • 3
  • r

    Razvan

    12/02/2020, 6:51 PM
    Hi, I can't figure out why my custom Jackson configuration that excludes null values is not used in the Body.auto lens.
    object CustomJackson : ConfigurableJackson(KotlinModule()
        .asConfigurable()
        .withStandardMappings()
        .done()
        .deactivateDefaultTyping()
        .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
        .configure(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES, false)
        .configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS, true)
        .configure(DeserializationFeature.USE_BIG_INTEGER_FOR_INTS, true)
        .setSerializationInclusion(JsonInclude.Include.NON_EMPTY)
        .setSerializationInclusion(JsonInclude.Include.NON_NULL)
    )
    val obj = Body.auto<MyObject>().toLens()
    in the json response I have the null object.... Trying to dig around, i see that
    Body.auto
    uses the mapper that is ConfigurableJackson class but can't figure out how to make sure it's the one from my CustomJackson that's used and not the default Jackson object ? any clues ?
    • 1
    • 1
Powered by Linen
Title
r

Razvan

12/02/2020, 6:51 PM
Hi, I can't figure out why my custom Jackson configuration that excludes null values is not used in the Body.auto lens.
object CustomJackson : ConfigurableJackson(KotlinModule()
    .asConfigurable()
    .withStandardMappings()
    .done()
    .deactivateDefaultTyping()
    .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
    .configure(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES, false)
    .configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS, true)
    .configure(DeserializationFeature.USE_BIG_INTEGER_FOR_INTS, true)
    .setSerializationInclusion(JsonInclude.Include.NON_EMPTY)
    .setSerializationInclusion(JsonInclude.Include.NON_NULL)
)
val obj = Body.auto<MyObject>().toLens()
in the json response I have the null object.... Trying to dig around, i see that
Body.auto
uses the mapper that is ConfigurableJackson class but can't figure out how to make sure it's the one from my CustomJackson that's used and not the default Jackson object ? any clues ?
Thanks to David's answer on this github issue I figured out... have to import my own auto... next time I'll search better
👍 1
View count: 7