Facilitate searches in RESTful API with JApiFilter

Julio Falbo2 min read
Listen to it, read by Julio Falbo (3 min)
3:00

Hello People!!

I was recently having a conversation with my team about REST good practices and the subject about search parameters came up.

This subject appeared because we saw in old applications attribute search endpoints being exposed as follows: “users/searchByFirstName/{firstName}”, “users/searchByLastName/{lastName}”.

The template shown above works, but is completely out of REST good practice.
Following the good practices of a RESTful application, we must respect the http methods and the domain of our resource, so, the correct would be to make a call using the GET method for the domain URI, for example /users. This call will return all users in your application.

Following this, we must implement filters based on optional Query Parameters in this endpoint. e.g. “/users?firstName=Julio&lastName=Falbo” so that we get a return based on the filters sent as URL parameters.

Ok Julio, but how to implement this?

There are several ways to implement this type of search, however the first that is thought is to fill your code with if and else.

Java
if(firstName != null && !firstName.isEmpty()){
 query += "and firstName=" + firstName;
}
...

The implementation shown above will work, however we will have a very dirty code with high complexity.

Thinking about this problem, I developed a lib (JApiFilter) based on the Spring Data JPA Specificationinterface.

And how does it work?

Basically, I defined the most commonly used search strategies to make it easy to create filters, but you can extend the JApiDefaultSpecification class and customize other behaviors using CriteriaBuilder.
Note: You can check the strategies defined in the JApiOperationEnumenum.

With search strategies defined you can build your Specification object, is just now that the idea of Builder comes in.

To do this I’ve created the JApiSpecificationBuilder class that allows you to intuitively and cleanly create your filters.
Note: If the filter value is passed as null, the search will ignore that condition.

This builder allows 2 way to create the filters.

The first way is based on an entity with the filled values (following the idea of ExampleMatcher, explained below). The createFiltersByEntity method expects the entity and the search strategy.

Java
Specification<YourEntity> specification = JApiSpecificationBuilder.init()
                .createFiltersByEntity(yourEntity, JApiOperationEnum.EQUAL)
                .buildSpec();

The second way is to create the filters by passing the name of the field to be compared and the value.

Java
Specification<YourEntity> specification = JApiSpecificationBuilder.init()
                .withEqualFilter("yourVarName", yourObject)
                .withBiggerFilter("yourVarName", yourObject)
                .withSmallerFilter("yourVarName", yourObject)
                .withLikeFilter("yourVarName", yourObject)
                .withInFilter(new FieldIn("yourFieldList", "attributeName"), yourObject)
                .withCustomFilter("yourVarName", yourObject, JApiOperationEnum.[yourChoise])
                .buildSpec();

The second strategy facilitated by this lib is to create an Example object based on the ExampleMatcher to perform searches based on an example entity.

ExampleMatcheris an interface inserted in Spring Data Coresince version 1.12.

It basically requires an entity instance populated with search values, just like an example.

Thinking about making this powerful feature even easier, I created a Generic Builder and the Example object is created at runtime.

Note: By default, I create the ExampleMatcher object by ignoring null values and ignoring the case.

Java
Example<YourEntity> example = new ExampleBuilder(YourEntity.class).
    .addFilter("yourField", yourObject)
    .build();

I hope this library will help you and make your life easier by following REST good practices.

Note: If you have identified an improvement opportunity, some bug, or even an idea for a new feature, please clone the project and open a pull request. I will be very happy with that!

Library link: https://github.com/juliofalbo/j-api-filter

Share on LinkedIn

Originally published on Medium on Feb 1, 2019. Claps and comments live there.

Comments

No comments yet. Be the first.

We email you a 6-digit code to publish it. Your email is never shown.

← More articles · follow by RSS