{"id":21026367,"url":"https://github.com/nimblehq/jsonapi-kotlin","last_synced_at":"2025-11-11T20:41:56.091Z","repository":{"id":76744626,"uuid":"539351996","full_name":"nimblehq/jsonapi-kotlin","owner":"nimblehq","description":"A Kotlin Multiplatform JSON:API library that supports decoding JSON:API string response","archived":false,"fork":false,"pushed_at":"2023-04-20T04:29:45.000Z","size":87,"stargazers_count":4,"open_issues_count":0,"forks_count":2,"subscribers_count":4,"default_branch":"develop","last_synced_at":"2025-07-28T09:46:14.370Z","etag":null,"topics":["android","ios","json","json-api","jsonapi","kmm","kotlin","kotlin-multiplatform","kotlin-multiplatform-mobile","kotlinmultiplatform","multiplatform"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nimblehq.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-09-21T07:04:47.000Z","updated_at":"2024-05-27T04:35:57.000Z","dependencies_parsed_at":null,"dependency_job_id":"84d4afed-15e8-437f-9523-d015618e26bd","html_url":"https://github.com/nimblehq/jsonapi-kotlin","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":"nimblehq/git-template","purl":"pkg:github/nimblehq/jsonapi-kotlin","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nimblehq%2Fjsonapi-kotlin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nimblehq%2Fjsonapi-kotlin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nimblehq%2Fjsonapi-kotlin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nimblehq%2Fjsonapi-kotlin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nimblehq","download_url":"https://codeload.github.com/nimblehq/jsonapi-kotlin/tar.gz/refs/heads/develop","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nimblehq%2Fjsonapi-kotlin/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":283929661,"owners_count":26918166,"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","status":"online","status_checked_at":"2025-11-11T02:00:06.610Z","response_time":65,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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","ios","json","json-api","jsonapi","kmm","kotlin","kotlin-multiplatform","kotlin-multiplatform-mobile","kotlinmultiplatform","multiplatform"],"created_at":"2024-11-19T11:44:18.608Z","updated_at":"2025-11-11T20:41:56.056Z","avatar_url":"https://github.com/nimblehq.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/nimblehq/jsonapi-kotlin/review_pull_request.yml?branch=develop)\n![GitHub Packages](https://img.shields.io/badge/version-0.1.0-blue)\n\n# JSON:API Kotlin\n\nKotlin module for mapping JSON response, in the format of [JSON:API](https://jsonapi.org) to objects.\n\nMade specifically for Kotlin Multiplatform Mobile (KMM).\n\n## Installation\n\nFollowing [Working with the Gradle registry](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-gradle-registry)\ndocs:\n\n- Add GitHub Packages repository to the root project `build.gradle.kts` at `allprojects` block.\n\n  ```\n  allprojects {\n      repositories {\n          ...\n          maven {\n             name = \"Github Packages\"\n             url = uri(\"https://maven.pkg.github.com/nimblehq/jsonapi-kotlin\")\n             credentials {\n                 username = GITHUB_USER\n                 password = GITHUB_TOKEN\n             }\n          }\n      }\n  }\n  ```\n\n  - GITHUB_USER: the developer's GitHub user to access GitHub Packages.\n  - GITHUB_TOKEN: the developer's GitHub personal access token with at least `packages:read` permission.\n\n- Open `build.gradle.kts` of `shared` module, or any KMM module that will use the library.\n\n  ```\n  kotlin {\n      sourceSets {\n          val commonMain by getting {\n              dependencies {\n                  implementation(\"co.nimblehq.jsonapi:core:${LATEST_VERSION}\")\n              }\n          }\n          ...\n      }\n      ...\n  }\n  ```\n\n## Usage\n\n- Use with `kotlinx.serialization.json.Json`. Call `decodeFromJsonApiString` to map string to object.\n\n  ```\n  @Serializable\n  data class ExampleModel(val title: String)\n  val body = \"\"\"\n  {\n    \"data\": {\n      \"type\": \"articles\",\n      \"id\": \"1\",\n      \"attributes\": {\n        \"title\": \"JSON:API paints my bikeshed!\"\n      }\n    }\n  }\n  \"\"\"\n  val json = Json {\n       prettyPrint = true\n       isLenient = true\n       ignoreUnknownKeys = true\n   }\n  val data = JsonApi(json).decodeFromJsonApiString\u003cExampleModel\u003e(body)\n  ```\n\n## Features\n\n### JSON:API\n\nThis library maps JSON response, in the format of [JSON:API](https://jsonapi.org).\n\n```\nval response = \"\"\"\n{\n  \"data\": {\n    \"type\": \"articles\",\n    \"id\": \"1\",\n    \"attributes\": {\n      \"title\": \"JSON:API paints my bikeshed!\",\n      \"body\": \"The shortest article. Ever.\",\n      \"created\": \"2015-05-22T14:56:29.000Z\",\n      \"updated\": \"2015-05-22T14:56:28.000Z\",\n      \"item_version\": 2\n    }\n  }\n}\n\"\"\"\n```\n\n```\n@Serializable\ndata class NetworkMockModel(\n    val title: String,\n    val body: String,\n    val created: String,\n    val updated: String,\n    @SerialName(\"item_version\")\n    val itemVersion: Int\n)\n\nval data = JsonApi(Json).decodeFromJsonApiString\u003cNetworkMockModel\u003e(response)\n```\n\n### Error\n\nReturns error if object failed to map or the API returns error\n\n```\nval response = \"\"\"\n{\n  \"errors\": [\n    {\n      \"source\": { \"pointer\": \"\" },\n      \"detail\":  \"Missing `data` Member at document's top level.\"\n    }\n  ]\n}\n\"\"\"\n```\n\n```\ntry {\n    val data = JsonApi(Json).decodeFromJsonApiString\u003cNetworkMockModel\u003e(response)\n} catch (e: JsonApiException) {\n    return e.errors.first().detail // Missing `data` Member at document's top level.\n}\n```\n\n### Array\n\n```\nval response = \"\"\"\n{\n  \"data\": [{\n    \"type\": \"articles\",\n    \"id\": \"1\",\n    \"attributes\": {\n      \"title\": \"JSON:API paints my bikeshed!\",\n      \"body\": \"The shortest article. Ever.\",\n      \"created\": \"2015-05-22T14:56:29.000Z\",\n      \"updated\": \"2015-05-22T14:56:28.000Z\",\n      \"item_version\": 2\n    }\n  }]\n}\n\"\"\"\n```\n\n```\n@Serializable\ndata class NetworkMockModel(\n    val title: String,\n    val body: String,\n    val created: String,\n    val updated: String,\n    @SerialName(\"item_version\")\n    val itemVersion: Int\n)\n\nval data = JsonApi(Json).decodeFromJsonApiString\u003cList\u003cNetworkMockModel\u003e\u003e(response)\n```\n\n### Relationship \u0026 Included\n\n`included` object will be mapped by `relationships` `type`.\n\n```\nval response = \"\"\"\n{\n  \"data\": {\n    \"type\": \"articles\",\n    \"id\": \"1\",\n    \"attributes\": {\n      \"title\": \"JSON:API paints my bikeshed!\",\n      \"body\": \"The shortest article. Ever.\",\n      \"created\": \"2015-05-22T14:56:29.000Z\",\n      \"updated\": \"2015-05-22T14:56:28.000Z\"\n    },\n    \"relationships\": {\n      \"author\": {\n        \"data\": {\"id\": \"42\", \"type\": \"people\"}\n      }\n    }\n  },\n  \"included\": [\n    {\n      \"type\": \"people\",\n      \"id\": \"42\",\n      \"attributes\": {\n        \"name\": \"John\",\n        \"age\": 80,\n        \"gender\": \"male\"\n      }\n    }\n  ]\n}\n\"\"\"\n```\n\n```\n@Serializable\ndata class NetworkIncludedMockModel(\n    val title: String,\n    val body: String,\n    val created: String,\n    val updated: String,\n    val author: People\n)\n\nval data = JsonApi(Json).decodeFromJsonApiString\u003cNetworkIncludedMockModel\u003e(response)\n```\n\n### Array Included\n\n```\nval response = \"\"\"\n{\n  \"data\": [{\n    \"type\": \"articles\",\n    \"id\": \"1\",\n    \"attributes\": {\n      \"title\": \"JSON:API paints my bikeshed!\",\n      \"body\": \"The shortest article. Ever.\",\n      \"created\": \"2015-05-22T14:56:29.000Z\",\n      \"updated\": \"2015-05-22T14:56:28.000Z\"\n    },\n    \"relationships\": {\n      \"author\": {\n        \"data\": {\"id\": \"42\", \"type\": \"people\"}\n      }\n    }\n  }],\n  \"included\": [\n    {\n      \"type\": \"people\",\n      \"id\": \"42\",\n      \"attributes\": {\n        \"name\": \"John\",\n        \"age\": 80,\n        \"gender\": \"male\"\n      }\n    }\n  ]\n}\n\"\"\"\n```\n\n```\n@Serializable\ndata class NetworkIncludedMockModel(\n    val title: String,\n    val body: String,\n    val created: String,\n    val updated: String,\n    val author: People\n)\n\nval data = JsonApi(Json).decodeFromJsonApiString\u003cList\u003cNetworkIncludedMockModel\u003e\u003e(response)\n```\n\n### Only Meta\n\nWhen mapping response with only `meta` and no `data`, pass the meta object as the resource type.\n\n```\nval response = \"\"\"\n{\n  \"meta\": {\n    \"message\": \"Success\"\n  }\n}\n\"\"\".trimIndent()\n```\n\n```\n@Serializable\ndata class NetworkOnlyMetaMockModel(\n    val message: String\n)\n\nval data = JsonApi(Json).decodeFromJsonApiString\u003cNetworkOnlyMetaMockModel\u003e(response)\n```\n\n### Meta\n\nUse `decodeWithMetaFromJsonApiString` instead of `decodeFromJsonApiString` to get `meta` along with object.\n\n```\nval response = \"\"\"\n{\n  \"data\": [{\n    \"type\": \"articles\",\n    \"id\": \"1\",\n    \"attributes\": {\n      \"title\": \"JSON:API paints my bikeshed!\",\n      \"body\": \"The shortest article. Ever.\",\n      \"created\": \"2015-05-22T14:56:29.000Z\",\n      \"updated\": \"2015-05-22T14:56:28.000Z\",\n      \"item_version\": 2\n    }\n  }],\n  \"meta\": {\n    \"page\": 2,\n    \"totalPages\": 13\n  }\n}\n\"\"\"\n```\n\n```\n@Serializable\ndata class NetworkMockModel(\n    val title: String,\n    val body: String,\n    val created: String,\n    val updated: String,\n    @SerialName(\"item_version\")\n    val itemVersion: Int\n)\n@Serializable\ndata class NetworkMetaMockModel(\n    val page: Int,\n    val totalPages: Int\n)\n\nval data = JsonApi(Json)\n  .decodeWithMetaFromJsonApiString\u003cList\u003cNetworkMockModel\u003e, NetworkMetaMockModel\u003e(\n    response\n  )\n```\n\n`decodeWithMetaFromJsonApiString` works with `single`, `array`, and `included`, same as `decodeFromJsonApiString`.\n\n## License\n\nThis project is Copyright (c) 2014 and onwards Nimble. It is free software and may be redistributed under the terms specified in the [LICENSE] file.\n\n[LICENSE]: /LICENSE\n\n## About\n\u003ca href=\"https://nimblehq.co/\"\u003e\n  \u003cpicture\u003e\n    \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://assets.nimblehq.co/logo/dark/logo-dark-text-160.png\"\u003e\n    \u003cimg alt=\"Nimble logo\" src=\"https://assets.nimblehq.co/logo/light/logo-light-text-160.png\"\u003e\n  \u003c/picture\u003e\n\u003c/a\u003e\n\nThis project is maintained and funded by Nimble.\n\nWe ❤️ open source and do our part in sharing our work with the community!\nSee [our other projects][community] or [hire our team][hire] to help build your product.\n\nWant to join? [Check out our Jobs][jobs]!\n\n[community]: https://github.com/nimblehq\n[hire]: https://nimblehq.co/\n[jobs]: https://jobs.nimblehq.co/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnimblehq%2Fjsonapi-kotlin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnimblehq%2Fjsonapi-kotlin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnimblehq%2Fjsonapi-kotlin/lists"}