Java 带Spring Kafka的Spring boot Rest api

Java 带Spring Kafka的Spring boot Rest api,java,spring,spring-boot,apache-kafka,spring-kafka,Java,Spring,Spring Boot,Apache Kafka,Spring Kafka,我设计了一个SpringBootRESTAPI添加和获取方法 @RestController("ProductV1Controller") public class ProductController { private final IProductProducer _productProducer; public ProductController(IProductProducer productProduc

我设计了一个SpringBootRESTAPI添加和获取方法

    @RestController("ProductV1Controller")
    public class ProductController 
     {

         private final IProductProducer _productProducer;
         public ProductController(IProductProducer productProducer) {
        _productProducer = productProducer;}

         @PostMapping()
            void AddProduct(@Valid @RequestBody ProductViewModel product) {
                _productProducer.AddProduct(product);
            }
        
        @GetMapping()
            List<ProductViewModel> Products() {
                var test = _productProducer.GetProducts();
                return _productProducer.GetProducts();
            }
}
@RestController(“ProductV1Controller”)
公共类产品控制器
{
私人最终IPProductProducer\u productProducer;
公共产品控制器(IPProductProducer){
_productProducer=productProducer;}
@后映射()
void AddProduct(@Valid@RequestBody-ProductViewModel-product){
_productProducer.AddProduct(产品);
}
@GetMapping()
产品清单(){
var test=_productProducer.GetProducts();
return_productProducer.GetProducts();
}
}
服务层
@服务
公共类ProductProducer实现IPProductProducer{
私人最终卡夫卡模板(KafkaTemplate);;
公共产品制作人(卡夫卡模板){
此.\u模板=\u模板;
}
@凌驾
公共列表产品(){
此.\u template.send(ProductTopicConstants.GET\u PRODUCTS,null);
return List.of(新产品视图模型(“,”,0)”);-->需要从kafka返回值
}
@凌驾
public void AddProduct(ProductViewModel产品){
此.\u template.send(ProductTopicConstants.ADD\u产品,产品);
}
}
卡夫卡听众
@KafkaListener(id=ProductTopicConstants.GET\u PRODUCTS,topics=ProductTopicConstants.GET\u PRODUCTS)
公共列表产品(){
返回_productRepository.findAll();
}
在服务层
GetProducts()
中,我需要返回来自
\u productRepository.findAll()的项目列表


使用Spring kafka实现REST API的最佳方法是什么。

您需要使用
回复KafkaTemplate
将结果返回给REST控制器

版本2.1.3引入了KafkaTemplate的子类来提供请求/应答语义。该类名为replyngkafkatemplate,除了超类中的方法外,还有一个方法

结果是一个ListenableFuture,异步填充结果(或超时的异常)。结果还具有sendFuture属性,该属性是调用KafkaTemplate.send()的结果。您可以使用此未来来确定发送操作的结果

文档中有一个示例

编辑

@springboot应用程序
@RestController
公共类SO63058608应用程序{
私有静态最终记录器LOG=LoggerFactory.getLogger(So63058608Application.class);
公共静态void main(字符串[]args){
SpringApplication.run(So63058608Application.class,args);
}
@自动连线
私有回复KafkaTemplate replyTemplate;
@GetMapping(path=“/get”)
public List getThem()引发异常{
请求答复未来=
this.replyTemplate.sendReceive(新产品记录(“so63058608-1”,0,null,null));
LOG.info(future.getSendFuture().get(10,TimeUnit.SECONDS).getRecordMetadata().toString());
返回future.get(10,TimeUnit.SECONDS).value();
}
@KafkaListener(id=“so63058608-1”,topics=“so63058608-1”,splitIterables=false)
@森托
public List returnList(@Payload(required=false)字符串负载){
返回新的ArrayList(列表中的“foo”、“bar”、“baz”);
}
@豆子
公共回复KafkaTemplate回复人(生产工厂pf,
ConcurrentKafkaListenerContainerFactory(集装箱工厂){
containerFactory.setReplyTemplate(kafkaTemplate(pf));
ConcurrentMessageListenerContainer=replyContainer(containerFactory);
ReplyingKafkatTemplate replyer=新的ReplyingKafkatTemplate(pf,容器);
返回应答器;
}
@豆子
公共ConcurrentMessageListenerContainer replyContainer(
ConcurrentKafkaListenerContainerFactory(集装箱工厂){
ConcurrentMessageListenerContainer容器=
containerFactory.createContainer(“so63058608-2”);
container.getContainerProperties().setGroupId(“so63058608-2”);
container.setBatchErrorHandler(新的BatchLoggingErrorHandler());
返回容器;
}
@豆子
公共卡夫卡模板卡夫卡模板(生产工厂pf){
返回新的卡夫卡模板(pf);
}
@豆子
公共新话题1(){
返回TopicBuilder.name(“so63058608-1”).partitions(1).replications(1.build();
}
@豆子
公共新话题3(){
返回TopicBuilder.name(“so63058608-2”).partitions(1).replications(1.build();
}
}
EDIT2

返回了一些对象的列表

@springboot应用程序
@RestController
公共类SO63058608应用程序{
私有静态最终记录器LOG=LoggerFactory.getLogger(So63058608Application.class);
公共静态void main(字符串[]args){
SpringApplication.run(So63058608Application.class,args);
}
@自动连线
私有回复KafkaTemplate replyTemplate;
@GetMapping(path=“/get”)
public List getThem()引发异常{
请求答复未来=
this.replyTemplate.sendReceive(新产品记录(“so63058608-1”,0,null,null));
LOG.info(future.getSendFuture().get(10,TimeUnit.SECONDS).getRecordMetadata().toString());
列表结果=future.get(10,TimeUnit.SECONDS).value();
LOG.info(result.toString());
返回结果;
}
@KafkaListener(id=“so63058608-1”,topics=“so63058608-1”,splitIterables=false)
@森托
public List returnList(@Payload(required=false)字符串负载){
返回新的ArrayList(新的Foo(“Foo”)、新的Foo(“bar”)、新的Foo(“baz”)列表);
}
@豆子
公共回复KafkaTemplate回复人(生产工厂pf,
卡夫卡林
@Service

    public class ProductProducer implements IProductProducer{
        private final KafkaTemplate<String, Object> _template;
    
        public ProductProducer(KafkaTemplate<String, Object> _template) {
            this._template = _template;
        }
    
        @Override
        public List<ProductViewModel> GetProducts() {
            this._template.send(ProductTopicConstants.GET_PRODUCTS,null);
            return List.of(new ProductViewModel("","",0,"")); --> Need to return the value from the kafka
        }
    
        @Override
        public void AddProduct(ProductViewModel product) {
            this._template.send(ProductTopicConstants.ADD_PRODUCT, product);
        }
       
    }
 @KafkaListener(id = ProductTopicConstants.GET_PRODUCTS, topics = ProductTopicConstants.GET_PRODUCTS)
    public List<Product> GetProducts() {
        return _productRepository.findAll();
    }
spring.kafka.consumer.key-deserializer=org.springframework.kafka.support.serializer.JsonDeserializer
spring.kafka.consumer.value-deserializer=org.springframework.kafka.support.serializer.JsonDeserializer
spring.kafka.consumer.auto-offset-reset=earliest
spring.kafka.consumer.properties.spring.json.trusted.packages=*

spring.kafka.producer.key-serializer=org.springframework.kafka.support.serializer.JsonSerializer
spring.kafka.producer.value-serializer=org.springframework.kafka.support.serializer.JsonSerializer
$ curl localhost:8080/get
["foo","bar","baz"]
spring.kafka.consumer.properties.spring.json.value.type.method=com.example.demo.So63058608Application.returnType
[Foo [bar=foo], Foo [bar=bar], Foo [bar=baz]]