Skip to content

Curve

Java Spring Boot Kafka License CI

Declarative Event Publishing Library for Spring Boot Microservices

Curve is a production-ready library that simplifies event-driven architecture in Spring Boot applications. With a single annotation, you get automatic Kafka publishing, PII masking, DLQ handling, and comprehensive observability.


๐Ÿš€ Quick Start

Installation

dependencies {
    implementation 'io.github.closeup1202:curve:0.2.0'
}
<dependency>
    <groupId>io.github.closeup1202</groupId>
    <artifactId>curve</artifactId>
    <version>0.2.0</version>
</dependency>

Configuration

application.yml
spring:
  kafka:
    bootstrap-servers: localhost:9092

curve:
  enabled: true
  kafka:
    topic: event.audit.v1
    dlq-topic: event.audit.dlq.v1

Usage

OrderService.java
import io.github.closeup1202.curve.spring.audit.annotation.PublishEvent;

@Service
public class OrderService {

    @PublishEvent(eventType = "ORDER_CREATED")
    public Order createOrder(OrderRequest request) {
        return orderRepository.save(new Order(request));
    }
}

That's it! ๐ŸŽ‰ Curve automatically handles:

  • โœ… Event ID generation (Snowflake)
  • โœ… Metadata extraction (trace ID, user, IP)
  • โœ… PII masking/encryption
  • โœ… Kafka publishing with retries
  • โœ… Dead Letter Queue (DLQ)
  • โœ… Metrics collection

Get Started โ†’ View on GitHub โ†’


๐Ÿ”ฅ Why Curve?

Before vs After

  • Before (50+ lines)


    @Service
    public class UserService {
        @Autowired KafkaTemplate kafka;
    
        public User createUser(UserRequest req) {
            User user = repo.save(new User(req));
    
            try {
                // Manual event creation
                EventEnvelope event = EventEnvelope.builder()
                    .eventId(UUID.randomUUID().toString())
                    .eventType("USER_CREATED")
                    .occurredAt(Instant.now())
                    .metadata(/* ... */)
                    .payload(/* ... */)
                    .build();
    
                // Manual PII masking
                String json = maskPii(
                    objectMapper.writeValueAsString(event)
                );
    
                // Manual Kafka send
                kafka.send("user-events", json)
                    .get(30, TimeUnit.SECONDS);
    
            } catch (Exception e) {
                log.error("Failed", e);
                sendToDlq(event);
            }
    
            return user;
        }
    }
    
  • After (1 annotation)


    @Service
    public class UserService {
    
        @PublishEvent(eventType = "USER_CREATED")
        public User createUser(UserRequest req) {
            return repo.save(new User(req));
        }
    }
    

    90% less code โœจ


โญ Key Features

  • Declarative Publishing


    No Kafka boilerplate - just add @PublishEvent annotation. Supports SpEL for flexible payload extraction.

    Learn more

  • Standardized Events


    All events follow a unified schema with metadata (source, actor, trace, tags).

    Event Structure

  • 3-Tier Failure Recovery


    Main Topic โ†’ DLQ โ†’ Local File Backup

    Zero event loss even when Kafka is down.

    Failure Recovery

  • Automatic PII Protection


    @PiiField annotation automatically masks/encrypts sensitive data.

    PII Protection

  • High Performance


    • Sync: ~500 TPS
    • Async: ~10,000+ TPS
    • Transactional Outbox: Atomicity guaranteed

    Performance

  • Built-in Observability


    Health checks, custom metrics, and detailed event tracking out of the box.

    Observability


๐Ÿงช Comparison

Feature Spring Events Spring Cloud Stream Curve
Kafka Integration โŒ โœ… โœ…
Declarative Usage โœ… โš  Partial โœ…
Standardized Schema โŒ โŒ โœ…
PII Protection โŒ โŒ โœ…
DLQ Support โŒ โœ… โœ…
Local File Backup โŒ โŒ โœ…
Health Check โŒ โŒ โœ…
Transactional Outbox โŒ โŒ โœ…
Boilerplate Code Medium High Minimal

๐Ÿ— Architecture

Curve follows Hexagonal Architecture (Ports & Adapters) for maximum flexibility:

graph TB
    A[Domain Layer Core] --> B[Spring Adapter]
    A --> C[Kafka Adapter]
    B --> D[AOP / Context]
    C --> E[Producer / DLQ]

    style A fill:#4051b5
    style B fill:#00897b
    style C fill:#00897b

Core Principles:

  • ๐Ÿ“Œ Framework-independent domain model
  • ๐Ÿ“Œ Dependency Inversion (DIP)
  • ๐Ÿ“Œ Easy to test and extend

Architecture Details


๐ŸŽฏ Use Cases

1. Audit Logging

@PublishEvent(eventType = "USER_LOGIN", severity = INFO)
public User login(String username, String password) {
    return authService.authenticate(username, password);
}

2. Event-Driven Architecture

@PublishEvent(eventType = "ORDER_COMPLETED")
public Order completeOrder(Long orderId) {
    Order order = orderRepository.findById(orderId);
    order.setStatus(OrderStatus.COMPLETED);
    return orderRepository.save(order);
}

3. Data Pipeline

@PublishEvent(eventType = "CUSTOMER_REGISTERED")
public Customer registerCustomer(CustomerRequest request) {
    // Event automatically flows to data lake/warehouse
    return customerRepository.save(new Customer(request));
}

๐Ÿ“š Documentation

  • Getting Started


    Quick setup guide and your first event in 5 minutes

    Quick Start

  • Configuration


    Comprehensive configuration guide for production

    Configuration

  • Operations


    Production deployment and best practices

    Operations

  • Troubleshooting


    Common issues and solutions

    Troubleshooting


๐Ÿค Community

Contributing Guide


๐Ÿ“ License

This project is licensed under the MIT License - see the LICENSE file for details.