2.9.20181028143330
Version: 2.9.20181028143330
This release brings many incremental improvements and some long overdue architecture cleanups. Make sure to familiarize yourself with the updated UrlMapper behavior and QueryParams implementation. Any application following the convention recommended the past year should not have any issues with this.Early support for faceted search
Faceted search is used by many UIs to allow users to quickly navigate data sets. For example, virtually every online shop makes use of this feature to show product categories and the number of products in that category. Those categories, denoted as facets, have a label, a set of values and a count for each value. Facets may also depend on each other, whereas later facets are filtered by former ones.With FacetModule Crnk provides an out-of-the-box solution to implemented faceted search. For more information have a look at the new chapter in the documentation.
Documentation updates
The outline of the documentation has been revised. Some of the chapters have been restructured. And there is now a cheatsheet giving an overview of the most important features and APIs.The crnk-examples have been renamed to crnk-integration-examples to clearly distinguish from the main crnk-example application. The name change reflects the fact that those examples are only meant to showcase the integration of Crnk into various frameworks, not its entire feature set.
New UrlMapper default configuration
The DefaultQuerySpecUrlMapper implementation offers a enforceDotPathSeparator property that has historically been disabled to maintain backward compatibility. It allows to write filter parameter as either:filter[person][address][city]=Zurich filter[address][city]=Zurichor
filter[person][address.city]=Zurich filter[address.city]=ZurichHereby person is the resource type and address.city a nested attribute. With the first notation, issues can arise if resources and relationships carry the same name. This ambiguity prevents Crnk from properly resolving paths and may lead to hard to understand errors. For this reason Crnk has recommended the second flavor for some time while at the same time offering backward compatibility with the first one. Setting enforceDotPathSeparator to true removes support for the first notation, meaning Crnk will only support the second notation and will always be able to properly resolve paths. If this causes issue for your applicaiton, the flag can easily be disabled again, for example, in SpringBoot the flag is accessible with the crnk.enforceDotPathSeparator property.
Simplified QuerySpec with new PathSpec
All QuerySpec-related objects like FilterSpec and SortSpec now hold the attribute path as PathSpec. PathSpec facilitate working with paths compared to the previous List<String> solution. It offers various methods create new instances and can be used to quickly construct filter and sort specifications.Relationships loading handled according to JSON API specification
The specification from http://jsonapi.org/format/#fetching-relationships mandates two relationship links:-
"self": "http://example.com/articles/1/relationships/author"
-
"related": "http://example.com/articles/1/author"
HTTP/1.1 200 OK Content-Type: application/vnd.api+json { "links": { "self": "/articles/1/relationships/author", "related": "/articles/1/author" }, "data": { "type": "people", "id": "12" }Behind the scenes, the same relationship repository implementation is called. The QuerySpec will specify that only the identifier is required through the includedFields property.
QuerySpecVisitor
The new QuerySpecVisitor and QuerySpecVisitorBase classes allow to visit a QuerySpec by calling QuerySpec.accept(QuerySpecVisitor). Visitors can be used, for example, to easily modify attribute paths within a QuerySpc.Removal of deprecated Repository annotations
The annotation-based repositories have been deprecated since Crnk 0.x and have now been removed. A switch to the Interface-based repositories like ResourceRepositoryV2 is quickly implemented if somewhere still necessary.Optimized QueryParams code base
QueryParams has been deprecated since Crnk 0.x. So far both QuerySpec and QueryParams have been first-class citizens within Crnk. With this release, support for QueryParams has been refactored and remains support through the QuerySpec-to-QueryParams conversion process. That has been the recommended and only meaningful setup for a long time. The big benefit is a much lighter and more robust code base in the area.Future release either drop QueryParams support or move it out into a dedicated module. Contributes in the area would be welcomed. If it is no longer deemed useful by anybody, it will be removed sometime in Q1/Q2 2019.
Classpath scanning for Typescript generator
The Typescript generator used to need a running application to extract information about the set of resources and repositories. This remains the best and only way to reliably extract all information out of a Crnk-based application. However, due to this architecture, generation is also prone to quickly fail in case of misconfiguration of the application. For this reason, this release introduces an new, alternative mechanism where the classpath can be scanned for @JsonApiResource-annotated classes and repository interface definitions extending ResourceRepositoryV2. The benefit is a simpler setup at the cost of potentially missing out on non-standard repositories that are not backed by a @JsonApiResource annotation. In Gradle this then looks like:dependencies { typescriptGenRuntime project(':management:management-api') ... } typescriptGen{ resourcePackages = ['îo.crnk.example'] runtime { configuration = 'typescriptGenRuntime' } ... }
new property: crnk.enforceIdName
If set to true, it will name all `@JsonApiId` annotated fields as `id` on the rest layer (sorting, filtering, etc.) regardless of its Java name. By default this is not enabled for historic reasons. But enabling it more closely reflects the JSON API specification and is recommended to do so. It likely will be enabled in Crnk 3 by default.@JpaResource annotation deprecated
@JpaResource rather than @JsonApiResource has historically been necessary to modify the naming of Entity-based resources. This is no longer necessary and @JsonApiResource can be used together with classes annotated with @Entity.Historic Activiti repositories
There is initial experimental support for historic resource repositories of Activiti tasks and processes.ActivitiModuleConfig config = new ActivitiModuleConfig(); ProcessInstanceConfig processConfig = config.addProcessInstance(ScheduleApprovalProcessInstance.class); processConfig.historic(HistoricScheduleApprovalProcessInstance.class); TaskRepositoryConfig taskConfig = config.addTask(ApproveTask.class); taskConfig.historic(HistoricApproveTask.class); taskConfig.filterBy("description", ENFORCED_DESCRIPTION); return ActivitiModule.create(processEngine, config);