Kotlin DSL http client

Overview

Introduction

Build Status Maven Central codecov Codacy Badge Kotlin Awesome Kotlin Badge Join the chat at https://gitter.im/kohttp/communitystar this repo

Kotlin DSL http client

Features

๐Ÿ”น Developers Experience-driven library without verbosity.

๐Ÿ”น Native way to use http client in Kotlin.

๐Ÿ”น HTTP GET/POST/PUT/HEAD/DELETE/PATCH requests.

๐Ÿ”น Asynchronous and blocking requests.

๐Ÿ”น Upload files.

๐Ÿ”น Logging - easily dump your http requests or convert them to cURL commands.

๐Ÿ”น Minimal footprint.

Quick start

// Use String or URL extensions send simple request
val response = "https://my-host.com/users?admin=true".httpGet()

// Parse response with your favorite library
val users = response.toJson()

// Use sync or async methods to send your requests
// Configure method params, headers, cookies and body in a concise way
val notifications: List<Deferred<Response>> = users.forEach { user ->
    httpPostAsync {
        url("https://my-host.com/friends/push")
        
        param {
            "userId" to user[id]
            "eventType" to NewFriend
        }
        
        header {
            "locale" to "en_EN"
            cookie {
                "user_session" to "toFycNV"
                "authToken" to "d2dwa6011w96c93ct3e3493d4a1b5c8751563217409"
            }
        }
    }
}

Samples

About kohttp

Installation

Gradle

Kotlin DSL:

implementation(group = "io.github.rybalkinsd", name = "kohttp", version = "0.12.0")

Groovy DSL:

implementation 'io.github.rybalkinsd:kohttp:0.12.0'

Maven:

<dependency>
  <groupId>io.github.rybalkinsd</groupId>
  <artifactId>kohttp</artifactId>
  <version>0.12.0</version>
</dependency>

Table of contents

Comments
  • Generic http/httpAsync DSL

    Generic http/httpAsync DSL

    This is a pull request to enable dynamic http request, see issue mentioned here: https://github.com/rybalkinsd/kohttp/issues/169

    Summary: With the current version the end-user needs to explicitly specify which http context to use for each http method type, see here code snippet from the issue https://github.com/rybalkinsd/kohttp/issues/169:

    package it.skrape.core.fetcher
    
    import io.github.rybalkinsd.kohttp.client.defaultHttpClient
    import io.github.rybalkinsd.kohttp.client.fork
    import io.github.rybalkinsd.kohttp.dsl.*
    import io.github.rybalkinsd.kohttp.dsl.context.HttpContext
    import io.github.rybalkinsd.kohttp.ext.url
    import it.skrape.core.Request
    import it.skrape.core.Result
    import org.jsoup.Connection
    
    class KoFetcher(private val request: Request): Fetcher {
    	private val client = defaultHttpClient.fork {
    		followRedirects = request.followRedirects
    		readTimeout = request.timeout.toLong()
    	}
    
    	override fun fetch(): Result {
    		val requester = when(request.method) {
    			Connection.Method.GET -> httpGet(client, getContext())
    			Connection.Method.POST -> httpPost(client, getContext())
    			Connection.Method.PUT -> httpPut(client, getContext())
    			Connection.Method.DELETE -> httpDelete(client, getContext())
    			Connection.Method.PATCH -> httpPatch(client, getContext())
    			Connection.Method.HEAD -> httpHead(client, getContext())
    			else -> throw UnsupportedOperationException("Method is not supported by KoHttp")
    		}
    		requester.use {
    			return Result(
    				responseBody = it.body()?.string() ?: "",
    				statusCode = it.code(),
    				statusMessage = it.message(),
    				contentType = it.header("Content-Type"),
    				headers = it.headers().names().associateBy({item -> item}, {item -> it.header(item, "")!!}),
    				request = request
    			)
    		}
    	}
    
    	private fun getContext(): HttpContext.() -> Unit = {
    		url(request.url)
    		header {
    			request.headers
    			"User-Agent" to request.userAgent
    			cookie {
    				request.cookies
    			}
    		}
    	}
    } 
    

    Provided solution Within this pull request a http request can be executed by either specifying the http method or http context. The underlying function will determine during runtime which http context to use by the provided arguments.

    The above snippet can be rewritten with the following snippet:

    package it.skrape.core.fetcher
    
    import io.github.rybalkinsd.kohttp.client.defaultHttpClient
    import io.github.rybalkinsd.kohttp.client.fork
    import io.github.rybalkinsd.kohttp.dsl.*
    import io.github.rybalkinsd.kohttp.dsl.context.HttpContext
    import io.github.rybalkinsd.kohttp.ext.url
    import it.skrape.core.Request
    import it.skrape.core.Result
    import org.jsoup.Connection
    
    class KoFetcher(private val request: Request): Fetcher {
    	private val client = defaultHttpClient.fork {
    		followRedirects = request.followRedirects
    		readTimeout = request.timeout.toLong()
    	}
    
    	override fun fetch(): Result {
    	    method: Method = Method.valueOf(request.method.toString)
    	    val requester = http(method = method, init = getContext)
    
    		requester.use {
    			return Result(
    				responseBody = it.body()?.string() ?: "",
    				statusCode = it.code(),
    				statusMessage = it.message(),
    				contentType = it.header("Content-Type"),
    				headers = it.headers().names().associateBy({item -> item}, {item -> it.header(item, "")!!}),
    				request = request
    			)
    		}
    	}
    
    	private fun getContext(): HttpContext.() -> Unit = {
    		url(request.url)
    		header {
    			request.headers
    			"User-Agent" to request.userAgent
    			cookie {
    				request.cookies
    			}
    		}
    	}
    }
    

    Note This pull request is currently WIP to get review input on the initial solution. Some unit tests are already added to provide example usages.

    enhancement 
    opened by Hakky54 17
  • Have problem when use multipartBody

    Have problem when use multipartBody

    Hello,

    I have a problem when using kohttp to upload an image when using multipartBody I have to upload an image and also needs some data like "name" and "id" like the attached image in Postman. I also need to add "Authorization" in the header. ่žขๅน•ๅฟซ็…ง 2019-07-06 16 21 14

    below is my code

    val path = "$serverURL"
            val response = httpPost {
                url(path)
                header {
                    "content-type" to "multipart/form-data"
                    "Authorization" to "Bearer " + myToken
                }
                multipartBody {
                    +form("image",image)
                    "name" to name
                    "id" to "123"
    
                }
            }.eager()
    

    The image cannot upload and seems like name & id also not send to the server. Can you help me if there is any wrong when I use kohttp to upload the file?

    bug 
    opened by rraayy 12
  • Response extension functions

    Response extension functions

    Response is rather verbose, especially accessing body content.

    httpXXX { } .use {
            val content = it.body()?.string().asJson()
    }
    

    Need to observe other http clients and figure out how dsl approach can serve users for clear response consumption.

    Previously EagerResponse was introduced, however it's usage is also rather complex

    enhancement good first issue in progress ๐Ÿ‘ฉ๐Ÿปโ€๐Ÿ’ป design stage 
    opened by rybalkinsd 9
  • Log Interceptor

    Log Interceptor

    Analyse okhttp log interceptor Figure out how to provide our own with minimal DSL configuration Try to avoid any dependencies for this case.

    From the first view okhttp-logging-interceptor's provides too verbose logs

    enhancement good first issue design stage 
    opened by rybalkinsd 9
  • java.lang.NoClassDefFoundError in API Level 23 (Android 6)

    java.lang.NoClassDefFoundError in API Level 23 (Android 6)

    I'm using Kohttp with AndroidAnnotations. For debug builds, I'm using MultiDex and for release builds, I'm disabling MultiDex and enabling ProGuard and Shrinking.

    Everything is working fine on Android 8 and 9 devices. However, for Android 4.4 and 6 devices, I'm getting the following error when doing a post request:

    java.lang.NoClassDefFoundError: io.github.rybalkinsd.kohttp.dsl.context.HeaderContext$sam$java_util_function_BiConsumer$0
            at io.github.rybalkinsd.kohttp.dsl.context.HeaderContext.forEach$kohttp(HeaderContext.kt:20)
            at io.github.rybalkinsd.kohttp.dsl.context.HttpContext.makeHeaders(HttpContext.kt:50)
            at io.github.rybalkinsd.kohttp.dsl.context.HttpContext.makeRequest(HttpContext.kt:38)
            at io.github.rybalkinsd.kohttp.dsl.HttpPostDslKt.httpPost(HttpPostDsl.kt:48)
            at com.eximusedu.app.service.Service.login(Service.kt:62)
            at com.eximusedu.app.LoginActivity.doLogin(LoginActivity.kt:137)
            at com.eximusedu.app.LoginActivity_.access$101(LoginActivity_.java:35)
            at com.eximusedu.app.LoginActivity_$5.execute(LoginActivity_.java:162)
            at org.androidannotations.api.BackgroundExecutor$Task.run(BackgroundExecutor.java:400)
            at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:423)
            at java.util.concurrent.FutureTask.run(FutureTask.java:237)
            at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:154)
            at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:269)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
            at java.lang.Thread.run(Thread.java:833)
    

    What could possibly the issue here? Thanks.

    bug 
    opened by sharafat 8
  • Scope

    Scope "Runtime" for dependencies?

    I am sure you have good reasons for. But it took me longer than I am willing to admit to figure out why "okhttp3.Response" could not be resolved.

    Could you either:

    • change the scope to "compile"
    • change the documentation so that new users will recognize that.
    bug in progress ๐Ÿ‘ฉ๐Ÿปโ€๐Ÿ’ป 
    opened by jschneider 8
  • WIP: Add tests for HttpPostContext content-type

    WIP: Add tests for HttpPostContext content-type

    I've added a couple tests which I think cover most of the functionality. I couldn't get the first way (header) to work.

    I don't believe this is ready to merge, hence the "WIP" in the title. Mostly looking to see whether I'm going in the right direction or not.

    Cheers!

    opened by mlevesquedion 8
  • Add tests for HttpPostContext content-type

    Add tests for HttpPostContext content-type

    Hello, I try to resolve #62 , but I can't do to the last. Because, this comment's ( https://github.com/rybalkinsd/kohttp/issues/62#issue-396198795 ) 1st way ( header { type } ) seems not to work.

    So, at first I try to implement 2nd and 3rd way's test.

    opened by doyaaaaaken 7
  • Dependency on Jackson even tho it is only used in one extension method

    Dependency on Jackson even tho it is only used in one extension method

    Hey. I've noticed that there is a dependency on Jackson. Is it really that necessary to add it to the library just to use it inside of one extension method? Can it be possibly moved to a separate artifact?

    enhancement good first issue 
    opened by dtropanets 7
  • adds interceptor to sign query params

    adds interceptor to sign query params

    Initial implementation for #52.

    I considered both the approaches mentioned in the issue.

    DSL on params

    • Simple, straightforward
    • It was at the request level
    • Limited to just the query params

    Defining an interceptor

    • Defined at the client level
    • Potential to access other aspects of the Request for signing the request

    Different services sign their requests differently eg: amazon vs twitter

    @rybalkinsd But would it be more flexible to let user the user define their own interceptor? Thoughts?

    We can further refactor the implementation based on the design we arrive at.

    opened by gokulchandra 7
  • `url()` with params and `param { }` works not obvious together

    `url()` with params and `param { }` works not obvious together

    At the moment we ignore url( ) parameters.

    It would be better if we will add them as a primary source of params.

    checklist:

    • [x] "path/?a=b"
    • [x] "path?a=b"
    • [x] "path/?a=b&c=&d=123"
    • [x] "path?a=b#tag"
    • [x] "path?a=xxx&a=&a=yyy
    enhancement 
    opened by rybalkinsd 6
  • url is double encoded if used with url(encodedUrl)

    url is double encoded if used with url(encodedUrl)

    In a sequence of calls when first call returns encoded url as redirect it cannot be used for next call with url(encodedUrl) as the library encodes path again. There is no bool to disable path encoding as far as i could find.

    opened by mazmar 0
  • How can I use kohttp for this specific curl command?

    How can I use kohttp for this specific curl command?

    I'd like to replace the usage of crude shell commands with a nice library, and kohttp looks quite promising

    One example I'm testing against, it's from gradle kts exec{}:

    commandLine("curl", "-X", "GET", "-H", "Authorization: token $token", "https://api.github.com/repos/kotlin-graphics/mary/contents/$path")
    

    I tried to port that over to kohttp

        val response = httpGet {
            host = "https://api.github.com/repos/kotlin-graphics/mary/contents/$path"
            header {
                "-H" to "Authorization: token $token"
            }
        }
    

    But unfortunately, all I get is:

    • What went wrong: Execution failed for task ':publishToGithub'. unexpected host: https://api.github.com/repos/kotlin-graphics/mary/contents/mattei.txt

    What am I doing wrong?

    Ps: sorry for asking this here if this is not the right place to

    opened by elect86 0
  • Response doc is misleading - .asJson is missing

    Response doc is misleading - .asJson is missing

    The doc says there's .asJson extension method, but there is nohing in sources, perhabs it's lost when factoring out jackson dependency. Note that kohttp-jackson also don't have .asJson method.

    opened by ivan-klass 1
  • Bump kohttp version to work with latest Android

    Bump kohttp version to work with latest Android

    The currently used kohttp version is 3.14.2 which is not working with Android level 30+

    According to this stackoverflow question bumping okhttp to version 4.9.0 should fix the problem

    opened by christian-draeger 6
Releases(0.12.0)
Owner
Sergei Rybalkin
Software engineer @facebook. Former @alibaba @yandex
Sergei Rybalkin
Android Easy Http - Simplest android http request library.

Android Easy Http Library ็น้ซ”ไธญๆ–‡ๆ–‡ๆช” About Android Easy Http Library Made on OkHttp. Easy to do http request, just make request and listen for the respons

null 13 Sep 30, 2022
Ktorfit - a HTTP client/Kotlin Symbol Processor for Kotlin Multiplatform (Js, Jvm, Android, iOS, Linux) using KSP and Ktor clients inspired by Retrofit

Ktorfit is a HTTP client/Kotlin Symbol Processor for Kotlin Multiplatform (Js, Jvm, Android, iOS, Linux) using KSP and Ktor clients inspired by Retrofit

Jens Klingenberg 637 Dec 25, 2022
Multiplatform coroutine-based HTTP client wrapper for Kotlin

networkinkt This is a lightweight HTTP client for Kotlin. It relies on coroutines on both JS & JVM platforms. Here is a simple GET request: val text =

Egor Zhdan 31 Jul 27, 2022
Asynchronous Http and WebSocket Client library for Java

Async Http Client Follow @AsyncHttpClient on Twitter. The AsyncHttpClient (AHC) library allows Java applications to easily execute HTTP requests and a

AsyncHttpClient 6k Jan 8, 2023
Squareโ€™s meticulous HTTP client for the JVM, Android, and GraalVM.

OkHttp See the project website for documentation and APIs. HTTP is the way modern applications network. Itโ€™s how we exchange data & media. Doing HTTP

Square 43.4k Jan 5, 2023
A type-safe HTTP client for Android and the JVM

Retrofit A type-safe HTTP client for Android and Java. For more information please see the website. Download Download the latest JAR or grab from Mave

Square 41k Jan 5, 2023
Asynchronous socket, http(s) (client+server) and websocket library for android. Based on nio, not threads.

AndroidAsync AndroidAsync is a low level network protocol library. If you are looking for an easy to use, higher level, Android aware, http request li

Koushik Dutta 7.3k Jan 2, 2023
Unirest in Java: Simplified, lightweight HTTP client library.

Unirest for Java Install With Maven: <!-- Pull in as a traditional dependency --> <dependency> <groupId>com.konghq</groupId> <artifactId>unire

Kong 2.4k Jan 5, 2023
An android asynchronous http client built on top of HttpURLConnection.

Versions 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 Version 1.0.6 Description An android asynchronous http client based on HttpURLConnection. Updates U

David 15 Mar 29, 2020
Unirest in Java: Simplified, lightweight HTTP client library.

Unirest for Java Install With Maven: <!-- Pull in as a traditional dependency --> <dependency> <groupId>com.konghq</groupId> <artifactId>unire

Kong 2.4k Dec 24, 2022
Kotlin-echo-client - Echo client using Kotlin with Ktor networking library

Overview This repository contains an echo server implemented with Kotlin and kto

Elliot Barlas 2 Sep 1, 2022
HttpMocker is a simple HTTP mocking library written in Kotlin to quickly and easily handle offline modes in your apps

HttpMocker HttpMocker is a very lightweight Kotlin library that allows to mock HTTP calls relying on either OkHttp or the Ktor client libraries. It ca

David Blanc 174 Nov 28, 2022
Kotlin HTTP requests library. Similar to Python requests.

khttp khttp is a simple library for HTTP requests in Kotlin. It functions similarly to Python's requests module. import khttp.get fun main(args: Arra

Anna Clemens 466 Dec 20, 2022
The easiest HTTP networking library for Kotlin/Android

Fuel The easiest HTTP networking library for Kotlin/Android. You are looking at the documentation for 2.x.y.. If you are looking for the documentation

Kittinun Vantasin 4.3k Jan 8, 2023
Ktor-Client this is the client part that uses the Ktor server

Ktor-Client this is the client part that uses the Ktor server Previews Tech stack & Open source libraries Minimum SDK level 21. Kotlin+ Coroutines + F

Mohamed Emad 4 Dec 23, 2022
Simple kafka client for monitoring topic events. Client has UI powered by Darklaf

kafka-client Simple kafka client for monitoring topic values. How to start $ java -jar kafka-client-1.0.jar How to use specify kafka hosts in config.y

Salavat 0 Jun 3, 2022
HTTP Server for Android Instrumentation tests

RESTMock REST API mocking made easy. RESTMock is a library working on top of Square's okhttp/MockWebServer. It allows you to specify Hamcrest matchers

Andrzej Chmielewski 750 Dec 29, 2022
๐Ÿš€ A Complete Fast Android Networking Library that also supports HTTP/2 ๐Ÿš€

Fast Android Networking Library About Fast Android Networking Library Fast Android Networking Library is a powerful library for doing any type of netw

AMIT SHEKHAR 5.5k Dec 27, 2022
Java HTTP Request Library

Http Request A simple convenience library for using a HttpURLConnection to make requests and access the response. This library is available under the

Kevin Sawicki 3.3k Jan 6, 2023