<commit_before>How to use Katharsis in your applications
=========================================

Katharsis provides means to easily expose resources over the REST interface. If you want to take a deeper look on the concepts behind Katharsis, this is page for you!


Requirements
------------

Below are listed dependencies used in Katharsis that project has to meet to be compatible with latest library version:

.. note::
  Katharsis library requires minimum Java 7 to build and run.


``katharsis-core``

.. code-block:: bash

  io.katharsis:katharsis-core:bundle:2.6.0
  +- org.reflections:reflections:jar:0.9.9:compile
  |  +- com.google.guava:guava:jar:15.0:compile
  |  +- org.javassist:javassist:jar:3.18.2-GA:compile
  |  \- com.google.code.findbugs:annotations:jar:2.0.1:compile
  +- net.jodah:typetools:jar:0.4.4:compile
  +- org.slf4j:slf4j-api:jar:1.7.13:compile
  +- com.fasterxml.jackson.core:jackson-databind:jar:2.6.3:compile
  |  \- com.fasterxml.jackson.core:jackson-core:jar:2.6.3:compile
  +- com.fasterxml.jackson.core:jackson-annotations:jar:2.6.3:compile


``katharsis-rs``

.. code-block:: bash

  io.katharsis:katharsis-rs:bundle:2.6.0
  +- io.katharsis:katharsis-core:jar:2.6.0:compile
  |  +- net.jodah:typetools:jar:0.4.4:compile
  |  +- org.slf4j:slf4j-api:jar:1.7.13:compile
  |  \- com.fasterxml.jackson.core:jackson-databind:jar:2.6.3:compile
  |     \- com.fasterxml.jackson.core:jackson-core:jar:2.6.3:compile
  +- com.fasterxml.jackson.core:jackson-annotations:jar:2.6.3:compile
  +- org.reflections:reflections:jar:0.9.9:compile
  |  +- com.google.guava:guava:jar:15.0:compile
  |  +- org.javassist:javassist:jar:3.18.2-GA:compile
  |  \- com.google.code.findbugs:annotations:jar:2.0.1:compile
  +- javax.ws.rs:javax.ws.rs-api:jar:2.0.1:compile
  +- javax.servlet:javax.servlet-api:jar:3.0.1:compile


``katharsis-servlet``

.. code-block:: bash

  io.katharsis:katharsis-servlet:bundle:2.6.0
  +- io.katharsis:katharsis-core:jar:2.6.0:compile
  |  +- net.jodah:typetools:jar:0.4.4:compile
  |  +- com.fasterxml.jackson.core:jackson-databind:jar:2.6.3:compile
  |  |  \- com.fasterxml.jackson.core:jackson-core:jar:2.6.3:compile
  |  \- com.fasterxml.jackson.core:jackson-annotations:jar:2.6.3:compile
  +- org.reflections:reflections:jar:0.9.9:compile
  |  +- org.javassist:javassist:jar:3.18.2-GA:compile
  |  \- com.google.code.findbugs:annotations:jar:2.0.1:compile
  +- com.google.guava:guava:jar:15.0:compile
  +- javax.servlet:javax.servlet-api:jar:3.0.1:provided
  +- org.slf4j:slf4j-api:jar:1.7.6:provided


``katharsis-spring``

.. code-block:: bash

  io.katharsis:katharsis-spring:bundle:2.6.0
  +- org.springframework.boot:spring-boot-starter-web:jar:1.3.1.RELEASE:compile
  |  ...
  +- org.springframework.boot:spring-boot-configuration-processor:jar:1.3.1.RELEASE:compile
  |  +- org.json:json:jar:20140107:compile
  |  \- org.springframework:spring-core:jar:4.2.4.RELEASE:compile
  |     \- commons-logging:commons-logging:jar:1.2:compile
  +- io.katharsis:katharsis-servlet:jar:2.6.0:compile
  |  +- io.katharsis:katharsis-core:jar:2.6.0:compile
  |  |  +- net.jodah:typetools:jar:0.4.4:compile
  |  |  \- org.slf4j:slf4j-api:jar:1.7.13:compile
  |  \- com.google.guava:guava:jar:15.0:compile
  +- org.reflections:reflections:jar:0.9.9:compile
  |  +- org.javassist:javassist:jar:3.18.2-GA:compile
  |  \- com.google.code.findbugs:annotations:jar:2.0.1:compile


``katharsis-vertx``

.. code-block:: bash

  +--- io.katharsis:katharsis-core:2.99.0-SNAPSHOT
  |    +--- org.projectlombok:lombok:1.16.8
  |    +--- net.jodah:typetools:0.4.4
  |    +--- org.slf4j:slf4j-api:1.7.13
  |    +--- com.fasterxml.jackson.core:jackson-databind:2.6.3
  |    |    +--- com.fasterxml.jackson.core:jackson-annotations:2.6.0 -> 2.6.3
  |    |    \--- com.fasterxml.jackson.core:jackson-core:2.6.3
  |    \--- com.fasterxml.jackson.core:jackson-annotations:2.6.3
  +--- io.vertx:vertx-core:3.2.1
  ...
  +--- io.vertx:vertx-web:3.2.1
  ...
  +--- org.reflections:reflections:0.9.9
  |    +--- com.google.guava:guava:15.0
  |    +--- org.javassist:javassist:3.18.2-GA
  |    \--- com.google.code.findbugs:annotations:2.0.1
  \--- org.slf4j:slf4j-api:1.7.13

  ``katharsis-client``

  .. code-block:: bash

  io.katharsis:katharsis-client:bundle:2.6.0
  +- io.katharsis:katharsis-core:jar:2.6.0:compile
  |  +- net.jodah:typetools:jar:0.4.4:compile
  |  +- org.slf4j:slf4j-api:jar:1.7.13:compile
  |  +- com.fasterxml.jackson.core:jackson-databind:jar:2.6.3:compile
  |  |  \- com.fasterxml.jackson.core:jackson-core:jar:2.6.3:compile
  |  \- com.fasterxml.jackson.core:jackson-annotations:jar:2.6.3:compile
  +- org.reflections:reflections:jar:0.9.9:compile
  |  +- com.google.guava:guava:jar:15.0:compile
  |  +- org.javassist:javassist:jar:3.18.2-GA:compile
  |  \- com.google.code.findbugs:annotations:jar:2.0.1:compile
  +- com.squareup.okhttp:okhttp:jar:2.7.5:compile
  |  \- com.squareup.okio:okio:jar:1.6.0:compile

Supported requests
------------------

Currently Katharsis covers most of the JSON API specification request types. The following table describes available requests that are currently accepted:

.. csv-table:: A summary of the supported requests
  :header:  HTTP method, Kind of request, Sample URL,  Multiplicity of resource

  GET,	resources, "http://host.local/tasks or http://host.local/tasks/1,2", multiple
  ,resource,	http://host.local/tasks/1,	single
  ,relationship,	http://host.local/tasks/1/relationships/project,	single
  ,field,	http://host.local/tasks/1/project,	single
  POST,	resource,	http://host.local/tasks,	single
  ,field,	http://host.local/tasks/1/project,	single
  ,relationship,	http://host.local/tasks/1/relationships/project,	single
  PATCH,	resource,	http://host.local/tasks/1,	single
  ,relationship,	http://host.local/tasks/1/relationships/project,	single
  DELETE,	resource,	http://host.local/tasks/1,	single
  ,relationship,	http://host.local/tasks/1/relationships/project,	single



Relationships
-------------

One of the main features of JSON API and Katharsis is support of managing relations between resources. To achieve that, two steps are required:

* Add a field annotated with JsonApiToOne or JsonApiToMany (depending on multiplicity of the relation) which will represent a unidirectional relation.
* Add a repository which defines operations that can be made on models.


Models
------

There are several annotations which can be assigned to models. By default all fields of the model are reflected in JSON API communication except synthetic fields. The annotations described below should be associated with either a field or a getter.


JsonApiResource
~~~~~~~~~~~~~~~

It is the most important annotation which defines a resource. It requires type parameter to be defined that is used to form a URLs and type field in passed JSONs. According to JSON API standard, the name defined in type can be either plural or singular

The example below shows a sample class which contains a definition of a resource.

.. code-block:: java

  @JsonApiResource(type = "tasks")
  public class Task {
    // fields, getters and setters
  }


JsonApiId
~~~~~~~~~

Defines a field which will be used as an identifier of a resource.
Each resource requires this annotation to be present on a field which type implements ``Serializable`` or is of primitive type.

The example below shows a sample class which contains a definition of a field which contains an identifier.

.. code-block:: java

  @JsonApiResource(type = "tasks")
  public class Task {
    @JsonApiId
    private Long id;

    // fields, getters and setters
  }

JsonApiToOne
~~~~~~~~~~~~

Indicates an association to single value which needs to be handled by a separate ``RelationshipRepository``.
 A type of the field has to be a valid resource.

The example below shows a sample class which contains this kind of relationship.


.. code-block:: java

  @JsonApiResource(type = "tasks")
  public class Task {

    // ID field

    @JsonApiToOne
    private Project project;

    // fields, getters and setters
  }

JsonApiToMany
~~~~~~~~~~~~~

Indicates an association to many values which need to be handled by a separate ``RelationshipRepository``.
A type of the field has to be an ``Iterable`` or its derived classes (e.g.``List``) of valid resources.
By default, relationship is considered to be lazy, that is the relationship is not shown in the Top Level JSON.
To change that, pass parameter ``@JsonApiToMany(lazy = false)``.

The example below shows a sample class which contains this kind of relationship.

.. code-block:: java

  @JsonApiResource(type = "tasks")
  public class Task {

    // ID field

    @JsonApiToMany(lazy = false)
    private List<Project> projects;

    @JsonApiToMany // not shown in Top Level JSON
    private List<Log> logs;

    // fields, getters and setters
  }



JsonApiIncludeByDefault
~~~~~~~~~~~~~~~~~~~~~~~

Indicates additional resources that should be included by default (will be available
in included field of Top level JSON object) with every primary resource.
The field can be added to every relationship defined by ``JsonApiToOne`` or ``JsonApiToMany``.
Otherwise, ``ResourceException`` will be thrown at the initialization phrase.

The example below shows a sample model with this annotation.

.. code-block:: java

  @JsonApiResource(type = "tasks")
  public class Task {

    // ID field

    @JsonApiToOne
    @JsonApiIncludeByDefault
    private Project project;

    // fields, getters and setters
  }

JsonApiLookupIncludeAutomatically
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Field or getter annotated with ``JsonApiLookupIncludeAutomatically`` will be automatically populated by Katharsis on ``GET`` requests.
It can be added to every relationship defined by ``JsonApiToOne`` or ``JsonApiToMany``.

The example below shows a sample class which will always contain a relationship's resource.

.. code-block:: java

  @JsonApiResource(type = "tasks")
  public class Task {

    // ID field

    @JsonApiToOne
    @JsonApiLookupIncludeAutomatically
    private Project project;

    // fields, getters and setters
  }








JsonApiMetaInformation
~~~~~~~~~~~~~~~~~~~~~~~

Field or getter annotated with ``JsonApiMetaInformation`` are marked to carry a ``MetaInformation`` implementation.
See http://jsonapi.org/format/#document-meta for more information about meta data. Example:


.. code-block:: java
	
	@JsonApiResource(type = "projects")
	public class Project {
	
		...
	
		@JsonApiMetaInformation
		private ProjectMeta meta;
	
		public static class ProjectMeta implements MetaInformation {
	
			private String value;
	
			public String getValue() {
				return value;
			}
	
			public void setValue(String value) {
				this.value = value;
			}
		}
	}



JsonApiLinksInformation
~~~~~~~~~~~~~~~~~~~~~~~

Field or getter annotated with ``JsonApiLinksInformation`` are marked to carry a ``LinksInformation`` implementation.
See http://jsonapi.org/format/#document-links for more information about linking. Example:


.. code-block:: java
	
	@JsonApiResource(type = "projects")
	public class Project {
	
		...
	
		@JsonApiLinksInformation
		private ProjectLinks links;
	
		public static class ProjectLinks implements MetaInformation {
	
			private String value;
	
			public String getValue() {
				return value;
			}
	
			public void setValue(String value) {
				this.value = value;
			}
		}
	}





Repositories
------------

The model definition must have corresponding resource repository.
In addition, each relation also must have a corresponding repository.

Those repositories can be defined in one of the two ways:

* Implementing a repository interface:

  * ResourceRepositoryV2 for a resource
  * RelationshipRepositoryV2 for resource relationships

* Annotated with a repository annotation:

  * JsonApiResourceRepository for a resource
  * JsonApiRelationshipRepository for resource relationships
  
Both approaches have their merits. But note that the use of interfaces has
one main advantage over annotated repositories: the interfaces are  
supported by ``katharsis-client``. Applications may declare their own 
interfaces, extending the ones of Katharsis with type arguments
and additional actions. On the server side, repository interfaces
are implemented by the repository implementations. On the client side,
``katharsis-client`` can automatically create stubs to have 
type-safe access to remote repositories. More information is available
with the client documentation further down.


ResourceRepositoryV2
~~~~~~~~~~~~~~~~~~~~

Base repository which is used to operate on resources.
Each resource should have a corresponding repository implementation.
It consist of five basic methods which provide a CRUD for a resource and two parameters: the first is a type of a resource and the second is a type of the resource’s identifier.

The methods are as follows:

* ``findOne(ID id, QuerySpec querySpec)``
  Search one resource with a given ID. If a resource cannot be found, a ResourceNotFoundException exception should be thrown.
  It should return an entity with associated relationships.

* ``findAll(QuerySpec querySpec)``
  Search for all of the resources. An instance of QueryParams can be used if necessary.
  If no resources can be found an empty Iterable or null must be returned.
  It should return entities with associated relationships.

* ``findAll(Iterable<ID>ids, QuerySpec querySpec)``
  Search for resources constrained by a list of identifiers. An instance of QueryParams can be used if necessary.
  If no resources can be found an empty Iterable or null must be returned.
  It should return entities with associated relationships.

* ``save(S entity)``
  Saves a resource. It should not save relating relationships. A Returning resource must include assigned identifier created for the instance of resource.
  This method should be able to both create a new resource and update existing one.

* ``delete(ID id)``
  Removes a resource identified by id parameter.
  
The ResourceRepositoryBase is a base class that takes care of some boiler-plate, like implementing findOne with findAll. An
implementation can then look as simple as:

.. code-block:: java

	public class ProjectRepository extends ResourceRepositoryBase<Project, String> {
	
		private Map<Long, Project> projects = new HashMap<>();
	
		public ProjectRepository() {
			super(Project.class);
			save(new Project(1L, "Project A"));
			save(new Project(2L, "Project B"));
			save(new Project(3L, "Project C"));
		}
	
		@Override
		public synchronized void delete(String id) {
			projects.remove(id);
		}
	
		@Override
		public synchronized <S extends Project> S save(S project) {
			projects.put(project.getId(), project);
			return project;
		}
	
		@Override
		public synchronized ResourceList<Project> findAll(QuerySpec querySpec) {
			return querySpec.apply(projects.values());
		}
	}


RelationshipRepositoryV2
~~~~~~~~~~~~~~~~~~~~~~~~

Each relationship defined in Katharsis (annotation @JsonApiToOne and @JsonApiToMany) must have a relationship repository defined.

Base unidirectional repository responsible for operations on relations.
All of the methods in this interface have fieldName field as their last parameter to solve the problem of many relationships between the same resources.

* ``setRelation(T source, D_ID targetId, String fieldName)``
  Sets a resource defined by targetId to a field fieldName in an instance source. If no value is to be set, null value is passed.

* ``setRelations(T source, Iterable<D_ID> targetIds, String fieldName)``
  Sets resources defined by targetIds to a field fieldName in an instance source. This is a all-or-nothing operation, that is no partial relationship updates are passed. If no values are to be set, empty Iterable is passed.

* ``addRelations(T source, Iterable<D_ID> targetIds, String fieldName)``
  Adds relationships to a list of relationships.

* ``removeRelations(T source, Iterable<D_ID> targetIds, String fieldName)``
  Removes relationships from a list of relationships.

* ``findOneTarget(T_ID sourceId, String fieldName, QuerySpec querySpec)``
  Finds one field's value defined by fieldName in a source defined by sourceId.

* ``findManyTargets(T_ID sourceId, String fieldName, QuerySpec querySpec)``
  Finds an Iterable of field's values defined by fieldName in a source defined by sourceId .


This interface must be implemented to let Katharsis work correctly, some of the requests are processed using only this kind of repository.
As it can be seen above, there are two kinds of methods: for multiple and single relationships and it is possible to implement only one type of methods, e.g. singular methods.
Nevertheless, it should be avoided because of potential future problems when adding new fields of other sizes.

In many cases, relationship operations can be mapped back to resource repository operations. Making the need
for a custom relationship repository implementation redundant. A findManyTargets request might can be
served by filtering the target repository. Or a relationship can be set by invoking the save operation 
on either the source or target resource repository (usually you want to save on the single-valued side).
The ResourceRepositoryBase is a base class that takes care of exactly this. A repository
implementation then looks as simple as:


.. code-block:: java

	public class ProjectToTaskRepository extends RelationshipRepositoryBase<Project, Long, Task, Long> {
	
		public ScheduleToTaskRepository() {
			super(Project.class, Task.class);
		}
	}


For this to work, relations must be set up bidirectionally with the ``opposite`` attribute:

.. code-block:: java
	
	@JsonApiResource(type = "tasks")
	public class Task {
	
		@JsonApiToOne(opposite = "tasks")
		@JsonApiIncludeByDefault
		private Project project;
	
	    ...
	}




ResourceList
~~~~~~~~~~~~~~~~~~~~~~~~

ResourceRepositoryV2 and RelationshipRepositoryV2 return lists of type ResourceList. The ResourceList can carry, next
to the actual resources, also meta and links information:

* ``getLinks()``
	Gets the links information attached to this lists.
	
* ``getMeta()``
	Gets the meta information attached to this lists.

* ``getLinks(Class<L> linksClass)``
	Gets the links information of the given type attached to this lists. If the given type is not found, null is returned.

* ``getMeta(Class<M> metaClass)``
	Gets the meta information of the given type attached to this lists. If the given type is not found, null is returned.

Thhere is a default implementation named DefaultResourceList. To gain type-safety, improved readability and katharsis-client support,
application may provide a custom implementation extending ResourceListBase:

.. code-block:: java

	class ScheduleList extends ResourceListBase<Schedule, ScheduleListMeta, ScheduleListLinks> {

	}
	
	class ScheduleListLinks implements LinksInformation {

		public String name = "value";
		
		...
	}

	class ScheduleListMeta implements MetaInformation {

		public String name = "value";
		
		...
	}
	
This implementation can then be added to a repository interface declaration
and used by both servers and clients:

.. code-block:: java

	public interface ScheduleRepository extends ResourceRepositoryV2<Schedule, Long> {
	
		@Override
		public ScheduleList findAll(QuerySpec querySpec);
		
	}






Annotated repositories
~~~~~~~~~~~~~~~~~~~~~~

A resource repository can also be defined using the ``JsonApiResourceRepository`` or ``JsonApiRelationshipRepository`` annotations from ``io.katharsis.repository.annotations`` package.

Defining the repositories this way has two benefits:

* It's not necessary to define all of the methods i.e. read-only resources might have just reading methods defined
* Additional parameters can be added to the methods like authentication, request headers or cookies

Along with the required parameters for each methods (like the resource identifier in ``JsonApiFindOne``), the default supported type is QueryParams, which provides a set of parsed query parameters.
Each Katharsis integration provides different set of supported parameters.
This list can be found in JAX-RS and Servlet integration sections.

A list below defines a mapping of ``ResourceRepository`` methods to annotations:

* ``findOne(ID, QueryParams) -> JsonApiFindOne``

  The first parameter must be a resource's id. This method must return one resource.

* ``findAll(QueryParams) -> JsonApiFindAll``

  This method must return a list of resources.

* ``findAll(Iterable<ID>, QueryParams) -> JsonApiFindAllWithIds``

  The first parameter must be a list of resource ids. This method must return a list of resources.

* ``save(S) -> JsonApiSave``

  The first parameter must be a resource. This method must return one resource.

* ``delete(ID) -> JsonApiDelete``

  The first parameter must be a resource's id.


A list below defines a mapping of ``RelationshipRepository`` methods to annotations:

* ``setRelation(T, D_ID, String) -> JsonApiSetRelation``

  The requirements for the method parameters are as follows:

  #. Instance of a source resource
  #. Instance of a relationship to be set
  #. Relationship's field name

* ``setRelations(T, Iterable<D_ID>, String) -> JsonApiSetRelations``

  The requirements for the method parameters are as follows:

  #. Instance of a source resource
  #. ``Iterable`` of relationships to be set
  #. Relationship's field name

* ``addRelations(T, Iterable<D_ID>, String) -> JsonApiAddRelation``

  The requirements for the method parameters are as follows:

  #. Instance of a source resource
  #. Iterable of relationships to be add
  #. Relationship's field name

* ``removeRelations(T, Iterable<D_ID>, String) -> JsonApiRemoveRelation``

  The requirements for the method parameters are as follows:

  #. Instance of a source resource
  #. Iterable of relationships to be removed
  #. Relationship's field name

* ``findOneTarget(T_ID, String, QuerySpec) -> JsonApiFindOneTarget``

  The requirements for the method parameters are as follows:

  #. An identifier of a source resource
  #. Relationship's field name
  #. The method has to return a resources.

* ``findManyTargets(T_ID, String, QuerySpec) -> JsonApiFindManyTargets``

  The requirements for the method parameters are as follows:

  #. An identifier of a source resource
  #. Relationship's field name
  #. The method has to return an Iterable with resources.



Query parameters
----------------

Katharsis has defined set of query parameters which can be used by the framework during data retrieval and by a developer to perform other operations.
All of the types of parameters can be accessed with the either QueryParams or QuerySpec object in repository methods.


QuerySpec vs. QueryParams
~~~~~~~~~~~~~~~~~~~~~~~~~~~

Note that if you are new to Katharsis and have setup your applications based on the
examples, you can skip this section. Everything is already properly setup for you.

QueryParams is the traditional query api of Katharsis. QuerySpec is a new API 
with the purpose of simplifying the implementation of repositories and offering 100% JSON API compliance
See the next section for more information about JSON API compliance.

QuerySpec is a drop-in replacement for QueryParams in annotated repositories.
``ResourceRepository`` and ``RelationshipRepository`` make use of QueryParams.
``ResourceRepositoryV2`` and ``RelationshipRepositoryV2`` make use of QuerySpec.

For the time being, both QueryParams and QuerySpec are fully supported. But
QueryParams will be deprecated at some point and the use of QuerySpec is highly
recommended. It is also possible to mix the use of both classes to gradually move
from QueryParams to QuerySpec. Katharsis is able to internally 
convert QueryParams to a QuerySpec. No changes necessary.

The next section outlines the necessary changes in the setup procedure to gain JSON API compliance.


JSON API compliance
~~~~~~~~~~~~~~~~~~~~

Note that if you are new to Katharsis and have setup your applications based on the
examples, you can skip this section. Everything is already properly setup for you.

The subsequent sections outline URL conventions to query resources.
QueryParams does not fully adhere to the JSON API specification and instead
provides a number of improvements over the specification. QuerySpec strives to offer both,
JSON API compliance and some more advanced URL patterns.

Most notably, QuerySpec supports the ordered sorting on multiple attributes 
by providing an ordered list of those sorted attributes. And QueryParams 
introduced support to not only sort and filter requested resources, but also included related resources.
Because of this, sort and filter parameters require an additional type passed in the parameter name.
With QuerySpec this type becomes optional and the requested (root) type is used by default. The
following two requests are equivalent:

``GET /tasks/?sort[tasks]=!shortName,name``

and more simply just:

``GET /tasks/?sort=-shortName,name``

In order to enable the JSON API compliant URL handling, a ``QuerySpecDeserializer`` instead of ``QueryParamsBuilder``
has to be provided when setting up Katharsis (see the corresponding documentation for the
various technology stacks). Typically the default implementation ``DefaultQuerySpecDeserializer``
is perfectly fine. In JAX-RS it looks like:

.. code-block:: java

	@ApplicationPath("/")
	public class MyApplication extends Application {
	
		@Override
		public Set<Object> getSingletons() {
			DefaultQuerySpecDeserializer querySpecDeserializer = new DefaultQuerySpecDeserializer();
			KatharsisFeature feature = new KatharsisFeature(new ObjectMapper(), querySpecDeserializer, serviceLocator);
			return Collections.singleton((Object)feature);
		}
	}
	
or just


.. code-block:: java

	@ApplicationPath("/")
	public class MyApplication extends Application {
	
		@Override
		public Set<Class<?>> getClasses() {
			return Collections.singleton(Katharsis.class);
		}
	}

	
Have a look at the examples. All of them are setup to use QuerySpec. 
	
``DefaultQuerySpecDeserializer`` provides some customization options:

* ``setDefaultLimit(Long)``
	Sets the page limit if none is specified by the request.
	
* ``setIgnoreUnknownAttributes(boolean)``
	DefaultQuerySpecDeserializer validates all passed parameters against the domain model and fails
	if one of the attributes is unknown. This flag allows to disable that check in case the should be necessary.

Note that *QueryParams is not working with the new serializer*. This means repositories must be 
migrated to QuerySpec first. This can happen gradually or in one step. Katharsis
internally converts QueryParams to QuerySpec where necessary as long as the old serializer is in use.


Filtering
~~~~~~~~~

Resource filtering can be achieved by providing parameters which start with ``filter``.
The format for filters: ``filter[ResourceType][property|operator]([property|operator])* = "value"``

QuerySpec examples:

* ``GET /tasks/?filter[name]=Super task``
* ``GET /tasks/?filter[name][EQ]=Super task``
* ``GET /tasks/?filter[tasks][name]=Super task``
* ``GET /tasks/?filter[tasks][name]=Super task&filter[tasks][dueDate]=2015-10-01``

QueryParams examples:

* ``GET /tasks/?filter[tasks][name]=Super task``
* ``GET /tasks/?filter[tasks][name]=Super task&filter[tasks][dueDate]=2015-10-01``
* ``GET /tasks/?filter[tasks][name][EQ]=Super task``
* ``GET /tasks/?filter[tasks][name][][$startWith]=Super&filter[tasks][name][][$endWith]=task``

QuerySpec uses the ``EQ`` operator if no operator was provided. Custom operators can be registered
with ``DefaultQuerySpecDeserializer.addSupportedOperator(..)``. The default operator can be 
overridden by setting ``DefaultQuerySpecDeserializer.setDefaultOperator(...)``.<commit_msg>Update user-docs.rst<commit_after>How to use Katharsis in your applications
=========================================

Katharsis provides means to easily expose resources over the REST interface. If you want to take a deeper look on the concepts behind Katharsis, this is page for you!


Requirements
------------

Below are listed dependencies used in Katharsis that project has to meet to be compatible with latest library version:

.. note::
  Katharsis library requires minimum Java 7 to build and run.


``katharsis-core``

.. code-block:: bash

  io.katharsis:katharsis-core:bundle:2.6.0
  +- org.reflections:reflections:jar:0.9.9:compile
  |  +- com.google.guava:guava:jar:15.0:compile
  |  +- org.javassist:javassist:jar:3.18.2-GA:compile
  |  \- com.google.code.findbugs:annotations:jar:2.0.1:compile
  +- net.jodah:typetools:jar:0.4.4:compile
  +- org.slf4j:slf4j-api:jar:1.7.13:compile
  +- com.fasterxml.jackson.core:jackson-databind:jar:2.6.3:compile
  |  \- com.fasterxml.jackson.core:jackson-core:jar:2.6.3:compile
  +- com.fasterxml.jackson.core:jackson-annotations:jar:2.6.3:compile


``katharsis-rs``

.. code-block:: bash

  io.katharsis:katharsis-rs:bundle:2.6.0
  +- io.katharsis:katharsis-core:jar:2.6.0:compile
  |  +- net.jodah:typetools:jar:0.4.4:compile
  |  +- org.slf4j:slf4j-api:jar:1.7.13:compile
  |  \- com.fasterxml.jackson.core:jackson-databind:jar:2.6.3:compile
  |     \- com.fasterxml.jackson.core:jackson-core:jar:2.6.3:compile
  +- com.fasterxml.jackson.core:jackson-annotations:jar:2.6.3:compile
  +- org.reflections:reflections:jar:0.9.9:compile
  |  +- com.google.guava:guava:jar:15.0:compile
  |  +- org.javassist:javassist:jar:3.18.2-GA:compile
  |  \- com.google.code.findbugs:annotations:jar:2.0.1:compile
  +- javax.ws.rs:javax.ws.rs-api:jar:2.0.1:compile
  +- javax.servlet:javax.servlet-api:jar:3.0.1:compile


``katharsis-servlet``

.. code-block:: bash

  io.katharsis:katharsis-servlet:bundle:2.6.0
  +- io.katharsis:katharsis-core:jar:2.6.0:compile
  |  +- net.jodah:typetools:jar:0.4.4:compile
  |  +- com.fasterxml.jackson.core:jackson-databind:jar:2.6.3:compile
  |  |  \- com.fasterxml.jackson.core:jackson-core:jar:2.6.3:compile
  |  \- com.fasterxml.jackson.core:jackson-annotations:jar:2.6.3:compile
  +- org.reflections:reflections:jar:0.9.9:compile
  |  +- org.javassist:javassist:jar:3.18.2-GA:compile
  |  \- com.google.code.findbugs:annotations:jar:2.0.1:compile
  +- com.google.guava:guava:jar:15.0:compile
  +- javax.servlet:javax.servlet-api:jar:3.0.1:provided
  +- org.slf4j:slf4j-api:jar:1.7.6:provided


``katharsis-spring``

.. code-block:: bash

  io.katharsis:katharsis-spring:bundle:2.6.0
  +- org.springframework.boot:spring-boot-starter-web:jar:1.3.1.RELEASE:compile
  |  ...
  +- org.springframework.boot:spring-boot-configuration-processor:jar:1.3.1.RELEASE:compile
  |  +- org.json:json:jar:20140107:compile
  |  \- org.springframework:spring-core:jar:4.2.4.RELEASE:compile
  |     \- commons-logging:commons-logging:jar:1.2:compile
  +- io.katharsis:katharsis-servlet:jar:2.6.0:compile
  |  +- io.katharsis:katharsis-core:jar:2.6.0:compile
  |  |  +- net.jodah:typetools:jar:0.4.4:compile
  |  |  \- org.slf4j:slf4j-api:jar:1.7.13:compile
  |  \- com.google.guava:guava:jar:15.0:compile
  +- org.reflections:reflections:jar:0.9.9:compile
  |  +- org.javassist:javassist:jar:3.18.2-GA:compile
  |  \- com.google.code.findbugs:annotations:jar:2.0.1:compile


``katharsis-vertx``

.. code-block:: bash

  +--- io.katharsis:katharsis-core:2.99.0-SNAPSHOT
  |    +--- org.projectlombok:lombok:1.16.8
  |    +--- net.jodah:typetools:0.4.4
  |    +--- org.slf4j:slf4j-api:1.7.13
  |    +--- com.fasterxml.jackson.core:jackson-databind:2.6.3
  |    |    +--- com.fasterxml.jackson.core:jackson-annotations:2.6.0 -> 2.6.3
  |    |    \--- com.fasterxml.jackson.core:jackson-core:2.6.3
  |    \--- com.fasterxml.jackson.core:jackson-annotations:2.6.3
  +--- io.vertx:vertx-core:3.2.1
  ...
  +--- io.vertx:vertx-web:3.2.1
  ...
  +--- org.reflections:reflections:0.9.9
  |    +--- com.google.guava:guava:15.0
  |    +--- org.javassist:javassist:3.18.2-GA
  |    \--- com.google.code.findbugs:annotations:2.0.1
  \--- org.slf4j:slf4j-api:1.7.13

  ``katharsis-client``

  .. code-block:: bash

  io.katharsis:katharsis-client:bundle:2.6.0
  +- io.katharsis:katharsis-core:jar:2.6.0:compile
  |  +- net.jodah:typetools:jar:0.4.4:compile
  |  +- org.slf4j:slf4j-api:jar:1.7.13:compile
  |  +- com.fasterxml.jackson.core:jackson-databind:jar:2.6.3:compile
  |  |  \- com.fasterxml.jackson.core:jackson-core:jar:2.6.3:compile
  |  \- com.fasterxml.jackson.core:jackson-annotations:jar:2.6.3:compile
  +- org.reflections:reflections:jar:0.9.9:compile
  |  +- com.google.guava:guava:jar:15.0:compile
  |  +- org.javassist:javassist:jar:3.18.2-GA:compile
  |  \- com.google.code.findbugs:annotations:jar:2.0.1:compile
  +- com.squareup.okhttp:okhttp:jar:2.7.5:compile
  |  \- com.squareup.okio:okio:jar:1.6.0:compile

Supported requests
------------------

Currently Katharsis covers most of the JSON API specification request types. The following table describes available requests that are currently accepted:

.. csv-table:: A summary of the supported requests
  :header:  HTTP method, Kind of request, Sample URL,  Multiplicity of resource

  GET,	resources, "http://host.local/tasks or http://host.local/tasks/1,2", multiple
  ,resource,	http://host.local/tasks/1,	single
  ,relationship,	http://host.local/tasks/1/relationships/project,	single
  ,field,	http://host.local/tasks/1/project,	single
  POST,	resource,	http://host.local/tasks,	single
  ,field,	http://host.local/tasks/1/project,	single
  ,relationship,	http://host.local/tasks/1/relationships/project,	single
  PATCH,	resource,	http://host.local/tasks/1,	single
  ,relationship,	http://host.local/tasks/1/relationships/project,	single
  DELETE,	resource,	http://host.local/tasks/1,	single
  ,relationship,	http://host.local/tasks/1/relationships/project,	single



Relationships
-------------

One of the main features of JSON API and Katharsis is support of managing relations between resources. To achieve that, two steps are required:

* Add a field annotated with JsonApiToOne or JsonApiToMany (depending on multiplicity of the relation) which will represent a unidirectional relation.
* Add a repository which defines operations that can be made on models.


Models
------

There are several annotations which can be assigned to models. By default all fields of the model are reflected in JSON API communication except synthetic fields. The annotations described below should be associated with either a field or a getter.


JsonApiResource
~~~~~~~~~~~~~~~

It is the most important annotation which defines a resource. It requires type parameter to be defined that is used to form a URLs and type field in passed JSONs. According to JSON API standard, the name defined in type can be either plural or singular

The example below shows a sample class which contains a definition of a resource.

.. code-block:: java

  @JsonApiResource(type = "tasks")
  public class Task {
    // fields, getters and setters
  }


JsonApiId
~~~~~~~~~

Defines a field which will be used as an identifier of a resource.
Each resource requires this annotation to be present on a field which type implements ``Serializable`` or is of primitive type.

The example below shows a sample class which contains a definition of a field which contains an identifier.

.. code-block:: java

  @JsonApiResource(type = "tasks")
  public class Task {
    @JsonApiId
    private Long id;

    // fields, getters and setters
  }

JsonApiToOne
~~~~~~~~~~~~

Indicates an association to single value which needs to be handled by a separate ``RelationshipRepository``.
 A type of the field has to be a valid resource.

The example below shows a sample class which contains this kind of relationship.


.. code-block:: java

  @JsonApiResource(type = "tasks")
  public class Task {

    // ID field

    @JsonApiToOne
    private Project project;

    // fields, getters and setters
  }

JsonApiToMany
~~~~~~~~~~~~~

Indicates an association to many values which need to be handled by a separate ``RelationshipRepository``.
A type of the field has to be an ``Iterable`` or its derived classes (e.g.``List``) of valid resources.
By default, relationship is considered to be lazy, that is the relationship is not shown in the Top Level JSON.
To change that, pass parameter ``@JsonApiToMany(lazy = false)``.

The example below shows a sample class which contains this kind of relationship.

.. code-block:: java

  @JsonApiResource(type = "tasks")
  public class Task {

    // ID field

    @JsonApiToMany(lazy = false)
    private List<Project> projects;

    @JsonApiToMany // not shown in Top Level JSON
    private List<Log> logs;

    // fields, getters and setters
  }



JsonApiIncludeByDefault
~~~~~~~~~~~~~~~~~~~~~~~

Indicates additional resources that should be included by default (will be available
in included field of Top level JSON object) with every primary resource.
The field can be added to every relationship defined by ``JsonApiToOne`` or ``JsonApiToMany``.
Otherwise, ``ResourceException`` will be thrown at the initialization phrase.

The example below shows a sample model with this annotation.

.. code-block:: java

  @JsonApiResource(type = "tasks")
  public class Task {

    // ID field

    @JsonApiToOne
    @JsonApiIncludeByDefault
    private Project project;

    // fields, getters and setters
  }

JsonApiLookupIncludeAutomatically
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Field or getter annotated with ``JsonApiLookupIncludeAutomatically`` will be automatically populated by Katharsis on ``GET`` requests.
It can be added to every relationship defined by ``JsonApiToOne`` or ``JsonApiToMany``.

The example below shows a sample class which will always contain a relationship's resource.

.. code-block:: java

  @JsonApiResource(type = "tasks")
  public class Task {

    // ID field

    @JsonApiToOne
    @JsonApiLookupIncludeAutomatically
    private Project project;

    // fields, getters and setters
  }








JsonApiMetaInformation
~~~~~~~~~~~~~~~~~~~~~~~

Field or getter annotated with ``JsonApiMetaInformation`` are marked to carry a ``MetaInformation`` implementation.
See http://jsonapi.org/format/#document-meta for more information about meta data. Example:


.. code-block:: java
	
	@JsonApiResource(type = "projects")
	public class Project {
	
		...
	
		@JsonApiMetaInformation
		private ProjectMeta meta;
	
		public static class ProjectMeta implements MetaInformation {
	
			private String value;
	
			public String getValue() {
				return value;
			}
	
			public void setValue(String value) {
				this.value = value;
			}
		}
	}



JsonApiLinksInformation
~~~~~~~~~~~~~~~~~~~~~~~

Field or getter annotated with ``JsonApiLinksInformation`` are marked to carry a ``LinksInformation`` implementation.
See http://jsonapi.org/format/#document-links for more information about linking. Example:


.. code-block:: java
	
	@JsonApiResource(type = "projects")
	public class Project {
	
		...
	
		@JsonApiLinksInformation
		private ProjectLinks links;
	
		public static class ProjectLinks implements MetaInformation {
	
			private String value;
	
			public String getValue() {
				return value;
			}
	
			public void setValue(String value) {
				this.value = value;
			}
		}
	}





Repositories
------------

The model definition must have corresponding resource repository.
In addition, each relation also must have a corresponding repository.

Those repositories can be defined in one of the two ways:

* Implementing a repository interface:

  * ResourceRepositoryV2 for a resource
  * RelationshipRepositoryV2 for resource relationships

* Annotated with a repository annotation:

  * JsonApiResourceRepository for a resource
  * JsonApiRelationshipRepository for resource relationships
  
Both approaches have their merits. But note that the use of interfaces has
one main advantage over annotated repositories: the interfaces are  
supported by ``katharsis-client``. Applications may declare their own 
interfaces, extending the ones of Katharsis with type arguments
and additional actions. On the server side, repository interfaces
are implemented by the repository implementations. On the client side,
``katharsis-client`` can automatically create stubs to have 
type-safe access to remote repositories. More information is available
with the client documentation further down.


ResourceRepositoryV2
~~~~~~~~~~~~~~~~~~~~

Base repository which is used to operate on resources.
Each resource should have a corresponding repository implementation.
It consist of five basic methods which provide a CRUD for a resource and two parameters: the first is a type of a resource and the second is a type of the resource’s identifier.

The methods are as follows:

* ``findOne(ID id, QuerySpec querySpec)``
  Search one resource with a given ID. If a resource cannot be found, a ResourceNotFoundException exception should be thrown.
  It should return an entity with associated relationships.

* ``findAll(QuerySpec querySpec)``
  Search for all of the resources. An instance of QueryParams can be used if necessary.
  If no resources can be found an empty Iterable or null must be returned.
  It should return entities with associated relationships.

* ``findAll(Iterable<ID>ids, QuerySpec querySpec)``
  Search for resources constrained by a list of identifiers. An instance of QueryParams can be used if necessary.
  If no resources can be found an empty Iterable or null must be returned.
  It should return entities with associated relationships.

* ``save(S entity)``
  Saves a resource. It should not save relating relationships. A Returning resource must include assigned identifier created for the instance of resource.
  This method should be able to both create a new resource and update existing one.

* ``delete(ID id)``
  Removes a resource identified by id parameter.
  
The ResourceRepositoryBase is a base class that takes care of some boiler-plate, like implementing findOne with findAll. An
implementation can then look as simple as:

.. code-block:: java

	public class ProjectRepository extends ResourceRepositoryBase<Project, String> {
	
		private Map<Long, Project> projects = new HashMap<>();
	
		public ProjectRepository() {
			super(Project.class);
			save(new Project(1L, "Project A"));
			save(new Project(2L, "Project B"));
			save(new Project(3L, "Project C"));
		}
	
		@Override
		public synchronized void delete(String id) {
			projects.remove(id);
		}
	
		@Override
		public synchronized <S extends Project> S save(S project) {
			projects.put(project.getId(), project);
			return project;
		}
	
		@Override
		public synchronized ResourceList<Project> findAll(QuerySpec querySpec) {
			return querySpec.apply(projects.values());
		}
	}


RelationshipRepositoryV2
~~~~~~~~~~~~~~~~~~~~~~~~

Each relationship defined in Katharsis (annotation @JsonApiToOne and @JsonApiToMany) must have a relationship repository defined.

Base unidirectional repository responsible for operations on relations.
All of the methods in this interface have fieldName field as their last parameter to solve the problem of many relationships between the same resources.

* ``setRelation(T source, D_ID targetId, String fieldName)``
  Sets a resource defined by targetId to a field fieldName in an instance source. If no value is to be set, null value is passed.

* ``setRelations(T source, Iterable<D_ID> targetIds, String fieldName)``
  Sets resources defined by targetIds to a field fieldName in an instance source. This is a all-or-nothing operation, that is no partial relationship updates are passed. If no values are to be set, empty Iterable is passed.

* ``addRelations(T source, Iterable<D_ID> targetIds, String fieldName)``
  Adds relationships to a list of relationships.

* ``removeRelations(T source, Iterable<D_ID> targetIds, String fieldName)``
  Removes relationships from a list of relationships.

* ``findOneTarget(T_ID sourceId, String fieldName, QuerySpec querySpec)``
  Finds one field's value defined by fieldName in a source defined by sourceId.

* ``findManyTargets(T_ID sourceId, String fieldName, QuerySpec querySpec)``
  Finds an Iterable of field's values defined by fieldName in a source defined by sourceId .


This interface must be implemented to let Katharsis work correctly, some of the requests are processed using only this kind of repository.
As it can be seen above, there are two kinds of methods: for multiple and single relationships and it is possible to implement only one type of methods, e.g. singular methods.
Nevertheless, it should be avoided because of potential future problems when adding new fields of other sizes.

In many cases, relationship operations can be mapped back to resource repository operations. Making the need
for a custom relationship repository implementation redundant. A findManyTargets request might can be
served by filtering the target repository. Or a relationship can be set by invoking the save operation 
on either the source or target resource repository (usually you want to save on the single-valued side).
The ResourceRepositoryBase is a base class that takes care of exactly this. A repository
implementation then looks as simple as:


.. code-block:: java

	public class ProjectToTaskRepository extends RelationshipRepositoryBase<Project, Long, Task, Long> {
	
		public ScheduleToTaskRepository() {
			super(Project.class, Task.class);
		}
	}


For this to work, relations must be set up bidirectionally with the ``opposite`` attribute:

.. code-block:: java
	
	@JsonApiResource(type = "tasks")
	public class Task {
	
		@JsonApiToOne(opposite = "tasks")
		@JsonApiIncludeByDefault
		private Project project;
	
	    ...
	}




ResourceList
~~~~~~~~~~~~~~~~~~~~~~~~

ResourceRepositoryV2 and RelationshipRepositoryV2 return lists of type ResourceList. The ResourceList can carry, next
to the actual resources, also meta and links information:

* ``getLinks()``
	Gets the links information attached to this lists.
	
* ``getMeta()``
	Gets the meta information attached to this lists.

* ``getLinks(Class<L> linksClass)``
	Gets the links information of the given type attached to this lists. If the given type is not found, null is returned.

* ``getMeta(Class<M> metaClass)``
	Gets the meta information of the given type attached to this lists. If the given type is not found, null is returned.

Thhere is a default implementation named DefaultResourceList. To gain type-safety, improved readability and katharsis-client support,
application may provide a custom implementation extending ResourceListBase:

.. code-block:: java

	class ScheduleList extends ResourceListBase<Schedule, ScheduleListMeta, ScheduleListLinks> {

	}
	
	class ScheduleListLinks implements LinksInformation {

		public String name = "value";
		
		...
	}

	class ScheduleListMeta implements MetaInformation {

		public String name = "value";
		
		...
	}
	
This implementation can then be added to a repository interface declaration
and used by both servers and clients:

.. code-block:: java

	public interface ScheduleRepository extends ResourceRepositoryV2<Schedule, Long> {
	
		@Override
		public ScheduleList findAll(QuerySpec querySpec);
		
	}






Annotated repositories
~~~~~~~~~~~~~~~~~~~~~~

A resource repository can also be defined using the ``JsonApiResourceRepository`` or ``JsonApiRelationshipRepository`` annotations from ``io.katharsis.repository.annotations`` package.

Defining the repositories this way has two benefits:

* It's not necessary to define all of the methods i.e. read-only resources might have just reading methods defined
* Additional parameters can be added to the methods like authentication, request headers or cookies

Along with the required parameters for each methods (like the resource identifier in ``JsonApiFindOne``), the default supported type is QueryParams, which provides a set of parsed query parameters.
Each Katharsis integration provides different set of supported parameters.
This list can be found in JAX-RS and Servlet integration sections.

A list below defines a mapping of ``ResourceRepository`` methods to annotations:

* ``findOne(ID, QueryParams) -> JsonApiFindOne``

  The first parameter must be a resource's id. This method must return one resource.

* ``findAll(QueryParams) -> JsonApiFindAll``

  This method must return a list of resources.

* ``findAll(Iterable<ID>, QueryParams) -> JsonApiFindAllWithIds``

  The first parameter must be a list of resource ids. This method must return a list of resources.

* ``save(S) -> JsonApiSave``

  The first parameter must be a resource. This method must return one resource.

* ``delete(ID) -> JsonApiDelete``

  The first parameter must be a resource's id.


A list below defines a mapping of ``RelationshipRepository`` methods to annotations:

* ``setRelation(T, D_ID, String) -> JsonApiSetRelation``

  The requirements for the method parameters are as follows:

  #. Instance of a source resource
  #. Instance of a relationship to be set
  #. Relationship's field name

* ``setRelations(T, Iterable<D_ID>, String) -> JsonApiSetRelations``

  The requirements for the method parameters are as follows:

  #. Instance of a source resource
  #. ``Iterable`` of relationships to be set
  #. Relationship's field name

* ``addRelations(T, Iterable<D_ID>, String) -> JsonApiAddRelation``

  The requirements for the method parameters are as follows:

  #. Instance of a source resource
  #. Iterable of relationships to be add
  #. Relationship's field name

* ``removeRelations(T, Iterable<D_ID>, String) -> JsonApiRemoveRelation``

  The requirements for the method parameters are as follows:

  #. Instance of a source resource
  #. Iterable of relationships to be removed
  #. Relationship's field name

* ``findOneTarget(T_ID, String, QuerySpec) -> JsonApiFindOneTarget``

  The requirements for the method parameters are as follows:

  #. An identifier of a source resource
  #. Relationship's field name
  #. The method has to return a resources.

* ``findManyTargets(T_ID, String, QuerySpec) -> JsonApiFindManyTargets``

  The requirements for the method parameters are as follows:

  #. An identifier of a source resource
  #. Relationship's field name
  #. The method has to return an Iterable with resources.



Query parameters
----------------

Katharsis has defined set of query parameters which can be used by the framework during data retrieval and by a developer to perform other operations.
All of the types of parameters can be accessed with the either QueryParams or QuerySpec object in repository methods.


QuerySpec vs. QueryParams
~~~~~~~~~~~~~~~~~~~~~~~~~~~

Note that if you are new to Katharsis and have setup your applications based on the
examples, you can skip this section. Everything is already properly setup for you.

QueryParams is the traditional query api of Katharsis. QuerySpec is a new API 
with the purpose of simplifying the implementation of repositories and offering 100% JSON API compliance
See the next section for more information about JSON API compliance.

QuerySpec is a drop-in replacement for QueryParams in annotated repositories.
``ResourceRepository`` and ``RelationshipRepository`` make use of QueryParams.
``ResourceRepositoryV2`` and ``RelationshipRepositoryV2`` make use of QuerySpec.

For the time being, both QueryParams and QuerySpec are fully supported. But
QueryParams will be deprecated at some point and the use of QuerySpec is highly
recommended. It is also possible to mix the use of both classes to gradually move
from QueryParams to QuerySpec. Katharsis is able to internally 
convert QueryParams to a QuerySpec. No changes necessary.

The next section outlines the necessary changes in the setup procedure to gain JSON API compliance.


JSON API compliance
~~~~~~~~~~~~~~~~~~~~

Note that if you are new to Katharsis and have setup your applications based on the
examples, you can skip this section. Everything is already properly setup for you.

The subsequent sections outline URL conventions to query resources.
QueryParams does not fully adhere to the JSON API specification and instead
provides a number of improvements over the specification. QuerySpec strives to offer both,
JSON API compliance and some more advanced URL patterns.

Most notably, QuerySpec supports the ordered sorting on multiple attributes 
by providing an ordered list of those sorted attributes. And QueryParams 
introduced support to not only sort and filter requested resources, but also included related resources.
Because of this, sort and filter parameters require an additional type passed in the parameter name.
With QuerySpec this type becomes optional and the requested (root) type is used by default. The
following two requests are equivalent:

``GET /tasks/?sort[tasks]=!shortName,name``

and more simply just:

``GET /tasks/?sort=-shortName,name``

In order to enable the JSON API compliant URL handling, a ``QuerySpecDeserializer`` instead of ``QueryParamsBuilder``
has to be provided when setting up Katharsis (see the corresponding documentation for the
various technology stacks). Typically the default implementation ``DefaultQuerySpecDeserializer``
is perfectly fine. In JAX-RS it looks like:

.. code-block:: java

	@ApplicationPath("/")
	public class MyApplication extends Application {
	
		@Override
		public Set<Object> getSingletons() {
			DefaultQuerySpecDeserializer querySpecDeserializer = new DefaultQuerySpecDeserializer();
			KatharsisFeature feature = new KatharsisFeature(new ObjectMapper(), querySpecDeserializer, serviceLocator);
			return Collections.singleton((Object)feature);
		}
	}
	
or just


.. code-block:: java

	@ApplicationPath("/")
	public class MyApplication extends Application {
	
		@Override
		public Set<Class<?>> getClasses() {
			return Collections.singleton(Katharsis.class);
		}
	}

	
Have a look at the examples. All of them are setup to use QuerySpec. 
	
``DefaultQuerySpecDeserializer`` provides some customization options:

* ``setDefaultLimit(Long)``
	Sets the page limit if none is specified by the request.
	
* ``setIgnoreUnknownAttributes(boolean)``
	DefaultQuerySpecDeserializer validates all passed parameters against the domain model and fails
	if one of the attributes is unknown. This flag allows to disable that check in case the should be necessary.

Note that *QueryParams is not working with the new serializer*. This means repositories must be 
migrated to QuerySpec first. This can happen gradually or in one step. Katharsis
internally converts QueryParams to QuerySpec where necessary as long as the old serializer is in use.


Filtering
~~~~~~~~~

Resource filtering can be achieved by providing parameters which start with ``filter``.
The format for filters: ``filter[ResourceType][property|operator]([property|operator])* = "value"``

QuerySpec examples:

* ``GET /tasks/?filter[name]=Super task``
* ``GET /tasks/?filter[name][EQ]=Super task``
* ``GET /tasks/?filter[tasks][name]=Super task``
* ``GET /tasks/?filter[tasks][name]=Super task&filter[tasks][dueDate]=2015-10-01``

QueryParams examples:

* ``GET /tasks/?filter[tasks][name]=Super task``
* ``GET /tasks/?filter[tasks][name]=Super task&filter[tasks][dueDate]=2015-10-01``
* ``GET /tasks/?filter[tasks][name][EQ]=Super task``
* ``GET /tasks/?filter[tasks][name][$startWith]=Super&filter[tasks][name][$endWith]=task``

QuerySpec uses the ``EQ`` operator if no operator was provided. Custom operators can be registered
with ``DefaultQuerySpecDeserializer.addSupportedOperator(..)``. The default operator can be 
overridden by setting ``DefaultQuerySpecDeserializer.setDefaultOperator(...)``.
{'fraction_non_alphanumeric': 0.10234817813765182, 'fraction_numerical': 0.011120107962213225, 'mean_word_length': 4.301030141167494, 'pattern_counts': {'":': 0, '<': 49, '<?xml version=': 0, '>': 73, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 32}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6052098', 'n_tokens_mistral': 16607, 'n_tokens_neox': 15398, 'n_words': 5742}