GithubHelp home page GithubHelp logo

kohttp's Introduction

Kotlin dsl for http

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

Kotlin DSL http client

Download

gradle kotlin DSL:

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

gradle groovy DSL:

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

maven:

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

Usage

Sync http calls

GET

String.httpGet() extension
val response: Response = "https://google.com/search?q=iphone".httpGet()
GET with request parameters
val response: Response = httpGet {
   host = "google.com"
   path = "/search"
   param {
       "q" to "iphone"
       "safe" to "off"
   }
}

or

val response: Response = httpGet {
   url("https://google.com/search")
   param {
       "q" to "iphone"
       "safe" to "off"
   }
}
GET with header and cookies
val response: Response = httpGet {
    host = "github.com"
    path = "/search"

    header {
        "username" to "rybalkinsd"
        "security-policy" to json {
            "base-uri" to "none"
            "expect-ct" to json {
                "max-age" to 2592000
                "report-uri" to "foo.com/bar"
            }
            "script-src" to listOf("github.com", "github.io")
        }

        cookie {
            "user_session" to "toFycNV"
            "expires" to "Fri, 21 Dec 2018 09:29:55 -0000"
        }
    }

    param { ... }
}

POST

POST with form body.

form body has a application/x-www-form-urlencoded content type

val response: Response = httpPost {
    host = "postman-echo.com"
    path = "/post"

    param { ... }
    header { ... }
    
    body {
        form {                              //  Resulting form will not contain ' ', '\t', '\n'
            "login" to "user"               //  login=user&
            "email" to "[email protected]" //  [email protected]
        }
    }
    // or
    body {
        form("login=user&[email protected]")
    }
}
POST with json body.

json body has a application/json content type

val response: Response = httpPost {
    host = "postman-echo.com"
    path = "/post"

    param { ... }
    header { ... }
    
    body {                                  //  Resulting json will not contain ' ', '\t', '\n'
        json {                              //  {
            "login" to "user"               //      "login": "user",
            "email" to "[email protected]" //      "email": "[email protected]" 
        }                                   //  }
    }
    // or
    body {
        json("""{"login":"user","email":"[email protected]"}""")
    }
}
POST with various content type

In addition to form or json body content types it is possible to declare a custom content type.

body DSL support three data sources: file(), bytes() and string()

httpPost {
    body("application/json") {
        string("""{"login":"user","email":"[email protected]"}""")
    }
}
val imageFile = File(getResource("/cat.gif").toURI())
httpPost {
    body(type = "image/gif") {
        file(imageFile)
    }
}
httpPost {
    body { // content type is optional, null by default
        bytes("string of bytes".toByteArray())
    }
}
POST with multipart body
val response = httpPost {
    url("http://postman-echo.com/post")

    multipartBody {
        +form("cat", File(this.javaClass.getResource("/cat.gif").toURI()))
        +form("dog", File("/mydog.img"))
    }
}

HEAD

You can use same syntax as in GET

val response = httpHead { }

PUT

You can use same syntax as in POST

val response = httpPut { }

PATCH

You can use same syntax as in POST

val response = httpPatch { }

DELETE

You can use same syntax as in POST

val response = httpDelete { }

Upload files

Upload DSL

You can upload file by URI or File

val fileUri = this.javaClass.getResource("/cat.gif").toURI()

val response = upload {
    url("http://postman-echo.com/post")
    file(fileUri)
}

Upload File extensions

val file = File(this.javaClass.getResource("/cat.gif").toURI())
val response = file.upload( string or url )

Upload URI extensions

val fileUri = this.javaClass.getResource("/cat.gif").toURI()
val response = fileUri.upload( string or url )

Async http calls

async GET

String.asyncHttpGet() extension function

This function starts a new coroutine with Unconfined dispatcher.

val response: Deferred<Response> = "https://google.com/search?q=iphone".asyncHttpGet()
asyncHttpGet call
val response: Deferred<Response> = asyncHttpGet {
    host = "google.com"
    path = "/search"
    header { ... }
    param { ... }
}

Response usage

Kohttp methods return okhttp3.Response which is AutoClosable It's strictly recommended to access it with use to prevent resource leakage.

val response = httpGet { ... }

reponse.use {
    ...
}

Interceptors

Kohttp provides a DSL to add interceptors. Custom Interceptors can be defined by implementing the okhttp3.Interceptors. Interceptors are added by forking the defaultHttpClient.

val forkedClient = defaultHttpClient.fork {
    interceptors {
          +interceptor1
          +interceptor2
    }
 }

Built-in Interceptors

  • Logging Interceptor: A Request Logging Interceptor.

    Parameters:

    1. log: (String) -> Unit = ::println: function as a parameter to consume the log message. It defaults to println. Logs Request body when present.

    Usage:

    val client = defaultHttpClient.fork {
                    interceptors {
                        +LoggingInterceptor()
                    }
                }

    Sample Output: [2019-01-28T04:17:42.885Z] GET 200 - 1743ms https://postman-echo.com/get

  • Signing Interceptor: Enables signing of query parameters. Allowing creation of presigned URLs.

    Parameters:

    1. parameterName: String: The name of the parameter with signed key
    2. signer: HttpUrl.() -> String: Function with okhttp3.HttpUrl as a receiver to sign the request parameter

    Usage:

    val client = defaultHttpClient.fork {
                    interceptors {
                        +SigningInterceptor("key") {
                            val query = (query() ?: "").toByteArray()
                            urlEncoder.encodeToString(md5.digest(query))
                        }
                    }
                }

Customization

defaultClientPool customization

Kohttp provides a defaultClientPool to have a single endpoint for your http request.

It is possible to customize defaultClientPool by setting kohttp.yaml in resource directory of your project.

You can check default values in io.github.rybalkinsd.kohttp.configuration.Config.kt All time values are in Milliseconds

client:
  connectTimeout: 5000
  readTimeout: 10000
  writeTimeout: 10000
  followRedirects: true
  followSslRedirects: true
  connectionPool:
    maxIdleConnections: 42
    keepAliveDuration: 10000

Fork HttpClient for specific tasks

Forked client uses exactly the same connection pool and dispatcher. However, it will custom parameters like custom timeouts, additional interceptors or others.

In this example below patientClient will share ConnectionPool with defaultHttpClient, however patientClient requests will have custom read timeout.

val patientClient = defaultHttpClient.fork {   
    readTimeout = 100_000 
}

Run HTTP methods on custom client

If defaultClientPool or forked client does not suit you for some reason, it is possible to create your own one.

// a new client with custom dispatcher, connection pool and ping interval
val customClient = client {
    dispatcher = ...
    connectionPool = ConnectionPool( ... )
    pingInterval = 1_000
}

Experimental

Eager response

Instead of .use { ... it.body?.string() ... } it is now possible to read response body as string. And also to map Headers to listOf<Header> to operate them easily.

val response: EagerResponse = "https://google.com/search?q=iphone".httpGet().eager()

// iterating over headers
response.headers.forEach { ... }

// manipulating body
response.body?.let { ... }
val response: EagerResponse = httpGet { }.eager()

// iterating over headers
response.headers.forEach { ... }

// manipulating body
response.body?.let { ... }

kohttp's People

Contributors

boxresin avatar bpaxio avatar gitter-badger avatar gokulchandra avatar rybalkinsd avatar shtykh avatar zsmb13 avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.