{"id":15985633,"url":"https://github.com/ahoo-wang/coapi","last_synced_at":"2025-07-29T23:32:40.391Z","repository":{"id":217788728,"uuid":"744300599","full_name":"Ahoo-Wang/CoApi","owner":"Ahoo-Wang","description":"Streamlining HTTP client definition in Spring 6, CoApi provides zero boilerplate code auto-configuration for more convenient and efficient interface calls | 简化 Spring 6 中 HTTP 客户端定义，提供零样板代码自动配置，让接口调用更便捷高效","archived":false,"fork":false,"pushed_at":"2025-07-24T23:15:23.000Z","size":475,"stargazers_count":6,"open_issues_count":1,"forks_count":1,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-07-25T04:59:49.175Z","etag":null,"topics":["http-client","httpinterface","openfeign","reactive","spring-boot","spring-cloud","webclient","webflux"],"latest_commit_sha":null,"homepage":"https://deepwiki.com/Ahoo-Wang/CoApi/1-overview","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/Ahoo-Wang.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,"zenodo":null}},"created_at":"2024-01-17T02:28:50.000Z","updated_at":"2025-07-24T23:15:26.000Z","dependencies_parsed_at":"2024-05-31T02:29:23.066Z","dependency_job_id":"a4da160d-4b32-444f-8fe8-af9e93551cfd","html_url":"https://github.com/Ahoo-Wang/CoApi","commit_stats":{"total_commits":103,"total_committers":2,"mean_commits":51.5,"dds":"0.46601941747572817","last_synced_commit":"d2ce5ab6639f2188e9e5b059d003a33f04bb7ed9"},"previous_names":["ahoo-wang/coapi"],"tags_count":46,"template":false,"template_full_name":null,"purl":"pkg:github/Ahoo-Wang/CoApi","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ahoo-Wang%2FCoApi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ahoo-Wang%2FCoApi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ahoo-Wang%2FCoApi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ahoo-Wang%2FCoApi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Ahoo-Wang","download_url":"https://codeload.github.com/Ahoo-Wang/CoApi/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ahoo-Wang%2FCoApi/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267780038,"owners_count":24143201,"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-07-29T02:00:12.549Z","response_time":2574,"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":["http-client","httpinterface","openfeign","reactive","spring-boot","spring-cloud","webclient","webflux"],"created_at":"2024-10-08T02:23:27.834Z","updated_at":"2025-07-29T23:32:40.351Z","avatar_url":"https://github.com/Ahoo-Wang.png","language":"Kotlin","readme":"# CoApi - HTTP Client that supports both reactive programming and synchronous programming models\n\n[中文文档](./README.zh-CN.md)\n\n[![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://github.com/Ahoo-Wang/CoApi/blob/mvp/LICENSE)\n[![GitHub release](https://img.shields.io/github/release/Ahoo-Wang/CoApi.svg)](https://github.com/Ahoo-Wang/CoApi/releases)\n[![Maven Central](https://maven-badges.herokuapp.com/maven-central/me.ahoo.coapi/coapi-api/badge.svg)](https://maven-badges.herokuapp.com/maven-central/me.ahoo.coapi/coapi-api)\n[![Codacy Badge](https://app.codacy.com/project/badge/Grade/709bea2aec1d4cfd85991edf66b5ccbc)](https://app.codacy.com/gh/Ahoo-Wang/CoApi/dashboard?utm_source=gh\u0026utm_medium=referral\u0026utm_content=\u0026utm_campaign=Badge_grade)\n[![Codecov](https://codecov.io/gh/Ahoo-Wang/CoApi/graph/badge.svg?token=ayVd7lthB6)](https://codecov.io/gh/Ahoo-Wang/CoApi)\n[![Integration Test Status](https://github.com/Ahoo-Wang/CoApi/actions/workflows/integration-test.yml/badge.svg)](https://github.com/Ahoo-Wang/CoApi)\n[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/Ahoo-Wang/CoApi)\n\nIn Spring Framework 6, a new HTTP\nclient, [Spring6 HTTP Interface](https://docs.spring.io/spring-framework/reference/integration/rest-clients.html#rest-http-interface),\nhas been introduced. This interface allows developers to define HTTP services as Java interfaces using the\n`@HttpExchange` annotation.\n\nHowever, the current *Spring* ecosystem does not yet provide support for automatic configuration, and developers need to\nimplement the configuration themselves.\n\nWhile the *Spring* ecosystem already\nhas [Spring Cloud OpenFeign](https://github.com/spring-cloud/spring-cloud-openfeign), it lacks support for the reactive\nprogramming model. To address this, *Spring Cloud OpenFeign* recommends an alternative\nsolution, [feign-reactive](https://github.com/PlaytikaOSS/feign-reactive). However, this alternative is currently not\nactively maintained and does not support Spring Boot 3.2.x.\n\n**CoApi** is here to help with zero-boilerplate code auto-configuration similar to *Spring Cloud OpenFeign*, as well as\nsupport for both reactive and synchronous programming models. Developers only need to define the interface, and it is\neasy to use.\n\n## Installation\n\n\u003e Use *Gradle(Kotlin)* to install dependencies\n\n```kotlin\nimplementation(\"me.ahoo.coapi:coapi-spring-boot-starter\")\n```\n\n\u003e Use *Gradle(Groovy)* to install dependencies\n\n```groovy\nimplementation 'me.ahoo.coapi:coapi-spring-boot-starter'\n```\n\n\u003e Use *Maven* to install dependencies\n\n```xml\n\n\u003cdependency\u003e\n    \u003cgroupId\u003eme.ahoo.coapi\u003c/groupId\u003e\n    \u003cartifactId\u003ecoapi-spring-boot-starter\u003c/artifactId\u003e\n    \u003cversion\u003e${coapi.version}\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n## Usage\n\n### Define `CoApi` - a third-party interface\n\n\u003e `baseUrl` : Define the base address of the request, which can be obtained from the configuration file, for example:\n`baseUrl = \"${github.url}\"`, `github.url` is the configuration item in the configuration file\n\n```java\n\n@CoApi(baseUrl = \"${github.url}\")\npublic interface GitHubApiClient {\n\n    @GetExchange(\"repos/{owner}/{repo}/issues\")\n    Flux\u003cIssue\u003e getIssue(@PathVariable String owner, @PathVariable String repo);\n}\n```\n\n\u003e Configuration：\n\n```yaml\ngithub:\n  url: https://api.github.com\n```\n\n### Define `CoApi` - Client Load Balancing\n\nWhen using client load balancing, you need to introduce dependencies first:\n\n```kotlin\nimplementation(\"org.springframework.cloud:spring-cloud-starter-loadbalancer\")\n```\n\n1. Use the `serviceId` parameter definition:\n\n```java\n\n@CoApi(serviceId = \"github-service\")\npublic interface ServiceApiClient {\n\n    @GetExchange(\"repos/{owner}/{repo}/issues\")\n    Flux\u003cIssue\u003e getIssue(@PathVariable String owner, @PathVariable String repo);\n}\n```\n\n2. Client load balancing protocol (`lb://`) definition via `baseUrl` parameter:\n\n```java\n\n@CoApi(baseUrl = \"lb://github-service\")\npublic interface ServiceApiClient {\n\n}\n```\n\n### Using `CoApi`\n\n```kotlin\n@RestController\nclass GithubController(\n    private val gitHubApiClient: GitHubApiClient,\n    private val serviceApiClient: ServiceApiClient\n) {\n\n    @GetMapping(\"/baseUrl\")\n    fun baseUrl(): Flux\u003cIssue\u003e {\n        return gitHubApiClient.getIssue(\"Ahoo-Wang\", \"CoApi\")\n    }\n\n    @GetMapping(\"/serviceId\")\n    fun serviceId(): Flux\u003cIssue\u003e {\n        return serviceApiClient.getIssue(\"Ahoo-Wang\", \"CoApi\")\n    }\n}\n```\n\n## Case Reference\n\n[Example](./example)\n\n### Service Provider\n\n[Example-Provider](./example/example-provider-server)\n\n```mermaid\nclassDiagram\ndirection BT\nclass TodoApi {\n\u003c\u003cInterface\u003e\u003e\n\n}\nclass TodoClient {\n\u003c\u003cInterface\u003e\u003e\n\n}\nclass TodoController\n\nTodoClient  --\u003e  TodoApi \nTodoController  ..\u003e  TodoApi\n```\n\n- `TodoApi` : A common contract between the client consumer and the service provider is defined to prevent the risk of\n  duplicate redundant definitions and to eliminate inconsistencies between the service provider implementation and the\n  client SDK.\n- `TodoClient` :The client consumer accesses the service provider's API via `TodoClient`.\n- `TodoController` : The service provider is responsible for implementing the `TodoApi` interface.\n\n#### Define API\n\n```kotlin\n@HttpExchange(\"todo\")\ninterface TodoApi {\n\n    @GetExchange\n    fun getTodo(): Flux\u003cTodo\u003e\n}\n```\n\n#### Define Client\n\n```kotlin\n@CoApi(serviceId = \"provider-service\")\ninterface TodoClient : TodoApi\n```\n\n#### Implement API\n\n```kotlin\n@RestController\nclass TodoController : TodoApi {\n    override fun getTodo(): Flux\u003cTodo\u003e {\n        return Flux.range(1, 10)\n            .map {\n                Todo(\"todo-$it\")\n            }\n    }\n}\n```\n\n### Service Consumer\n\n[Example-Consumer](./example/example-consumer-server)\n\nThe service consumer turns on the automatic configuration of the `CoApi` via the `@EnableCoApi` annotation.\n\n```kotlin\n@EnableCoApi(clients = [TodoClient::class])\n@SpringBootApplication\nclass ConsumerServer\n```\n\n```kotlin\n@RestController\nclass TodoController(private val todoClient: TodoClient) {\n\n    @GetExchange\n    fun getProviderTodo(): Flux\u003cTodo\u003e {\n        return todoClient.getTodo()\n    }\n}\n```","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fahoo-wang%2Fcoapi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fahoo-wang%2Fcoapi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fahoo-wang%2Fcoapi/lists"}