TSID Support
TSID (Time-Sorted Unique Identifier)
combines the best of auto-increment and UUID: 64-bit, roughly time-ordered (index friendly!),
cluster-safe and rendered as a compact 13-character Crockford base-32 string like
0gwvcnq9wm7st. commons-rest-tsid makes TSID a first-class citizen in your REST layer.
Installation
Section titled “Installation”<dependency> <groupId>io.rocketbase.commons</groupId> <artifactId>commons-rest-tsid</artifactId> <version>4.0.0-M4</version></dependency><dependency> <groupId>io.hypersistence</groupId> <artifactId>hypersistence-tsid</artifactId> <version>2.1.4</version></dependency>implementation("io.rocketbase.commons:commons-rest-tsid:4.0.0-M4")implementation("io.hypersistence:hypersistence-tsid:2.1.4")The auto-configuration registers a Jackson module (TSID ↔ string), a Spring MVC formatter for
TSID parameters and an exception handler mapping invalid ids to 404.
TSID id = TSID.Factory.getTsid(); // generateString text = id.toLowerCase(); // "0gwvcnq9wm7st"long value = id.toLong(); // 64-bit representation for the databaseDTO fields serialize to the lowercase canonical string automatically (parsing stays case-insensitive):
public class LocationRead { private TSID id; // → "id": "0gwvcnq9wm7st" private String name;}Path variables bind directly — invalid input raises TsidDecodeException → 404:
@GetMapping("/api/location/{id}")public LocationRead getById(@PathVariable TSID id) { return converter.fromEntity(repository.findById(id.toLong()) .orElseThrow(NotFoundException::new));}With JPA
Section titled “With JPA”Pairs nicely with hypersistence-utils’
@Tsid generator — store a Long, expose a TSID:
@Entitypublic class LocationEntity { @Id @Tsid private Long id; private String name;}// converterLocationRead.builder() .id(TSID.from(entity.getId())) .name(entity.getName()) .build();Configuration
Section titled “Configuration”| Property | Default | Explanation |
|---|---|---|
tsid.handler.enabled |
true |
toggle the 404 handler for TsidDecodeException |
tsid.invalid.allowed |
false |
strict by default: invalid ids in JSON bodies and conversions raise TsidDecodeException (→ 404), same as path variables; set true to leniently map them to null instead |
Node bits, custom epoch and generation tuning are configured through the hypersistence-tsid library itself (system properties / environment) — see its documentation.
TSID or ObfuscatedId?
Section titled “TSID or ObfuscatedId?”| TSID | ObfuscatedId | |
|---|---|---|
| id source | generated (time-sorted) | existing numeric ids |
| hides count/growth | ✔ (timestamp-based) | ✔ (hashed) |
| sortable by creation | ✔ | ✘ |
| works with auto-increment | ✘ (new id strategy) | ✔ (wraps existing Long) |
Use TSID for new schemas; use hashids to retrofit privacy onto existing sequential ids.