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
  • d

    dave

    04/17/2020, 3:49 PM
    @Mehdi you can use a composite to extract the values like so:
    fun main() {
        data class Pageable(val sortAscending: Boolean, val page: Int, val maxResults: Int)
    
        val lens = Query.composite {
            Pageable(
                boolean().defaulted("sortAscending", true)(it),
                int().defaulted("page", 1)(it),
                int().defaulted("maxResults", 20)(it)
            )
        }
    
        println(lens(Request(GET, "/list?page=1")))
        // Pageable(sortAscending=true, page=1, maxResults=20)
    }
    👌 1
    👍 1
    p
    • 2
    • 1
  • s

    sp

    04/18/2020, 3:59 AM
    not an http4k bug per se but something to consider when building executable jars with Jetty in http4k
    d
    a
    • 3
    • 6
  • e

    Eduardo Narros

    04/22/2020, 2:15 PM
    Hi all, we are using http4k-contract and we were wondering if there is a way to add a description to a definition property. As the properties are inferred from the response data class, we thought perhaps there is an annotation or equivalent that we could use?
    d
    • 2
    • 4
  • d

    dave

    04/23/2020, 12:40 PM
    you just need to add the person/xsd one first because otherwise the wildcard will match
    c
    • 2
    • 10
  • c

    Cosmin Victor Celea

    04/27/2020, 2:26 PM
    Is it possible to use coroutines ? I have to do a large insert after calling an endpoint but i want to return the a Status.OK after i validate the data and not wait for the data to be inserted.
    d
    • 2
    • 1
  • m

    Mehdi

    05/01/2020, 11:17 PM
    How to add a custom filter similar to BasicAuth into ServerFilters?
    d
    • 2
    • 2
  • u

    Uberto Barbini

    05/06/2020, 7:36 PM
    question 1: is there some example to copy on managing the cookie storage for http4k client? we made it works but I think it should be kind of simpler than the code we've written
    s
    • 2
    • 1
  • u

    Uberto Barbini

    05/06/2020, 7:41 PM
    question 2: when doing local testing, we start alll our microservices on local host with different ports. To make the services correctly calling each other we keep a map of the ports and set all the hostname to localhost. So far so good... now we are toying with the idea of not starting the servers (sockets and all), but just connecting the httpHandlers between them. What we need is a way to select the right one using some abstraction (what currently is the port). Is there some work done in this direction somewhere?
    s
    d
    n
    • 4
    • 32
  • a

    andyg

    05/08/2020, 7:46 AM
    re: cookies. I have a list of Response objects from the same domain, now I am trying to replicate the client state at the end, specifically the cookies. The basic logic would say to loop through each Response, and for each Cookie either add new or overwrite, as appropriate. What's the most efficient or easiest way to do this in 4k? loop and create a simple list of k/v pairs? Use BasicCookieStorage and map the Response's cookie to LocalCookie? Use a Filter and send each Response through it? Something else? Thank you.
    • 1
    • 1
  • c

    Cosmin Victor Celea

    05/11/2020, 1:14 PM
    Hi we are trying to upgrade http4k but we are getting a compile error because body.gzipped() now returns a CompressionResult. Any ideas?
    Untitled
    d
    • 2
    • 4
  • s

    Saša Šijak

    05/12/2020, 12:27 PM
    I am evaluating kotlin frameworks for my new app which will use server generated pages, no JSON api needed. I like simple frameworks with little magic, but with reasonable defaults, speed and large enough community. That left ktor and http4k in kotlin world. Why would I choose http4k over ktor?
    d
    • 2
    • 1
  • s

    Saša Šijak

    05/13/2020, 4:39 AM
    1 more question. Is there a way to add auto reload functionality on code changes?
    s
    d
    j
    • 4
    • 4
  • a

    andyg

    05/13/2020, 10:07 AM
    Hi, what's the best practice for returning an arbitrary Map object as a JSON Response? No validation, as the keys will vary often. The 3 examples at https://www.http4k.org/guide/modules/json/ all describe objects specifically created to be JSON, not a normal Map (or list of Pairs). And can http4k automatically set the Response's content type to
    application/json
    ? Perhaps an equivalent of Flask's
    jsonify
    (https://flask.palletsprojects.com/en/1.1.x/api/#flask.json.jsonify). Thanks.
    d
    • 2
    • 12
  • a

    Arnab Datta

    05/18/2020, 8:49 AM
    I noticed that the latest http4k uses okhttp
    4.6.0
    but the newest version of okhttp is
    4.7.0
    Is there a recommended upgrade strategy here? Should I wait for http to catch up with okhttp before upgrading both?
    d
    • 2
    • 3
  • a

    Alpha Ho

    05/22/2020, 6:13 AM
    Hi, I’m trying to contribute to http4k and think I may work on https://github.com/http4k/http4k/issues/327 To add the multipart response support, should I create a set of classes and lenses similar to
    MultipartFormBody
    ,
    MultipartEntity
    ,
    MultipartFormParser
    ,
    Part
    etc.? If so, is it possible to reuse some of the existing logic? Because the current
    http4k-multipart
    module seems very specific to
    multipart/form-data
    requests, it feels not very straight-forward to reuse.
    🔥 1
    • 1
    • 1
  • d

    dave

    05/29/2020, 3:16 PM
    For anyone that is interested - another pretty good showing from the http4k camp... 🙂 https://kotlinlang.slack.com/archives/C0B8RC352/p1590765239291500
    🎉 1
    s
    • 2
    • 1
  • q

    Quy D X Nguyen

    05/30/2020, 5:02 PM
    So, I'm using Http4k streaming like so
    val client = ApacheClient(responseBodyMode = BodyMode.Stream, client = HttpClients.custom()
    		.setDefaultRequestConfig(RequestConfig.custom()
    				.setCookieSpec(CookieSpecs.IGNORE_COOKIES)
    				.build()).build())
    
    val app = { request: Request ->
    	val query = Request(Method.GET, "<some url>")
    	val response = client(query)
    
    	Response(Status.OK).body(response.body)
    }.asServer(Netty(port)).start()
    Now if I use Jetty, the streaming nature works fine. I want to use Netty however, and switching to Netty means all the streaming code is ignored, and no waterfall occurs.
    s
    • 2
    • 14
  • q

    Quy D X Nguyen

    05/31/2020, 4:32 PM
    Also, is
    ApacheClient
    safe to reuse in a handler?
    s
    • 2
    • 12
  • a

    Andrew Worley

    06/02/2020, 12:29 PM
    Hi guys, we're currently trying to use http4k as a reverse proxy, and wanted to pass an incoming request to a client (which client depends on matching the path in the request), and then return the response from the client to the originating requestor. We're having some trouble with tests at the moment - we wanted to create a fake server in our test (to simulate the service we proxy to), and capture the request that it receives, so assert that our proxy passed on the request correctly. The issue that we're having is when trying to call bodyString() on the captured request, this just hangs. We think it's something to do with the body already being consumed, but wondered if you could help explain what we're doing wrong here? I'll post the example test and HttpHandler code. Thanks in advance!
    d
    s
    • 3
    • 9
  • q

    Quy D X Nguyen

    06/08/2020, 9:25 PM
    So a bug I've found is that
    ApacheClient
    will just stop querying large files (3Mb) and not close the connection. This leads to thread starvation and eventually an unresponsive app.
    val client = ApacheClient(responseBodyMode = BodyMode.Stream, client = HttpClients.custom()
        .setDefaultRequestConfig(RequestConfig.custom()
            .setCookieSpec(CookieSpecs.IGNORE_COOKIES)
            .setConnectTimeout(3000)
            .setSocketTimeout(3000)
            .build())
        .setMaxConnTotal(10)
        .build())
    I'm just piping the resulting stream directly into a response, and when I augmented the ReadCalls with some printlns, they just suddenly stop after a while - and then my app freezes. Edit: It can also happen on smaller files. What's important is that the connection doesn't appear to be closed.
    d
    s
    • 3
    • 8
  • m

    Mehdi

    06/09/2020, 9:20 AM
    Hi All, How can I easily configure OpenAPI or swagger for my existing routes? I checked the codes and discussions here, open API contract is totally confusing me to be honest🙂
    fun routes(): RoutingHttpHandler {
    return org.http4k.routing.routes(
                    "/ping" bind Method.GET to pingHandler,
                    "foo" bind <http://Method.POST|Method.POST> t fooHandler,
                  
            )
    }
    d
    • 2
    • 6
  • d

    dave

    06/09/2020, 7:05 PM
    Our @kotliners talk "Writing Test-Driven Apps with http4k" is now available. Create reliable, crazy fast HTTP tests (even for 3rd party services), which you can reuse at multiple levels of the testing pyramid. https://t.co/xrrkdkUHmb
    👍 7
    f
    • 2
    • 1
  • q

    Quy D X Nguyen

    06/11/2020, 3:35 AM
    How does WsHandler work? Does it handle the upgrading itself? If not, why does it take an Upgrade Request instance field?
    d
    • 2
    • 1
  • c

    Cosmin Victor Celea

    06/11/2020, 8:00 AM
    GET /api/personer/47120999865 HTTP/2
    Host: localhost:8443
    User-Agent: curl/7.64.1
    Accept: /
    * Connection state changed (MAX_CONCURRENT_STREAMS == 128)! * TLSv1.2 (IN), TLS alert, close notify (256): * Empty reply from server * Connection #0 to host localhost left intact curl: (52) Empty reply from server * Closing connection 0
    s
    d
    • 3
    • 56
  • k

    krtko

    06/15/2020, 7:45 PM
    Hi being using HTTP4k in production for roughly a year now and its been great! So thank you. I'm having a very odd and very rare issue. I recently updated from
    3.183.0
    to
    3.249.0
    and I use Undertow in production About once a day, a single request throw this error
    io.undertow.request - UT005007: Request was not fully consumed
    Any ideas?
    d
    • 2
    • 9
  • a

    andyg

    06/29/2020, 7:02 AM
    Hi David, adding cookies to a request via
    .cookie(name, val)
    results in the cookie values being surrounded by double-quotes. I'm guessing that is usually OK but is it possible to create the Cookie header without the double-quotes for some fussy servers? (other than creating my own list of k-v pairs and joining the string manually). Thanks
    s
    d
    • 3
    • 5
  • p

    pabl0rg

    07/01/2020, 4:31 PM
    Hi, does anyone know of an example app using http4k and oauth2 where the app uses the user's oauth token not only to identify/authorize the user but also to make requests to remote web services?
    d
    • 2
    • 4
  • c

    Cosmin Victor Celea

    07/08/2020, 1:56 PM
    Getting this error: “header ‘x-http4k-context’ is required” when calling
    contexts[request]
    Any ideas?
    d
    • 2
    • 11
  • a

    andyg

    07/24/2020, 3:17 AM
    not really a 4k question but probable you've had to deal with it: Trying to test my 4k server using the 4k
    ApacheClient()
    ... which is stuck on "DEBUG" log level and thus prints huge amounts of output. Tried to change with
    (LoggerFactory.getLogger(ApacheClient::class.java) as ch.qos.logback.classic.Logger).level = Level.ERROR
    but no luck. Any ideas on changing the client log level? Thanks.
    d
    f
    • 3
    • 3
  • s

    Sandyzwin6

    08/04/2020, 11:22 AM
    I have an ApacheClient in some of my integration tests for a streaming server. The server will never close the stream autonomously unless there is an error, so in the tests I wait for a number of messages and then close the response. However the call to close of the response body hangs on reading the socket. It would appear that some handshake is not working.
    val client: HttpHandler = ApacheClient(responseBodyMode = BodyMode.Stream)
            client(invoke(Method.GET, url)).use { response ->
                assertEquals(Status.OK, response.status)
                validateReadings(response, 1, instant(from), instant(to))
            }
    s
    • 2
    • 11
Powered by Linen
Title
s

Sandyzwin6

08/04/2020, 11:22 AM
I have an ApacheClient in some of my integration tests for a streaming server. The server will never close the stream autonomously unless there is an error, so in the tests I wait for a number of messages and then close the response. However the call to close of the response body hangs on reading the socket. It would appear that some handshake is not working.
val client: HttpHandler = ApacheClient(responseBodyMode = BodyMode.Stream)
        client(invoke(Method.GET, url)).use { response ->
            assertEquals(Status.OK, response.status)
            validateReadings(response, 1, instant(from), instant(to))
        }
s

s4nchez

08/04/2020, 11:55 AM
@Sandyzwin6 are you consuming the response body in your test? In our experience one doesn’t need to explicitly close connections to get both streaming and resource management to work correctly
s

Sandyzwin6

08/04/2020, 1:41 PM
Yes the validateReadings function reads from the resource,
It just seems strange that using
use
on a Closeable, which is the normal pattern and AFAIK the contract of a Closeable, does not close the resource but hangs. I can simply ignore this because it is only a test and what I actually want to test works fine, but to be honest this doesn't seem right.
s

s4nchez

08/04/2020, 1:45 PM
In this case it’d help to see an example of the server code that reproduces the behaviour you’re seeing
There shouldn’t be a need for the “use” because the underlying apache client will manage the resources for you
Another thing you can try is replacing client/server implementations to see if the behaviour remains the same.
s

Sandyzwin6

08/04/2020, 1:46 PM
That's not the point is it? A response is a closeable I should be able to close it surely?
I can't change the server implementation.
s

s4nchez

08/04/2020, 1:47 PM
Ah! If the server is not http4k, then I suggest trying with another underlying client (okhttp is what we’ve been using the most recently)
s

Sandyzwin6

08/04/2020, 1:52 PM
The server is a SpringBoot Application using some
StreamingResponseBody
So looking for the reason in that stuff will be like looking for a needle in a haystack. Why use Spring? Why Indeed... Not my choice :-(
😞 1
s

s4nchez

08/04/2020, 1:55 PM
3 things you can try: 1. Like I said, check if the same happens with a different http4k client 2. Temporary disable streaming 3. Remove the “use” (as it may be trying to close an already closed stream and that case may not be handled correctly somewhere)
View count: 6