A lightweight Java framework for building REST APIs compliant with the JSON:API specification. Works with Spring Boot, Quarkus, and the Jakarta Servlet API.
Full JSON:API compliance out of the box β resources, relationships, compound documents, pagination, sparse fieldsets, error handling, and links. No shortcuts, no partial implementations.
First-class support for Spring Boot, Quarkus, and plain Jakarta Servlet API. One dependency, zero configuration β the framework auto-configures itself.
No JPA or ORM required. Use SQL, NoSQL, REST clients, in-memory stores β anything that returns data. The framework never touches your persistence layer.
Extend the request processing pipeline without modifying core logic. Build your own plugins or use the built-in ones:
- Access Control β per-field authorization via annotations, OAuth2 scopes, resource ownership
- OpenAPI β auto-generated spec from your domain model
- Sparse Fieldsets β
fields[type]filtering on the server - Compound Documents β multi-level
includewith parallel resolution
Concurrent relationship resolution, parallel compound document fetching, and support for virtual threads (Project Loom). Designed for production throughput from day one.
An opt-in Meta API exposes your live API's resources, relationships, operations, plugins, and effective configuration as machine-readable JSON:API β always in sync with the running service.
Every service ships with the same request/response format, the same pagination model, the same error structure β enforced by the framework, not by design reviews. Whether you're building a new microservice or standardizing an existing API layer, JsonApi4j gives your team an enforceable shared contract across Spring Boot, Quarkus, or plain Servlet.
Define your resources and operations β routing, serialization, pagination links, error handling, and documentation are generated automatically. Less plumbing, more domain logic.
The framework modules are published to Maven Central.
| Stack | Artifact |
|---|---|
| Spring Boot | pro.api4:jsonapi4j-rest-springboot |
| Quarkus | pro.api4:jsonapi4j-rest-quarkus |
| Servlet API | pro.api4:jsonapi4j-rest |
<dependency>
<groupId>pro.api4</groupId>
<artifactId>jsonapi4j-rest-springboot</artifactId>
<version>${jsonapi4j.version}</version>
</dependency>@JsonApiResource(resourceType = "users")
public class UserResource implements Resource<UserDbEntity> {
@Override
public String resolveResourceId(UserDbEntity user) {
return user.getId();
}
@Override
public UserAttributes resolveAttributes(UserDbEntity user) {
return new UserAttributes(user.getFullName(), user.getEmail());
}
}@JsonApiResourceOperation(resource = UserResource.class)
public class UserOperations implements ResourceOperations<UserDbEntity> {
private final UserDb userDb;
public UserOperations(UserDb userDb) {
this.userDb = userDb;
}
@Override
public PaginationAwareResponse<UserDbEntity> readPage(JsonApiRequest request) {
var page = userDb.readAllUsers(request.getCursor());
return PaginationAwareResponse.cursorAware(page.getEntities(), page.getCursor());
}
}GET /users
{
"data": [
{
"id": "1",
"type": "users",
"attributes": {
"fullName": "John Doe",
"email": "john@doe.com"
},
"links": {
"self": "/users/1"
}
},
{
"id": "2",
"type": "users",
"attributes": {
"fullName": "Jane Doe",
"email": "jane@doe.com"
},
"links": {
"self": "/users/2"
}
}
],
"links": {
"self": "/users",
"first": "/users",
"next": "/users?page%5Bcursor%5D=DoJu"
},
"meta": {
"pagination.nextCursor": "DoJu"
}
}That's it β pagination, links, content negotiation, and error handling are all handled automatically.
See the Getting Started guide for the full walkthrough including relationships, compound documents, and more.
Each plugin is a separate dependency β add only what you need:
Annotation-driven authorization with per-field granularity. Restrict attributes based on authentication status, OAuth2 scopes, and resource ownership β including automatic data anonymization for unauthorized fields.
@AccessControl(authenticated = Authenticated.AUTHENTICATED)
public class UserAttributes {
private final String fullName;
private final String email;
@AccessControl(
scopes = @AccessControlScopes(requiredScopes = "users.sensitive.read"),
ownership = @AccessControlOwnership(ownerIdFieldPath = "id")
)
private final String creditCardNumber;
}Unauthenticated requests see no attributes. Authenticated non-owners see fullName and email. Only the resource owner with the required scope sees creditCardNumber. Read more
Auto-generates an OpenAPI specification from your declared domain β resources, operations, relationships, and JSON:API parameters. Zero configuration required.
Access the spec at /jsonapi/oas in JSON or YAML format. Read more
Implements JSON:API sparse fieldsets. Clients request only the fields they need with fields[type]=field1,field2, reducing payload size on the server. Read more
Resolves include queries with multi-level relationship chaining (e.g., include=relatives.relatives), parallel batch fetching, and built-in response caching with Cache-Control support. The resolver can also run standalone at an API Gateway level. Read more
| Full documentation | api4.pro |
| Getting Started | api4.pro/getting-started |
| Maven Central | pro.api4 |
| App | Stack | Description |
|---|---|---|
| Spring Boot | Spring Boot | Users, Countries, Currencies with relationships and compound documents |
| Quarkus | Quarkus | Same domain, CDI-based integration |
| Servlet | Servlet API | Same domain, objects registration in Servlet Context |
Building on JsonApi4j with an AI agent? Install the Claude Code plugin β it bundles a skill that knows how to design resources, relationships, operations, compound documents, validation, and tests with this framework:
/plugin marketplace add MoonWorm/jsonapi4j
/plugin install jsonapi4j@jsonapi4j
Looking for a JSON:API implementation for Java? Here's a quick guide:
- Choose JsonApi4j if you want a lightweight, persistence-agnostic framework. No JPA or ORM required β bring your own data source. Works with Spring Boot, Quarkus, and plain Servlet API.
- Choose Elide if your stack is built around JPA/Hibernate and you also need GraphQL support alongside JSON:API.
- Consider crnk for a mature, feature-rich JSON:API implementation with deep JPA integration.
Contributions are welcome! See CONTRIBUTING.md for details.
This project is licensed under the Apache 2.0 License β see the LICENSE file for details.

