This is a Kotlin-based asynchronous REST client for JIRA. In particular, it wraps the functionality of Atlassian's JIRA Rest client into Kotlin using the Arrow-kt library
Atlassian's JIRA Rest client is based on their own implementation of a Promise. That is, all methods return values nested into Promise.
Besides its own capabilities, Promise implements Future, thus, the Atlassian's client can be used rather easily with reactive libraries like RxJava and Project Reactor.
With JiraKlient we wanted to achieve two goals:
- Provide a functional client, with compose-able methods.
- Provide a tagless-final implementation, moving away of Atlassian's Promise
To achieve these we leverage the powers of Kleisli.
- JiraKlient: Client's algebra
- JiraKlientForMonoK: Implementation for Project Reactive's Mono
- JiraKlientForSingleK: Implementation for Rx2 Single
- JiraKlientForIO: Implementation for Arrow's IO
For starters, JiraKlient provides a tagless algebra. So, applications can use this abstraction instead of using Atlassian's Promise.
Most importantly, though, JiraKlient uses the Kleisli functional data type. This means that applications "describe" compose-able uses of the underlying Atlassian client, without actually calling it, until is required.
The following code creates a kleisli that returns an view of the Issue that contains the data of the issue and its transitions.
data class IssueView(val issue: Issue, val transitions: List<Transition>)
/**
* Conditional, reads.
* If there is a issue, then a call for transitions will be placed
*/
fun <F> JiraKlient<F>.getIssueView(issueKey: String): JiraKleisli<F, Option<IssueView>> =
fx(JIRA_KLEISLI) {
val issue = issues.getIssue(issueKey).asOptionT().bind()
val ts = issues.getTransitions(issue).asSomeT().bind()
IssueView(issue, ts)
}.value().fix()
To actually run the above code two things need to be provided
- An instance of the underlying Atlassian's JIRA client
- An instance of the JiraKlient, actually choosing effect F (Mono, Single or IO)
fun main() {
val jiraClient = TODO("Create the JIRA client")
val issueView : IO<IssueView> = JiraKlientForIO
.getIssueView("SOME_ISSUE_KEY")
.run(jiraClient).fix()
issueView
.unsafeRunSync()
.also{ println(it) }
client.close()
}