{"id":13536991,"url":"https://github.com/respawn-app/ApiResult","last_synced_at":"2025-04-02T03:31:31.272Z","repository":{"id":190791521,"uuid":"683362703","full_name":"respawn-app/ApiResult","owner":"respawn-app","description":"Kotlin Multiplatform Error Handling. Catch and handle all errors. Avoid Crashes. Like Arrow but without the black magic. No boilerplate. No performance overhead. 90+ operators.","archived":false,"fork":false,"pushed_at":"2025-01-05T15:48:55.000Z","size":396,"stargazers_count":44,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-01-05T16:19:30.955Z","etag":null,"topics":["android","arrow","arrow-kt","error-handling","functional-programming","kmm","kmp","kotlin","monad","result","validation"],"latest_commit_sha":null,"homepage":"https://opensource.respawn.pro/ApiResult","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/respawn-app.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"docs/CONTRIBUTING.md","funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":"docs/roadmap.md","authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-08-26T10:23:21.000Z","updated_at":"2025-01-05T15:48:59.000Z","dependencies_parsed_at":"2023-12-25T10:36:50.100Z","dependency_job_id":"356b863a-efca-4728-a9c2-c1004df3a771","html_url":"https://github.com/respawn-app/ApiResult","commit_stats":{"total_commits":43,"total_committers":1,"mean_commits":43.0,"dds":0.0,"last_synced_commit":"ad8b17416357348c202c281e5f9ed72088236572"},"previous_names":["respawn-app/apiresult"],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/respawn-app%2FApiResult","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/respawn-app%2FApiResult/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/respawn-app%2FApiResult/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/respawn-app%2FApiResult/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/respawn-app","download_url":"https://codeload.github.com/respawn-app/ApiResult/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246751244,"owners_count":20827857,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","arrow","arrow-kt","error-handling","functional-programming","kmm","kmp","kotlin","monad","result","validation"],"created_at":"2024-08-01T09:00:53.222Z","updated_at":"2025-04-02T03:31:31.266Z","avatar_url":"https://github.com/respawn-app.png","language":"Kotlin","funding_links":[],"categories":["Libraries"],"sub_categories":["Utility","🚀 Language extensions"],"readme":"# ApiResult\n\n[![CI](https://github.com/respawn-app/ApiResult/actions/workflows/ci.yml/badge.svg)](https://github.com/respawn-app/ApiResult/actions/workflows/ci.yml)\n![License](https://img.shields.io/github/license/respawn-app/ApiResult)\n![GitHub last commit](https://img.shields.io/github/last-commit/respawn-app/ApiResult)\n![Issues](https://img.shields.io/github/issues/respawn-app/ApiResult)\n![GitHub top language](https://img.shields.io/github/languages/top/respawn-app/ApiResult)\n[![CodeFactor](https://www.codefactor.io/repository/github/respawn-app/ApiResult/badge)](https://www.codefactor.io/repository/github/respawn-app/ApiResult)\n[![AndroidWeekly #556](https://androidweekly.net/issues/issue-556/badge)](https://androidweekly.net/issues/issue-556/)\n\n![badge][badge-android] ![badge][badge-jvm] ![badge][badge-js] ![badge][badge-nodejs] ![badge][badge-linux] ![badge][badge-windows] ![badge][badge-wasm] ![badge][badge-ios] ![badge][badge-mac] ![badge][badge-watchos] ![badge][badge-tvos]\n\nApiResult is a Kotlin Multiplatform declarative error handling framework that is performant, easy to use and\nfeature-rich.\n\nApiResult is [Railway Programming](https://proandroiddev.com/railway-oriented-programming-in-kotlin-f1bceed399e5) and\nfunctional\nerror handling **on steroids**.\n\n## Why use a library instead of try/catch?\n\nExceptions in Kotlin are **unchecked**. \nEach time you call a function, it can throw and crash you app. \nWith ApiResult, you will never have this problem again.\n\n* ApiResult **forces** your code users to handle errors. Forget about unhandled exceptions and unexpected crashes.\n* ApiResult is **lightweight**. The library creates no objects and has ~0 performance impact.\n* Use 90+ operators covering most of possible use cases to turn your\n  code from imperative and procedural to declarative and functional, which is more readable and extensible.\n* Core library has **no dependencies**. No need to worry about unexpected junk in your codebase.\n* This isn't like Arrow, where with a monad you get a bunch of extra black magic. This framework focuses on **error handling** only.\n* ApiResult is fully compatible with Exceptions and Coroutines. Just wrap a call and it will work.\n* The library has 140+ tests for 92% operator coverage. Expect long-term support and stability.\n\n## How do I use it?\n\n```kotlin\n// wrap a result of any computation and expose the result\nclass BillingRepository(private val api: RestApi) {\n\n    suspend fun getSubscriptions() = ApiResult {\n        api.getSubscriptions()\n    } // -\u003e ApiResult\u003cList\u003cSubscription\u003e?\u003e\n}\n\n// obtain and handle the result in the client code\nfun onClickVerify() {\n    val state: SubscriptionState = billingRepository.getSubscriptions()\n        .errorOnNull() // map nulls to error states with compile-time safety\n        .recover\u003cNotSignedInException, _\u003e { emptyList() } // recover from some or all errors\n        .require { securityRepository.isDeviceTrusted() } // conditionally fail the chain\n        .mapValues(::SubscriptionModel) // map list items\n        .filter { it.isPurchased } // filter\n        .mapError\u003cNetworkException, _, _\u003e { e -\u003e BillingException(cause = e) } // map exceptions\n        .then { validateSubscriptions(it) } // execute a computation and continue with its result, propagating errors\n        .chain { updateGracePeriod(it) } // execute another computation, and if it fails, stop the chain\n        .onError { subscriptionService.disconnect() } // executed on error\n        .onEmpty { return SubscriptionState.NotSubscribed } // use non-local returns and short-circuit evaluation\n        .fold(\n            onSuccess = { SubscriptionState.Subscribed(it) },\n            onError = { SubscriptionState.Error(it) },\n        ) // unwrap the result to another value\n    // ...\n}\n```\n\n## Quickstart\n\n* Documentation:\n  [![Docs](https://img.shields.io/website?down_color=red\u0026down_message=Offline\u0026label=Docs\u0026up_color=green\u0026up_message=Online\u0026url=https%3A%2F%2Fopensource.respawn.pro%2FApiResult%2F%23%2F)](https://opensource.respawn.pro/ApiResult)\n* KDoc:\n  [![Javadoc](https://javadoc.io/badge2/pro.respawn.apiresult/core/javadoc.svg)](https://opensource.respawn.pro/ApiResult/javadocs)\n* Latest version:\n  ![Maven Central](https://img.shields.io/maven-central/v/pro.respawn.apiresult/core?label=Maven%20Central)\n\n```toml\n[versions]\napiresult = \"\u003c Badge above 👆🏻 \u003e\"\n\n[dependencies]\napiresult = { module = \"pro.respawn.apiresult:core\", version.ref = \"apiresult\" } \n```\n-----\n```kotlin\ndependencies {\n    // usually you will want to expose ApiResult types in your module APIs, so consider using api() for the dependency\n    commonMainApi(\"pro.respawn.apiresult:core:\u003cversion\u003e\")\n}\n```\n\nReady to try? Start with reading the [Quickstart Guide](https://opensource.respawn.pro/ApiResult/#/quickstart).\n\n## License\n\n```\n   Copyright 2022-2025 Respawn Team and contributors\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n```\n\n[badge-android]: http://img.shields.io/badge/-android-6EDB8D.svg?style=flat\n\n[badge-android-native]: http://img.shields.io/badge/support-[AndroidNative]-6EDB8D.svg?style=flat\n\n[badge-jvm]: http://img.shields.io/badge/-jvm-DB413D.svg?style=flat\n\n[badge-js]: http://img.shields.io/badge/-js-F8DB5D.svg?style=flat\n\n[badge-js-ir]: https://img.shields.io/badge/support-[IR]-AAC4E0.svg?style=flat\n\n[badge-nodejs]: https://img.shields.io/badge/-nodejs-68a063.svg?style=flat\n\n[badge-linux]: http://img.shields.io/badge/-linux-2D3F6C.svg?style=flat\n\n[badge-windows]: http://img.shields.io/badge/-windows-4D76CD.svg?style=flat\n\n[badge-wasm]: https://img.shields.io/badge/-wasm-624FE8.svg?style=flat\n\n[badge-apple-silicon]: http://img.shields.io/badge/support-[AppleSilicon]-43BBFF.svg?style=flat\n\n[badge-ios]: http://img.shields.io/badge/-ios-CDCDCD.svg?style=flat\n\n[badge-mac]: http://img.shields.io/badge/-macos-111111.svg?style=flat\n\n[badge-watchos]: http://img.shields.io/badge/-watchos-C0C0C0.svg?style=flat\n\n[badge-tvos]: http://img.shields.io/badge/-tvos-808080.svg?style=flat\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frespawn-app%2FApiResult","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frespawn-app%2FApiResult","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frespawn-app%2FApiResult/lists"}