Is it possible to allow query method @Params to be optional, specifically in the case of Spring Data REST?
For example, I'd like to bind a very similar search to the same resource path. To do this now, I would need something like the following:
@RestResource(path = "driver", rel = "byDriver")
List<Bar> findByDriverId(@Param("id") String id, Pageable pageable);
@RestResource(path = "driverAndSpan", rel = "byDriverAndSpan")
List<Bar> findByDriverIdAndStartTimeGreaterThanEqualAndEndTimeLessThanEqual(@Param("id") String id, @Param("start") Date start,
@Param("end") Date end, Pageable pageable);
Which gives me:
byDriver: {
href: "http://localhost:8080/foo/search/driver{?id,page,size,sort}",
},
byDriverAndSpan: {
href: "http://localhost:8080/foo/search/driverAndSpan{?id,start,end,page,size,sort}",
}
What I want is to be able to see something like the following path, where start
and end
are optional parameters, rather than defining multiple methods in my Repository.
byDriverAndSpan: {
href: "http://localhost:8080/foo/search/driverAndSpan{?id,*start,*end,page,size,sort}",
}
Which could potentially look like:
@RestResource(path = "driverAndSpan", rel = "byDriverAndSpan")
List<Bar> findByDriverIdAndStartTimeGreaterThanEqualAndEndTimeLessThanEqual(@Param("id") String id, @Param(value = "start", optional = true) Date start,
@Param(value = "end", optional = true) Date end, Pageable pageable);
You can do it in three ways: Set required = false in @RequestParam annotation. Set defaultValue = “any default value” in @RequestParam annotation. Using Optional keyword.
CrudRepository mainly provides CRUD operations. PagingAndSortingRepository provide methods to perform pagination and sorting of records. JpaRepository provides JPA related methods such as flushing the persistence context and deleting of records in batch.
Its findById method retrieves an entity by its id. The return value is Optional<T> . Optional<T> is a container object which may or may not contain a non-null value. If a value is present, isPresent returns true and get returns the value.
The JPA specification defines that during ordering, NULL values shall be handled in the same way as determined by the SQL standard. The standard specifies that all null values shall be returned before or after all non-null values. It's up to the database to pick one of the two options.
Maybe you can define a 'main' function as default
which will delegate to the other functions. Something like this
@RestResource(path = "driverAndSpan", rel = "byDriverAndSpan")
default List<Bar> findByDriverIdAndOptionalStartTimeGreaterThanEqualAndOptionalEndTimeLessThanEqual(@Param("id") String id, @Param(value = "start", optional = true) Date start,
@Param(value = "end", optional = true) Date end, Pageable pageable) {
if(start != null && end != null) {
return findByDriverIdAndStartTimeGreaterThanEqualAndEndTimeLessThanEqual(id, start, end, pageable);
}
return findByDriverId(id, pageable);
}
I think you can even use Optional
as a parameter type, then you can use function overloading
@RestResource(path = "driverAndSpan", rel = "byDriverAndSpan")
default List<Bar> findByDriverIdAndStartTimeGreaterThanEqualAndEndTimeLessThanEqual(
@Param("id") String id, @Param(value = "start") Optional<Date> start,
@Param(value = "end") Optional<Date> end, Pageable pageable) {
if (!start.isEmpty() && !end.isEmpty()) {
return findByDriverIdAndStartTimeGreaterThanEqualAndEndTimeLessThanEqual(id, start.get(), end.get(), pageable);
}
return findByDriverId(id, pageable);
}
List<Bar> findByDriverIdAndStartTimeGreaterThanEqualAndEndTimeLessThanEqual(String id, Date start, Date end, Pageable pageable);
Notice that in this case, you shouldn't expose the other endpoints, and only expose this default method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With