Skip to content

SpineEventEngine/validation

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4,243 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Ubuntu build codecov   license

Spine Validation

The library brings data validation directly into your Protobuf messages.

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, Spine Validation injects assertions directly into the generated Java classes, enabling automatic enforcement of constraints without explicit API calls in application code.

Prerequisites

This library is built with Java 17.

Validation in Action

Define your validation rules right in the .proto file:

import "spine/options.proto";
import "spine/time_options.proto";

import "google/protobuf/timestamp.proto";

message CardNumber {
    string digits = 1 [(pattern).regex = "\\d{4}\\s?\\d{4}\\s?\\d{4}\\s?\\d{4}"];
    string owner = 2 [(required) = true];
    google.protobuf.Timestamp issued_at = 3 [(when).in = PAST];
}

At build time, Spine Validation injects assertions into the generated Java classes:

var card = CardNumber.newBuilder()
    .setDigits("invalid")
    .build(); // <- Validates here.
val card = cardNumber {
    digits = "invalid"
} // <- Validates here. 

If any constraint is violated, a ValidationException is thrown from build().

You can also validate without throwing:

var card = CardNumber.newBuilder()
    .setDigits("invalid")
    .buildPartial(); // <- No validation.
var optionalError = card.validate();
optionalError.ifPresent(err -> {
    System.out.println(err.getMessage());
});

Validation Options

Validation options are defined by the following files:

  1. options.proto
  2. time_options.proto

Users must import these .proto files to use the options they define.

import "spine/options.proto"; // Brings all options, except for time-related ones.
import "spine/time_options.proto"; // Brings time-related options.

Adding custom validation

Users can extend the library by providing custom Protobuf options and code generation logic.

See the Custom validation section of the User Guide for details.

About

The library and plugins for the Spine Compiler for generating custom validation code

Topics

Resources

License

Code of conduct

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

Generated from SpineEventEngine/template