Choose Your Stack

Why JsonApi4j

One standard. Every service. No more API design debates — just consistent, spec-compliant endpoints out of the box.

JSON:API Compliant

Purpose-built around the JSON:API specification — predictable request/response format and processing rules.

Auto-Generated OpenAPI

Always-in-sync API documentation derived from the same metadata used at runtime. Powerful customization capabilities. Exposed as JSON or YAML via a dedicated endpoint.

Framework Agnostic

Works with Spring Boot, Quarkus, and plain Jakarta Servlet API. Add one dependency and the framework auto-configures itself in your environment.

Under the Hood

Built for engineers who care about what happens between the request and the response.

Pluggable Architecture

Hook into the request pipeline with the visitor-based Plugin System. Ships with Access Control, Sparse Fieldsets, OpenAPI, and Compound Documents plugins.

Compound Documents

Multi-level include queries with parallel batch resolution, built-in caching, and Cache-Control aggregation. Deployable at the application or API Gateway level.

Fine-Grained Access Control

Declarative, annotation-driven authorization — per-field anonymization based on access tier, OAuth2 scopes, and resource ownership. No changes to core logic.

Minimal Boilerplate

Define resources, relationships, and operations — the framework automatically generates JSON:API documents, pagination links, error responses, and many more.

Persistence/Data Source Agnostic

No JPA or Hibernate required. Works with SQL, NoSQL, REST clients, in-memory stores, or any data source you bring.

Parallel Execution

Relationship resolution, compound document fetching, and batch operations run concurrently. Supports virtual threads (Project Loom) for maximum throughput.

Request Processing Pipeline

Every incoming API request flows through a well-defined processing pipeline — from data retrieval through relationship resolution to final document composition. At each stage, registered plugins can inspect, mutate, or short-circuit the request using the Visitor pattern.

Request Processing Pipeline

Quick Example

Define a resource and an operation — that’s all it takes to expose a fully compliant JSON:API endpoint:

@JsonApiResource(resourceType = "users")
public class UserResource implements Resource<UserDbEntity> {

    @Override
    public String resolveResourceId(UserDbEntity dto) {
        return dto.getId();
    }

    @Override
    public UserAttributes resolveAttributes(UserDbEntity dto) {
        return new UserAttributes(dto.getFullName(), dto.getEmail());
    }
}
@JsonApiResourceOperation(resource = UserResource.class)
public class UserOperations implements ResourceOperations<UserDbEntity> {

    @Override
    public CursorPageableResponse<UserDbEntity> readPage(JsonApiRequest request) {
        return PaginationAwareResponse.limitOffsetAware(
                userDb.readAll(request.getLimit(), request.getOffset()),
                userDb.total()
        );
    }
}

GET /users

{
  "data": [
    {
      "type": "users",
      "id": "1",
      "attributes": {
        "fullName": "John Doe",
        "email": "john@example.com"
      },
      "links": {
        "self": "/users/1"
      }
    }
  ],
  "links": {
    "self": "/users?page[offset]=0&page[limit]=20",
    "next": "/users?page[offset]=20&page[limit]=20"
  }
}