Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Spring Data Rest support Spring Data's expression operators, eg. Between, GreaterThan?

I know Spring Data Common supports queries(methods in the repository) with operators such as Between, LessThan, GreaterThan, Like for the property expressions.

I am wondering if these operators are also supported in Data Rest? If supported, what do the Rest API URLs look like when these operators are used. For example, if I need to query people whose age is between 20 and 30. Query in repository should be List<Person> findByAgeBetween(Long min, Long max); But what is the URL?

I couldn't find anything related to this question in the spring reference.

like image 479
Kyle Avatar asked Oct 22 '25 15:10

Kyle


2 Answers

So what I am assuming here is that you have the following repository:

interface PersonRepository extends CrudRepository<Person, Long> {

  List<Person> findByAgeBetween(Long min, Long max);
}

Based on this you'd get the following resources exposed:

  1. A collection resource as generally described here named persons (we're using a pluralization library by default, but you can tweak these names and paths using @RepositoryRestResource).

  2. An item resource as generally described here for each element in the collection.

  3. A search resource named search as generally described here. It contains a list of links pointing to individual query method resources (see next).

  4. A query method resource per query method as generally described here. The parameter names need to be defined using @Param annotations as on Java versions before 8, interface methods do not carry naming information so that we cannot find out about it. That means an improved repository declaration would look something like this:

     interface PersonRepository extends CrudRepository<Person, Long> {
    
       List<Person> findByAgeBetween(@Param("min") Long min, @Param("max") Long max);
     }
    

This will cause the following output when you access the search resource:

    _links : {
      self : { href : "…" },
      findByAgeBetween : {
        href : "…/persons/search/findByAgeBetween{?min,max}",
        templated : true
      }
    }

A client would now go ahead, find the link named findByAgeBetween, recognize that its an RFC 6570 Uri template (through the templated parameter as the HAL spec suggests) and expand the template with the adequate values for min and max.

The important aspect here is that the server is free to change the URI structure as long as the parameter names stay the same. You could go ahead and rather use path variables instead of request parameters or the like. By using the template approach the client doesn't need to know about the structure. It only knows about template variables in general.

Both the name of the link and the path can be customized by using @RestResource on the query method.

like image 138
Oliver Drotbohm Avatar answered Oct 24 '25 06:10

Oliver Drotbohm


In the 1.1 docs you can find this example:

The following would use the findByNameStartsWith query method defined on the PersonRepository for all Person entities with names starting with the letter "K" and add sort data that orders the results on the name property in descending order:

curl -v http://localhost:8080/people/search/nameStartsWith?name=K&sort=name&name.dir=desc

So in your case it would be:

curl -v http://localhost:8080/person/search/ageBetween?min=xxx&max=yyy
like image 21
Vlad Mihalcea Avatar answered Oct 24 '25 05:10

Vlad Mihalcea