Skip to content

Files

Latest commit

 

History

History

spring-boot-starter-data-events

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 

Spring Boot Starter Data Events

This starter project provides auto-configuration support classes for building event-driven Spring Data applications.

  • Uses a familiar Spring Data repository pattern for creating an EventRepository<T, ID>
  • The EventRepository provides trait specific features for managing an event log that is attached to an existing domain entity
  • Provides a set of event abstractions that can be extended to use any Spring Data repository (JPA, Mongo, Neo4j, Redis..)
  • Provides an EventService bean that can be used to publish events to a Spring Cloud Stream output channel

Usage

In your Spring Boot project, add the starter project dependency to your class path. For Maven, add the following dependency to your pom.xml.

<dependencies>
    <dependency>
        <groupId>org.kbastani</groupId>
        <artifactId>spring-boot-starter-data-events</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
    ...
</dependencies>

Next, configure your Spring Cloud Stream output bindings. Add the following snippet to the application.properties|yaml file of your Spring Boot application. Replace the destination value with the name of your message channel for the event stream.

spring:
  cloud:
    stream:
      bindings:
        output:
          destination: payment

Next, you'll need to create a custom Event entity. The snippet below extends the provided Event<T, E, ID> interface. This example uses Spring Data JPA, but you can use any Spring Data project for implementing your event entities.

@Entity
@EntityListeners(AuditingEntityListener.class)
public class PaymentEvent extends Event<Payment, PaymentEventType, Long> {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long eventId;

    @Enumerated(EnumType.STRING)
    private PaymentEventType type;

    @OneToOne(cascade = CascadeType.MERGE, fetch = FetchType.LAZY)
    @JsonIgnore
    private Payment entity;

    @CreatedDate
    private Long createdAt;

    @LastModifiedDate
    private Long lastModified;
 
    ...
}

To start managing events you'll need to extend the EventRepository<T, ID> interface. The PaymentEvent is the JPA entity we defined in the last snippet.

public interface PaymentEventRepository extends EventRepository<PaymentEvent, Long> {
}

That's it! You're ready to start sending domain events to the stream binding's output channel using the auto-configured EventService. The example snippet below shows how to create and append a new PaymentEvent to a Payment entity before publishing the event over AMQP to the configured event stream's output channel.

@Service
public class PaymentService {
    private final EventService<PaymentEvent, Long> eventService;
    
    public PaymentController(EventService<PaymentEvent, Long> eventService) {
        this.eventService = eventService;
    }
    
    public PaymentEvent appendCreateEvent(Payment payment) {
        PaymentEvent paymentEvent = new PaymentEvent(PaymentEventType.PAYMENT_CREATED);
        paymentEvent.setEntity(payment);
        paymentEvent = eventService.save(event);
        
        // Send the event to the Spring Cloud stream binding
        eventService.sendAsync(paymentEvent);
    }
    
    ...
}
    

A default EventController is also provided with the starter project. The EventController provides a basic REST API with hypermedia resource support for managing the Event log of a domain entity over HTTP. The following cURL snippet gets the PaymentEvent we created in the last example from the EventController.

curl -X GET "http://localhost:8082/v1/events/1"

Response:

{
  "eventId": 1,
  "type": "PAYMENT_CREATED",
  "createdAt": 1482749707006,
  "lastModified": 1482749707006,
  "_links": {
    "self": {
      "href": "http://localhost:8082/v1/events/1"
    },
    "payment": {
      "href": "http://localhost:8082/v1/payments/1"
    }
  }
}

In the snippet above we can see the EventController responded with a hal+json formatted resource. Since the PaymentEvent has a reference to the Payment entity, we see a payment link is available to fetch the related resource.