Crnk: JSON API framework
Documentation    Related Projects

Crank up the development of RESTful applications with Crnk (pronounced Crank). Crnk is an implementation of the JSON API specification and recommendations in Java to facilitate building RESTful applications. To quote the specification:

By following shared conventions, you can increase productivity, take advantage of generalized tooling, and focus on what matters: your application.

9 July 2017: version 1.0.20170709163645 is available. More information below and in the documentation.
Easy to integrate with frameworks like Spring, JEE, CDI, JAX-RS, Dropwizard, Servlet API.
Long-term support for technologies such as Java 7 and JPA 2.0 to ease enterprise adoption.
Only few dependencies of the core libraries, most notably the Jackson library.
JSON API client and server implementation with the possibility of shared, fully type-safe repository interfaces.
Open Source and released under the Apache License, Version 2.0. license. Suitable for both open source and commercial projects.
Modular design to choose and extend the feature set through a Module API.
Mobile friendly. Fetch complex object graphs in a single request with JSON API inclusions. Fetch partial objects with JSON API sparse field sets. Use together with the popular OkHttp library on Android devices.
Typescript friendly. Generate Typescript interfaces to access your repositories and resources in a type-safe manner.
Expose any JPA entity as JSON API resource with out-of-the-box sorting, filtering, paging and CRUD support without any implementation work. Or further map your entities to DTOs.
Standardized error handling with support for JSR-303 Bean Validation and a variety of other standard Java exception types.
Atomically insert, update and delete multiple resources with JSON Patch.
Integrate into Zipkin to trace incoming and outgoing requests.
Up-to-date documentation with Asciidoc.
Secure your repositories on repository, resource and field level.
Extensive meta model of your repositories available as JSON API repositories for the purpose of documentation and UI automation.

Example applications

Checkout the various example applications in crnk-examples. To start the spring boot application (the most advanced one) checkout crnk-framework and run:

gradlew :crnk-examples:spring-boot-example:run

A number of URLs to try: JSON Home document provided by crnk-home listing all repositories. crnk-ui allowing to browse all repositories. Simple in-memory repository ( ScheduleEntity JPA entity exposed as repository with crnk-jpa. See[name]
Sorting, filtering and pagination. Notice the total resource count in the meta data and the various pagination links. ScheduleEntity mapped to ScheduleDto and exposed as repository. Notice the additional computed attribute upperName. For the setup checkout Meta data of all resources provided by crnk-meta. Have a look also at the relationships, such as to the attributes.

Have a look at the console when issuing requests. crnk-brave with a log reporter is used for tracing.

Setup in 5 Minutes

The following gives a brief example of how to setup Crnk with JAX-RS and CDI. For more information have a look at the documentation and join us on Gitter and GitHub!

Add crnk-core together with the CDI and JAX-RS integrations to your classpath:
compile 'io.crnk:crnk-core:${version}'
compile 'io.crnk:crnk-cdi:${version}'
compile 'io.crnk:crnk-rs:${version}'

Setup a JAX-RS application and add the CrnkFeature. In this example a default page size and some meaningful Jackson settings are further configured.

public class DemoApplication extends Application {

	private static final Long DEFAULT_PAGE_SIZE = 20L;

	public Set<Object> getSingletons() {
		CrnkFeature crnk = new CrnkFeature();

		ObjectMapper objectMapper = crnk.getObjectMapper();
		objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);

		return new HashSet<>(Arrays.asList(crnk));
The actual data objects known as resource in JSON API terminology looks like:
@JsonApiResource(type = "schedules")
public class Schedule {

	private Long id;

	private String name;

	public Long getId() {
		return id;

	public Schedule setId(Long id) { = id;
		return this;

	public String getName() {
		return name;

	public void setName(String name) { = name;

Specifying an interface for your repository is an optional step, but can be quite convient when working on the client-side (like for testing). This particular example further specifies the structure of links and meta data attached to the actual data.
public interface ScheduleRepository extends ResourceRepositoryV2 {

	ScheduleList findAll(QuerySpec querySpec);

	class ScheduleList extends ResourceListBase {


	class ScheduleListLinks extends DefaultPagedLinksInformation implements LinksInformation {

		private String someLink = "http://...";

		public String getSomeLink() {
			return someLink;

		public void setSomeLink(String someLink) {
			this.someLink = someLink;

	class ScheduleListMeta implements MetaInformation {

		private String someMeta = "value";

		public String getSomeMeta() {
			return someMeta;

		public void setSomeMeta(String someMeta) {
			this.someMeta = someMeta;
The actual implementation of a JSON API repository. This example stores all data in-memory. Notice the QuerySpec.apply to do sorting, filtering and patching in-memory. More advanced use cases will translate the QuerySpec to a native query of the underlying data store. The @ApplicationScoped will lead for the repository to get picked up by the crnk-cdi integration.

public class ScheduleRepositoryImpl extends ResourceRepositoryBase<Schedule, Long> implements ScheduleRepository {

	private static Map<Long, Schedule> schedules = new HashMap<>();

	public ScheduleRepositoryImpl() {

	public static void clear() {

	public ScheduleList findAll(QuerySpec querySpec) {
		ScheduleList list = new ScheduleList();
		list.setLinks(new ScheduleListLinks());
		list.setMeta(new ScheduleListMeta());
		return list;

	public <S extends Schedule> S save(S entity) {
		schedules.put(entity.getId(), entity);
		return null;

	public void delete(Long id) {


9. July 2017

1.0.20170709163645 is the next release of Crnk coming with some major updates:

26 June 2017

1.0.20170626133151 is released. It patches an issue in the Typescript generator whereas it can fail when it is used together with the Gradle deamon and Deltaspike.

21 June 2017

1.0.20170620140608 is available as minor patch/feature release:

Module Changes
crnk-validation OptimisticLockException.message transmitted as as JSON API error detail
  • Running it in embedded mode with UIModule will no longer display the URL input.
  • Type input component is validated upon changing the url.
crnk-core, crnk-client utf-8 charset added to content-type HTTP request and responses headers
crnk-meta Support for ObjectNode, ArrayNode, JsonNode as primitive types added.
  • Logback setup to avoid uncessary logging during Gradle build.
  • Improved up-to-date checking of Gradle tasks.

10 June 2017

1.0.20170610072810 is available!

1 June 2017

0.9.20170601160228 is available. Mostly a quality release to catch up with Sonar.

25 May 2017

A first version 0.9.20170524133411 is released. Various contributors and existing users currently verify that everything is working smoothly.

While it is the first release, it can already be considered being production stable. The maintainers here moved forward from a mostly private code base that partially was also contributed to As such there is also an easy migration path as Crnk still maintains support for the same set of main annotations and interfaces as Katharsis does. For more information see the migration guide below.


A first version has been released, but many more improvements are planned for the near-future:

Katharsis Users

Crnk has support for the same set of annotations as Katharsis 3.0. As such there is a simple migration path from Katharsis to Crnk. If questions come up, do not hestitate to ask in the forum.