Skip to content

Caik/spec4j

📋 Spec4j

A Kotlin implementation of the Specification Pattern for composable, reusable business rules.

Stop scattering validation logic across your codebase. Spec4j lets you define small, testable business rules as specifications and combine them into policies — making your domain logic explicit, reusable, and easy to reason about.

CI codecov Maven Central License: MIT Kotlin JDK

📑 Table of Contents

🔍 Overview

Spec4j provides a clean, type-safe way to define and evaluate business rules. Instead of scattering validation logic throughout your codebase, you define atomic specifications that can be composed into policies.

// Define specifications
val isAdult = Specification.of<User, Reason>("IsAdult", { it.age >= 18 }, Reason.UNDERAGE)
val hasVerifiedEmail = Specification.of<User, Reason>("HasVerifiedEmail", { it.emailVerified }, Reason.EMAIL_NOT_VERIFIED)

// Compose into a policy
val registrationPolicy = Policy.create<User, Reason>()
    .with(isAdult)
    .with(hasVerifiedEmail)

// Evaluate
val result = registrationPolicy.evaluateFailFast(user)
if (result.allPassed) {
    // proceed
} else {
    // handle result.failureReasons()
}

✨ Features

  • 🧩 Composable — Build complex rules from simple, reusable specifications
  • 🔒 Type-safe — Failure reasons are enums, not strings
  • Two evaluation modesevaluateFailFast (stops on first failure) or evaluateAll (collects all failures)
  • 🔗 Logical operatorsallOf, anyOf, not for combining specifications
  • 💜 Kotlin-first — DSL builder, invoke operator, and fun interface for idiomatic Kotlin
  • Java-friendly — Full interoperability with @JvmStatic annotations

📦 Installation

Maven Central

Gradle (Kotlin DSL)

dependencies {
    implementation("io.github.caik:spec4j-core:$version")
}

Gradle (Groovy)

dependencies {
    implementation "io.github.caik:spec4j-core:$version"
}

Maven

<dependency>
    <groupId>io.github.caik</groupId>
    <artifactId>spec4j-core</artifactId>
    <version>$version</version>
</dependency>

📚 Core Concepts

📌 Specification

A single, atomic condition that evaluates a context and returns pass/fail with a reason:

val minimumAge = Specification.of<LoanApplication, Reason>(
    "MinimumAge",
    { it.applicantAge >= 18 },
    Reason.APPLICANT_TOO_YOUNG
)

📜 Policy

A named collection of specifications that together define a business rule:

// Fluent builder — works in both Java and Kotlin
val loanEligibility = Policy.create<LoanApplication, Reason>()
    .with(minimumAge)
    .with(maximumAge)
    .with(creditCheck)

// Kotlin DSL — more concise, Kotlin only
val loanEligibility = policy<LoanApplication, Reason> {
    +minimumAge
    +maximumAge
    +creditCheck
}

🔗 Composites

Combine specifications with logical operators:

// AND — all must pass
val fullyVerified = SpecificationFactory.allOf("FullyVerified", emailVerified, phoneVerified)

// OR — at least one must pass  
val hasPaymentMethod = SpecificationFactory.anyOf("HasPayment", hasCreditCard, hasBankAccount)

// NOT — inverts the result
val notBlocked = SpecificationFactory.not("NotBlocked", Reason.BLOCKED, isBlockedCountry)

🎯 Examples

The examples module contains complete working examples showcasing Spec4j's capabilities:

# Loan eligibility (basic usage)
./gradlew :examples:run -PexampleName=LoanEligibility

# E-commerce order validation (custom specs, not(), reusable specs)
./gradlew :examples:run -PexampleName=OrderValidation

# Feature access control (multiple policies, dynamic specs)
./gradlew :examples:run -PexampleName=FeatureAccess

🛠️ Building

# Build and run tests
./gradlew build

# Run tests with coverage report
./gradlew test jacocoTestReport
# Report: lib/build/reports/jacoco/test/html/index.html

🤝 Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.

⚖️ License

License

Released 2026 by Carlos Henrique Severino

About

Kotlin/Java library for the Specification Pattern — define small, testable business rules as specifications and compose them into policies

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages