Skip to content

Latest commit

 

History

History
92 lines (61 loc) · 4.79 KB

File metadata and controls

92 lines (61 loc) · 4.79 KB

http-api-client

A Kotlin MPP library that can be used as a foundation to build clients (SDKs) for HTTP based APIs.

📝 This library is still in active development and may break compatibility in future releases

Usage

Include in your dependencies

JVM (Android)

dependencies {
    implementation "com.github.RedCrewOS.api-sdk-creator-mpp:http-api-client:http-api-client_v0.5.0"
}

iOS

TODO

Motivation

To understand the motivation behind building this library, and the design decisions, see the original motivation doc

This is a Kotlin port of the JS library. A lot of the type and function names have been carried over, however there are some important implementation differences.

Arrow

In order to have the ability to return errors and data from functions, and having access to ADTs in Kotlin, a library called Arrow is used. The Arrow docs have a good intro to Monads and error handling with Arrow.

Threading model

Arrow and thus this library uses Kotlin Coroutines to achieve concurrency. Because of that, most of the functions in this library are suspendable which allows non-blocking functions to be composed together. That means that users of the functions in this library will either have to be suspending functions, or launch a new Coroutine in order to use the functions.

SDK developers will have to decide how to allow client applications to decide the Dispatcher that the Coroutines use in order to be executed on the correct thread.

This is very important in UI applications (eg: Android apps) where IO work should be performed on the IO Dispatcher so that a background thread is used, to prevent the UI being blocked on IO.

It's worth noting that because the functions in this library never throw, exceptions in Coroutines can't be silently dropped and will always be returned in an Either.Left However if SDK developers choose the throw an exception, application developers will still have to make sure that they can handle exceptions thrown within Coroutines properly.

Asynchronous task modelling

While Crocks (in Javascript) has the Async monad to represent chainable units of concurrent work, Arrow uses Kotlin suspend functions instead of a Monad. As a result, ideas from the JS version of api-sdk-creator had to be reworked to fit with this paradigm.

One of the consequences of using suspend functions is that the orthodox Monad methods of map chain/flatMap etc can't be used. Thankfully Arrow offers monad comprehensions which allow us to write code that composes monads together (like Crock's chaining). While the code reads like imperative code, monad comprehensions will exit early if the result of binding a result is not mappable, etc. This preserves the monad semantics we want (Option, Either, etc) in code that has a lot less boilerplate, which is nice in a statically typed language.

Invoke operator overloading

Because Kotlin is a statically typed language it is does not support currying lambdas with generic type parameters where the generic type is not part of the entire function signature. For example, fun gsonUnmarshaller(gson: Gson): (KClass<T>) -> Unmarshaller<T> does not compile.

We overcome this by using invoke operator overloading. See the docs on GenericTypeCurriedFunction for more details on the implementation.

References

Docs

Read the 📘 reference docs

Examples

See the platform examples