{"id":19337747,"url":"https://github.com/csini/spring-kafka-extensions","last_synced_at":"2026-02-12T16:03:16.119Z","repository":{"id":250279915,"uuid":"817331639","full_name":"Csini/spring-kafka-extensions","owner":"Csini","description":"spring-kafka-extensions is a library that makes an entity based reactive approach (rxjava) to apache kafka possible, if you are using spring","archived":false,"fork":false,"pushed_at":"2024-10-29T00:00:56.000Z","size":1463,"stargazers_count":3,"open_issues_count":2,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-19T21:58:06.099Z","etag":null,"topics":["java","kafka","kafka-client","kafka-consumer","kafka-producer","reactive","rxjava","spring","spring-boot"],"latest_commit_sha":null,"homepage":"","language":"Java","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/Csini.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":"2024-06-19T13:36:17.000Z","updated_at":"2024-11-11T11:40:45.000Z","dependencies_parsed_at":"2024-07-26T09:28:09.656Z","dependency_job_id":"40e96517-f953-4c4f-9cad-6babc07d3f9f","html_url":"https://github.com/Csini/spring-kafka-extensions","commit_stats":null,"previous_names":["csini/spring-kafka-extensions"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/Csini/spring-kafka-extensions","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Csini%2Fspring-kafka-extensions","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Csini%2Fspring-kafka-extensions/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Csini%2Fspring-kafka-extensions/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Csini%2Fspring-kafka-extensions/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Csini","download_url":"https://codeload.github.com/Csini/spring-kafka-extensions/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Csini%2Fspring-kafka-extensions/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29371421,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-12T08:51:36.827Z","status":"ssl_error","status_checked_at":"2026-02-12T08:51:26.849Z","response_time":55,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["java","kafka","kafka-client","kafka-consumer","kafka-producer","reactive","rxjava","spring","spring-boot"],"created_at":"2024-11-10T03:15:23.264Z","updated_at":"2026-02-12T16:03:16.103Z","avatar_url":"https://github.com/Csini.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"left\"\u003e\n    \u003cimg src=\"img/spring-kafka-extensions-logo.png\" alt=\"spring-kafka-extensions-logo\" width=\"300\"\u003e\n\u003c/p\u003e\n\n# spring-kafka-extensions library\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![Maven Central](https://img.shields.io/maven-central/v/net.csini.spring.kafka/spring-kafka-extensions.svg?label=Maven%20Central)](https://search.maven.org/artifact/net.csini.spring.kafka/spring-kafka-extensions)\n\nspring-kafka-extensions is a library that makes an entity based reactive approach (rxjava) to apache kafka possible, if you are using spring\n\nImagine that you have per Topic one KafkaEntity and you can read (consume) and write (produce) them easyly reactive. \n\nThis library can create automatic an Observer, an Observable and a Subject to every KafkaEntity! All you need to do is to use the custom `@KafkaEntity`, `@KafkaEntityKey`, `@KafkaEntityObserver`, `@KafkaEntityObservable` and `@KafkaEntitySubject` annotations!\n# overview\n![spring-kafka-extensions-overview](img/spring-kafka-extensions-overview.png)\n\n# how to install\n## add the library as dependency\n\n```html\n\u003cdependency\u003e\n\t\u003cgroupId\u003enet.csini.spring.kafka\u003c/groupId\u003e\n\t\u003cartifactId\u003espring-kafka-extensions\u003c/artifactId\u003e\n\t\u003cversion\u003e1.0.0\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nactual version is uploaded to Maven Central [here](https://repo1.maven.org/maven2/net/csini/spring/kafka/spring-kafka-extensions/)\n\n## create a `@Bean` from `KafkaEntityConfig` e.g\n\n```java\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\n\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.beans.factory.annotation.Value;\nimport org.springframework.context.ApplicationContext;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\n\nimport net.csini.spring.kafka.config.KafkaEntityConfig;\nimport net.csini.spring.kafka.exception.KafkaEntityException;\n\n@Configuration\npublic class KafkaEntityEnvironment {\n\n\t@Autowired\n\tApplicationContext applicationContext;\n\n\t@Value(value = \"${spring.kafka.bootstrap-servers:localhost:9092}\")\n\tprivate List\u003cString\u003e bootstrapServers = new ArrayList\u003c\u003e(Collections.singletonList(\"localhost:9092\"));\n\n\t@Bean\n\tpublic KafkaEntityConfig kafkaEntityConfig() throws KafkaEntityException {\n\n\t\tKafkaEntityConfig kafkaEntityConfig = new KafkaEntityConfig(applicationContext, bootstrapServers);\n\t\tkafkaEntityConfig.afterPropertiesSet();\n\t\t// here is a good timing to subscribe to KafkaEntityObservers (optional)\n\t\t\n\t\tList\u003cKafkaEntityException\u003e errors = kafkaEntityConfig.getErrors();\n\t\t// handle errors (optional)\n\t\t\n\t\treturn kafkaEntityConfig;\n\t}\n}\n```\n# how to use\n## define per topic one class or record and mark with `@KafkaEntity` (mark a field with `@KafkaEntityKey`) \nTopic name will be the name of the entity class with included packagename\nbut you can use custom Topic name like this `@KafkaEntity(customTopicName = \"PRODUCT\")`\n\n```java\npackage net.csini.spring.kafka.entity;\n\nimport net.csini.spring.kafka.KafkaEntity;\nimport net.csini.spring.kafka.KafkaEntityKey;\n\n@KafkaEntity\npublic record Student(@KafkaEntityKey String studentid, int age) {\n\n}\n```\nTopic name will be `net.csini.spring.kafka.entity.Student`\n```java\npackage net.csini.spring.topic;\n\nimport net.csini.spring.kafka.KafkaEntity;\n\n@KafkaEntity\npublic class Product {\n\n\t@net.csini.spring.kafka.KafkaEntityKey\n\tprivate String id;\n\n\tprivate String title;\n\n\tprivate String description;\n\t\n}\n```\nTopic name will be `net.csini.spring.topic.Product`\n\n## write data to a topic (produce)\nin a Spring Bean just inject a **KafkaEntityObserver** (City as KafkaEntity is defined [here](src/test/java/net/csini/spring/kafka/entity/City.java))\n\ndefault is `transactional=true`\n\n```java\nimport java.util.List;\n\nimport org.springframework.stereotype.Service;\n\nimport io.reactivex.rxjava3.core.Observer;\nimport net.csini.spring.kafka.KafkaEntityObserver;\nimport net.csini.spring.kafka.entity.City;\n\n@Service\npublic class ExampleKafkaEntityObserverService {\n\t\n\t@KafkaEntityObserver(entity = City.class)\n\tprivate Observer\u003cCity\u003e cityObserver;\n\t\n\tprivate List\u003cCity\u003e input = List.of(new City(\"Budapest\"), new City(\"Wien\"));\n\n\tpublic void sendCitiesToKafkaTopic(){\n\t\tObservable.fromIterable(input).subscribe(cityObserver);\n\t}\n}\n```\n\nif you need the **RecordMetadata** from the Kafka Message than you can use KafkaEntitySubject\n\nin a Spring Bean just inject a **KafkaEntitySubject** (User as KafkaEntity is defined [here](src/test/java/net/csini/spring/kafka/entity/User.java))\n\ndefault is `transactional=true`\n\n```java\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport org.apache.kafka.clients.producer.RecordMetadata;\nimport org.springframework.stereotype.Service;\n\nimport io.reactivex.rxjava3.core.Single;\nimport net.csini.spring.kafka.KafkaEntitySubject;\nimport net.csini.spring.kafka.entity.User;\n\nimport net.csini.spring.kafka.subject.KafkaSubject;\n\n@Service\npublic class OtherKafkaEntitySubjectService {\n\n\t@KafkaEntitySubject(entity = User.class, transactional = false)\n\tprivate KafkaSubject\u003cUser\u003e userSubject;\n\n\tpublic RecordMetadata sendUserToKafkaTopic(User u) {\n\t\tList\u003cRecordMetadata\u003e ret = new ArrayList\u003c\u003e();\n\t\tuserSubject.subscribe(r -\u003e {\n\t\t\tret.add(r);\n\t\t});\n\t\tSingle.just(u).toObservable().subscribe(userSubject);\n\t\treturn ret.get(0);\n\t}\n\n}\n```\n\n## read data from a topic (consume)\nin a Spring Bean just inject a **KafkaEntityObservable** (Place as KafkaEntity is defined [here](src/test/java/net/csini/spring/kafka/entity/Place.java))\n\n```java\nimport org.springframework.stereotype.Service;\n\nimport io.reactivex.rxjava3.core.Observable;\nimport net.csini.spring.kafka.KafkaEntityObservable;\nimport net.csini.spring.kafka.entity.Place;\n\n@Service\npublic class ExampleKafkaEntityObservableService {\n\n\t@KafkaEntityObservable(entity = Place.class)\n\tprivate Observable\u003cPlace\u003e placeObservable;\n\t\n\tpublic void readPlacesFromKafkaTopic() throws Exception {\n\n\t\tList\u003cPlace\u003e eventList = new ArrayList\u003c\u003e();\n\t\t\n\t\t@NonNull\n\t\tDisposable connect = placeObservable.subscribe(r -\u003e {\n\t\t\teventList.add(r);\n\t\t});\n\t\t\n\t\t// later if you want to stop consuming, you can unsubscribe\n\t\tconnect.dispose();\n\t}\n}\n```\n\n# example project which is using this library\n\n[https://github.com/Csini/catalog-synchronizer](https://github.com/Csini/catalog-synchronizer)\n\n- version 1.0.0 uses the \"traditional\" `@KafkaListener` and `KafkaTemplate` from spring-kafka\n\n- version 2.0.0 (ISSUE-35) uses **spring-kafka-extensions** `@KafkaEntity`, `@KafkaEntityKey`, `@KafkaEntityObserver`, `@KafkaEntityObservable` and `@KafkaEntitySubject` annotations!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcsini%2Fspring-kafka-extensions","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcsini%2Fspring-kafka-extensions","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcsini%2Fspring-kafka-extensions/lists"}