- Overview
- Quick Start
- Introduction
- Guides
- Client Libraries
- API Reference
- Examples
- DDD Resources
- Validation user guide
- Validation developer guide
Overview
Spine Validation is a Protobuf-centric validation library that generates
type-safe validation code directly from your .proto definitions.
It allows you to describe constraints on fields, messages, and collections using
declarative options and then automatically enforces these constraints at runtime.
The library is part of the Spine toolchain but can also be used independently in any Java/Kotlin backend that models data using Protocol Buffers.
Why
While Protobuf provides a structured way to define data schemas, it does not include built-in mechanisms for enforcing domain-specific rules at runtime. Without validation, invalid or inconsistent data can slip through, leading to subtle bugs and potential system failures.
Typically, developers address this by manually adding validation logic in application code or by invoking separate validation APIs. This ad-hoc approach can be error-prone and often results in duplicated, hard-to-maintain code scattered across the codebase.
How it works
Spine Validation solves this by modifying the code generated by the Protobuf compiler (protoc).
At build time, Validation injects assertions directly into the generated Java classes,
enabling automatic enforcement of constraints without explicit API calls in application code.
Components
Spine Validation consists of three main parts:
Validation plugin to Spine Compiler – analyzes your Protobuf definitions and generates validation code for messages and builders.
Gradle plugin – integrates with your build, configuring Spine Compiler to run the Validation code generation as part of the Protobuf compilation process.
Runtime library – provides validation APIs and error reporting mechanisms for JVM projects (Java and Kotlin).
Together, these components enable declarative, type-safe validation that is enforced both at compile time and at runtime.
Key capabilities
Declarative constraints in .proto
Validation rules are expressed as Protobuf options such as:
(required)(min)/(max)(pattern)- cross-field rules and message-level constraints
This keeps validation close to the data model and ensures it evolves together with it.
Generated validation code
The validation plugin to Spine Compiler processes your Protobuf model and generates:
- validation code for messages and builders,
- runtime checks,
- detailed error reports with field paths and messages.
No manual validators, reflection, or annotations are required.
Runtime validation API
Every generated message can be validated at runtime via:
validate(),- builder-based validation during construction,
- fail-fast or aggregated error reporting.
Errors are represented as structured diagnostics suitable for API responses, logs, or domain exception flows.
Rich domain-oriented constraints
Beyond simple “required/min/max”, the library includes:
- collection rules (
(distinct),(required)), - nested and cross-field validation,
- advanced string formats (using regex).
Extensible architecture
Teams can define custom validation options by:
- declaring new
.protooptions, - providing model configuration,
- contributing custom validation logic and code generation.
This allows entire organizations to standardize domain validation rules.
When to use Spine Validation
Use Spine Validation if:
- your data model is defined in Protobuf,
- you want robust validation with compile-time guarantees,
- you want validation rules to be versioned and reviewed along with the model,
- you need consistent semantics across services and APIs,
- you prefer generated code over reflection-based validators.
It is especially useful in:
- backend services (Java/Kotlin),
- message-driven systems,
- systems with rich domain models,
- multi-service environments where shared
.protomodels are common.
Relationship to the Spine Event Engine
Within the Spine Event Engine, this library is the canonical way to validate:
- incoming commands,
- events,
- entity states,
- domain value objects.
Validation occurs at well-defined points in the lifecycle and integrates with the framework’s error reporting mechanisms.
However, the library is fully standalone and can be used without the rest of the Spine stack.