Getting Started
commons-rest is a set of small, focused Spring Boot libraries for building REST services.
It gives you the pieces every service needs — typed exceptions with RFC 9457 problem
details, a serializable pagination wrapper, i18n-aware
translations, obfuscated ids and generated TypeScript clients — without forcing a framework
on top of Spring.
Requirements
Section titled “Requirements”- Java 17 or newer
- Spring Boot 4 / Spring Framework 7 (v4.x) — for Spring Boot 3 stay on the 3.5.x line
- Jackson 3 (
tools.jackson) — v4 is fully migrated, only the annotations remain oncom.fasterxml.jackson.annotation
Installation
Section titled “Installation”For a typical Spring MVC service you add commons-rest-server — it pulls in
commons-rest-api (DTOs, exceptions, annotations) transitively:
<dependency> <groupId>io.rocketbase.commons</groupId> <artifactId>commons-rest-server</artifactId> <version>4.0.0-M2</version></dependency>implementation("io.rocketbase.commons:commons-rest-server:4.0.0-M2")If you only consume REST services (client side) or share DTOs between services, the
lightweight commons-rest-api module is enough:
<dependency> <groupId>io.rocketbase.commons</groupId> <artifactId>commons-rest-api</artifactId> <version>4.0.0-M2</version></dependency>implementation("io.rocketbase.commons:commons-rest-api:4.0.0-M2")What you get out of the box
Section titled “What you get out of the box”commons-rest-server ships a Spring Boot auto-configuration — no @Enable... annotation, no
configuration class. As soon as the dependency is on the classpath:
NotFoundException,BadRequestExceptionandInsufficientPrivilegesExceptionthrown anywhere in your controllers are rendered asapplication/problem+jsonresponses (404 / 400 / 403)- Bean-validation errors (
@Validfailures) become a structured problem response with a per-field error map - An
AcceptHeaderLocaleResolveris configured so error messages can be translated - Enum request parameters are converted case-insensitively
Every part can be switched off with a property and every bean is
@ConditionalOnMissingBean — your own beans always win.
A first endpoint
Section titled “A first endpoint”@RestController@RequestMapping("/api/employee")@RequiredArgsConstructorpublic class EmployeeController {
private final EmployeeRepository repository; private final EmployeeConverter converter;
@GetMapping public PageableResult<EmployeeRead> list( @PageableDefault(size = 25) Pageable pageable) { return PageableResult.fromPage(repository.findAll(pageable), converter::fromEntity); }
@GetMapping("/{id}") public EmployeeRead getById(@PathVariable String id) { EmployeeEntity entity = repository.findById(id) .orElseThrow(() -> new NotFoundException("employee not found")); return converter.fromEntity(entity); }
@PostMapping public EmployeeRead create(@RequestBody @Valid EmployeeWrite write) { return converter.fromEntity(repository.save(converter.newEntity(write))); }}Three things to notice:
PageableResultwraps the Spring DataPageinto a serializable, framework-neutral DTO — the JSON shape is stable and clients don’t need Spring Data types.NotFoundExceptionjust gets thrown — the auto-configured handler turns it into a proper404problem response.EmployeeRead/EmployeeWriteare separate DTOs: the response structure and the create/update structure evolve independently — see Concepts.
A failing @Valid request answers like this, without any code on your side:
{ "type": "urn:problem-type:form-error", "title": "Bad Request", "status": 400, "detail": "invalid form", "fields": { "email": ["must not be empty"] }}Next steps
Section titled “Next steps”- Understand the Entity / Read / Write separation
- Return paged results with PageableResult
- See how error handling works end to end
- Generate TypeScript clients & react-query hooks from your controllers