# 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` * 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`. ```xml org.kbastani spring-boot-starter-data-events 1.0-SNAPSHOT ... ``` 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. ```yaml spring: cloud: stream: bindings: output: destination: payment ``` Next, you'll need to create a custom `Event` entity. The snippet below extends the provided `Event` interface. This example uses Spring Data JPA, but you can use any Spring Data project for implementing your event entities. ```java @Entity @EntityListeners(AuditingEntityListener.class) public class PaymentEvent extends Event { @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` interface. The `PaymentEvent` is the JPA entity we defined in the last snippet. ```java public interface PaymentEventRepository extends EventRepository { } ``` 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. ```java @Service public class PaymentService { private final EventService eventService; public PaymentController(EventService 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`. ```bash curl -X GET "http://localhost:8082/v1/events/1" ``` Response: ```json { "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.