Home > Blockchain >  Offset and Limit are not Working in GET API
Offset and Limit are not Working in GET API

Time:10-12

I have a spring application.

My Get api:

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;

 @GetMapping(path = {"/v1/Log"},
        produces = {"application/json"},
        consumes = {"application/json"})
public ResponseEntity<LogsResponse> getLog(final Pageable pageable) {
        final Page<Log> log = LogService.getActionLog(pageable);
        return ResponseEntity.ok(log.content);
}

My Repository class:

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface LogDBRepository extends MongoRepository<Log, String> {
    Page<Log> findAll(final Pageable pageable);
}

this is how I am testing offset and limit:

Issue I am facing is -> With /log?offset=1&limit=1 It is not returning the result by skipping or omitting the first page and also it should give only 1 result since my limit is 1 but it is returning all the rows/document present in the Mongo DB.

while same api is working If I use /log?page=1&size=1

My Expectation: how can I make it to return only 1 result and skip the first result?


@Test
public void givenPageRequest_whenGetLogCalled_returnSuccess() {

LogDBRespository.saveAll(Arrays.asList(Log.builder().id("id1").transactionId("tx1").status(LogStatus.PENDING).build(),
                Log.builder().id("id2").status(LogStatus.PENDING).transactionId("tx2").build()));

final HttpHeaders headers = new HttpHeaders();
        
headers.setContentType(MediaType.APPLICATION_JSON);

final HttpEntity httpEntity = new HttpEntity(headers);

ResponseEntity<LogsResponse> responseEntity = testRestTemplate.exchange("/log?offset=1&limit=1", HttpMethod.GET, httpEntity, LogsResponse.class);

Assertions.assertEquals(HttpStatus.OK.value(), responseEntity.getStatusCode().value());

}

CodePudding user response:

If you are trying to bind the values from the request parameter to pageable you have to use the same variables defined in pageable(or PageRequest to be more specific) which are page and size.

PageRequest parameter names

And that is why when you are using page and size it works.

But if you are passing those values in the request parameter with some other names you will have to do it something like this,

public ResponseEntity<LogsResponse> getLog(@RequestParam(defaultValue = "0") Integer offset, @RequestParam(defaultValue = "10") Integer limit) {
    Pageable pageable = PageRequest.of(offset, limit);
    
    final Page<Log> log = LogService.getActionLog(pageable);
    return ResponseEntity.ok(log.content);
}

CodePudding user response:

I'm not an expert on paging, but I think you have to create the Pageable object on your own consuming the request params if you don't use the default params "page" and "size". Currently, these params are not consumed by your controller method at all. So create your own Pageable object in the controller using the params:

@GetMapping(path = {"/v1/Log"},
    produces = {"application/json"},
    consumes = {"application/json"})
public ResponseEntity<LogsResponse> getLog(@RequestParam(value = "offset", required = false) Integer offset, @RequestParam(value = "limit", required = false) Integer limit) {
    //A check for null values in the request params would be a good idea here
    PageRequest pageRequest = new PageRequest(offset, limit, Direction.DESC);
    final Page<Log> log = LogService.getActionLog(pageRequest);
    return ResponseEntity.ok(log.content);
}

If you use @RequestParam without "value", Spring mvc expects the param name equal to the variable name, you can omit the "value" expression in this case. If you omit the "required" expression, it defaults to true which means that your request is failing if the param is missing.

A different approach would be to override the default parameter names for paging, see this tutorial.

  • Related