{"id":26872349,"url":"https://github.com/paradisehell/convex","last_synced_at":"2025-10-23T17:43:52.327Z","repository":{"id":48934300,"uuid":"345612415","full_name":"ParadiseHell/convex","owner":"ParadiseHell","description":"An elegant tool based on Retrofit to help developers just focus on business data.","archived":false,"fork":false,"pushed_at":"2021-07-06T16:54:27.000Z","size":2208,"stargazers_count":52,"open_issues_count":0,"forks_count":5,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-05-07T09:16:45.375Z","etag":null,"topics":["android","java","retrofit2","retrofit2-converter"],"latest_commit_sha":null,"homepage":"","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/ParadiseHell.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-03-08T10:11:13.000Z","updated_at":"2023-09-18T16:25:53.000Z","dependencies_parsed_at":"2022-09-13T04:14:18.352Z","dependency_job_id":null,"html_url":"https://github.com/ParadiseHell/convex","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ParadiseHell%2Fconvex","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ParadiseHell%2Fconvex/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ParadiseHell%2Fconvex/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ParadiseHell%2Fconvex/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ParadiseHell","download_url":"https://codeload.github.com/ParadiseHell/convex/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252847568,"owners_count":21813461,"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","java","retrofit2","retrofit2-converter"],"created_at":"2025-03-31T08:31:06.945Z","updated_at":"2025-10-23T17:43:47.286Z","avatar_url":"https://github.com/ParadiseHell.png","language":"Kotlin","readme":"![Convex](static/Convex.png)\n\n# Override\nConvex is an elegant tool based on [Retrofit](https://github.com/square/retrofit)\nto help developers just focus on business data.\n\nWith the ability of Convex you can process different **BaseResponse** simply\nand uniformly.\n\n# Background\nLots of Restful APIs' responses are designed as following :\n\n```json\n{\n\t\"code\" : 0,\n\t\"message\" : \"\",\n\t\"data\" : {}\n}\n```\n\nor\n\n```json\n{\n\t\"status\" : 0,\n\t\"message\" : \"\",\n\t\"data\" : {}\n}\n```\n\nand so on.\n\nSo when developers use **Retrofit**, they have to design a **BaseResponse**\nas following :\n\n```kotlin\ndata class BaseResponse\u003cT\u003e(\n\t@SerializedName(\"code\")\n\tval code : Int = 0,\n\t@SerializedName(\"message\")\n\tval message : String?,\n\t@SerializedName(\"data\")\n\tval data : T?\n)\n```\n\nAnd when define a service method they need to wrap business data with\n**BaseReponse** as following :\n\n```kotlin\ninterface UserService {\n\t@GET(\"/users\")\n\tsuspend fun getAllUsers() : BaseResponse\u003cList\u003cUser\u003e\u003e\n}\n```\n\n# Thoughts\n\nHanding **BaseResponse** is really boring and repetitive.😖\n\nIs there a way to just handle **BaseResponse** only once?🤔\n\nIs there a way to remove the business data wraper **BaseResponse**?🤔\n\nSo **Convex** comes out.🎉 🎉 🎉\n\n# How to use\n\nFor more details, please see the [ConvexTest](https://github.com/ParadiseHell/convex/blob/main/convex/src/test/kotlin/org/paradisehell/convex/ConvexTest.kt) or the [Android-Project](https://github.com/ParadiseHell/convex/blob/main/app/src/main/java/org/paradisehell/convex/MainActivity.kt).\n\n### Grab Convex from Maven Central\n\nIn your build.gradle :\n\n```gradle\ndependencies {\n    implementation \"org.paradisehell.convex:convex:1.0.0\"\n}\n```\n\n### Implement a ConvexTansformer\n\n```kotlin\nprivate class UserConvexTransformer : ConvexTransformer {\n\t@Throws(IOException::class)\n\toverride fun transform(original: InputStream): InputStream {\n\t\tTODO(\"Return the business data InputStream.\")\n\t}\n}\n```\n\n### Add ConvexConverterFactory to Retrofit\n\n```kotlin\nRetrofit.Builder()\n\t.baseUrl(\"https://users.com/\")\n\t// add ConvexConverterFactory first !!!\n\t.addConverterFactory(ConvexConverterFactory())\n\t.addConverterFactory(GsonConverterFactory.create())\n\t.build()\n```\n\n### Define service method with `Transformer` annotation\n\n```kotlin\ninterface UserService {\n\t@GET(\"/users\")\n\t@Transformer(UserConvexTransformer::class)\n\tsuspend fun getAllUsers() : List\u003cUser\u003e // No BaseResponse is needed anymore.👻👻👻\n}\n```\n\n**That's All, enjoy yourself with Convex.**\n\n# More convenience usage\n\nAs you can see below, every service's method need to annotation with `Transformer`,\nwhich is boring and repetitive. So `Convex` provide a plugin called `convex-booster`\nto automatic to do this work.\n\n### Add `booster-gradle-plugin` and `convex-booster` to classpath\n\nIn your root `build.gradle`\n\n```gradle\nbuildscript {\n    dependencies {\n        // booster\n        classpath \"com.didiglobal.booster:booster-gradle-plugin:3.3.1\"\n        // convex-booster\n        classpath \"org.paradisehell.convex:convex-booster:1.0.0\"\n    }\n}\n```\n\n### Apply booster plugin\n\nIn your app `build.gradle`\n```\nplugins {\n    id 'com.didiglobal.booster'\n}\n```\n\nor \n\n```\napply plugin: \"com.didiglobal.booster\"\n```\n\n### Define service with `Transformer` annotation\n\n```kotlin\n@Transformer(UserConvexTransformer::class)\ninterface UserService {\n\t@GET(\"/users\")\n\tsuspend fun getAllUsers() : List\u003cUser\u003e // No BaseResponse is needed anymore.👻👻👻\n}\n```\n\nIf you do not want `ConvexTransformer` to work with some service methods, you\ncan use `DisableTransformer` annotation with these method as following.\n\n```kotlin\n@Transformer(UserConvexTransformer::class)\ninterface UserService {\n\t@GET(\"/users\")\n\t@DisableTransformer // Convex will ignore UserConvexTransformer\n\tsuspend fun getAllUsers() : BaseResponse\u003cList\u003cUser\u003e\u003e\n}\n```\n\n# Thanks\n\n- [booter](https://github.com/didi/booster)\n\t- Optimizer for mobile applications.🚀🚀🚀\n\t- An elegant framework to process bytecode really simply.👍👍👍\n\nLicense\n=======\n\n    Copyright 2021 ParadiseHell.\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","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fparadisehell%2Fconvex","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fparadisehell%2Fconvex","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fparadisehell%2Fconvex/lists"}