Skip to content

Commit

Permalink
Refactoring pagination feature in the API.
Browse files Browse the repository at this point in the history
  • Loading branch information
Mariana Azevedo committed Sep 20, 2020
1 parent 287fe14 commit 9ee9bbd
Show file tree
Hide file tree
Showing 17 changed files with 144 additions and 119 deletions.
2 changes: 1 addition & 1 deletion Procfile
Original file line number Diff line number Diff line change
@@ -1 +1 @@
web: java -jar -Dspring.profiles.active=prod -Dserver.port=$PORT target/financial-java-api-3.1.2-SNAPSHOT.jar
web: java -jar -Dspring.profiles.active=prod -Dserver.port=$PORT target/financial-java-api-3.1.3-SNAPSHOT.jar
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ This API provides HTTP endpoint's and tools for the following:
* Create a Transaction: `POST/financial/v1/transactions`
* Update a Transaction: `PUT/financial/v1/transactions`
* Delete a Transaction (by id): `DELETE/financial/v1/transactions/1`
* Get report of transactions in a period of time (sorted and paginated): `GET/financial/v1/transactions?startDate=2020-01-01&endDate=2020-09-18&order=DESC&page=2`
* Get report of transactions in a period of time (sorted and paginated): `GET/financial/v1/transactions?startDate=2020-01-01&endDate=2020-09-20&page=2&size=5&sort=DESC`
* Find a unique transaction by id: `GET/financial/v1/transactions/1`
* Find a unique transaction by id, but filtering JSON fields: `GET/financial/v1/transactions/1?fields=id,nsu,transactionDate,amount`
* Find transactions by NSU (Unique sequential number): `GET/financial/v1/transactions/byNsu/{nsuNumber}`
Expand Down Expand Up @@ -94,18 +94,18 @@ the one that was updated.
"type": "CARD",
"links": [
{
"rel": "self",
"rel": "self",
"href": "http://localhost:8080/financial/v1/transactions/1"
}
]
}
}
```

`GET/financial/v1/transactions?startDate=2020-01-01&endDate=2020-01-18&order=DESC&page=2`
`GET/financial/v1/transactions?startDate=2020-01-01&endDate=2020-01-18&page=2&size=5&sort=DESC`

This end-point returns transactions created within the period specified in the request. E.g: in the above query, we are looking for
all transactions carried out between 01-18 January 2020. Also, the result should return in descending order and only the page 2.
The end-point returns transactions were created within the period specified in the request. E.g., in the above query, we are looking for all transactions carried out between 01-18 January 2020. Also, the result should return in descending order and only page 2
with five transactions.

`DELETE/financial/v1/transaction/{id}`

Expand All @@ -131,7 +131,7 @@ This end-point returns the statistics based on the transactions created.
"count": 2,
"links": [
{
"rel": "self",
"rel": "self",
"href": "http://localhost:8080/financial/v1/statistics/1"
}
]
Expand Down Expand Up @@ -182,7 +182,7 @@ The API also was developed to run with an `jar`. In order to generate this `jar`
mvn package
```

It will clean, compile and generate a `jar` at target directory, e.g. `financial-java-api-3.1.2-SNAPSHOT.jar`
It will clean, compile and generate a `jar` at target directory, e.g. `financial-java-api-3.1.3-SNAPSHOT.jar`

### Execution

Expand Down Expand Up @@ -220,7 +220,7 @@ mvn integration-test
In order to run the API, run the jar simply as following:

```bash
java -jar financial-java-api-3.1.2-SNAPSHOT.jar --spring.profiles.active=dev
java -jar financial-java-api-3.1.3-SNAPSHOT.jar --spring.profiles.active=dev
```

or
Expand Down
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@

<groupId>io.github.mariazevedo88</groupId>
<artifactId>financial-java-api</artifactId>
<version>3.1.2-SNAPSHOT</version>
<version>3.1.3-SNAPSHOT</version>
<packaging>jar</packaging>

<name>financial-java-api</name>
<description>A financial API for managing transactions</description>
<description>A financial API for managing transactions. It is built with Java, Spring Boot, and Spring Framework.</description>

<developers>
<developer>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import java.math.BigDecimal;
import java.text.ParseException;
import java.time.LocalDateTime;
import java.time.LocalDate;

import org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
import org.junit.jupiter.api.Order;
Expand Down Expand Up @@ -59,8 +59,7 @@ public void testCreateTransactionNSU123456() throws ParseException {
//Create a new HttpEntity
final HttpEntity<TransactionDTO> entity = new HttpEntity<>(dtoNsu123456, headers);

ResponseEntity<String> responseEntity = this.restTemplate
.exchange("http://localhost:" + port + "/financial/v1/transactions",
ResponseEntity<String> responseEntity = this.restTemplate.exchange("http://localhost:" + port + "/financial/v1/transactions",
HttpMethod.POST, entity, String.class);

assertEquals(201, responseEntity.getStatusCodeValue());
Expand All @@ -80,8 +79,7 @@ public void testCreateTransactionNSU258963() throws ParseException {
//Create a new HttpEntity
final HttpEntity<TransactionDTO> entity = new HttpEntity<>(dtoNsu258963, headers);

ResponseEntity<String> responseEntity = this.restTemplate
.exchange("http://localhost:" + port + "/financial/v1/transactions",
ResponseEntity<String> responseEntity = this.restTemplate.exchange("http://localhost:" + port + "/financial/v1/transactions",
HttpMethod.POST, entity, String.class);

assertEquals(201, responseEntity.getStatusCodeValue());
Expand All @@ -97,16 +95,12 @@ public void testFindAllTransactions() throws ParseException {
//Create a new HttpEntity
final HttpEntity<String> entity = new HttpEntity<>(headers);

LocalDateTime startDateTime = FinancialApiUtil.
getLocalDateTimeFromString("2020-08-21T18:32:04.150Z");
LocalDateTime endDateTime = startDateTime.plusDays(5);

String startDate = startDateTime.format(FinancialApiUtil.getDateFormater());
String endDate = endDateTime.format(FinancialApiUtil.getDateFormater());
String startDate = LocalDate.of(2020, 8, 20).toString();
String endDate = LocalDate.of(2020, 8, 30).toString();

ResponseEntity<String> responseEntity = this.restTemplate
.exchange("http://localhost:" + port + "/financial/v1/transactions?startDate=" + startDate + "&endDate=" + endDate,
HttpMethod.GET, entity, String.class);
.exchange("http://localhost:" + port + "/financial/v1/transactions?startDate=" + startDate + "&endDate=" + endDate
+ "&page=" + 1 + "&size=" + 2 + "&order=ASC", HttpMethod.GET, entity, String.class);

assertEquals(200, responseEntity.getStatusCodeValue());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.server.mvc.WebMvcLinkBuilder;
Expand All @@ -37,7 +39,6 @@
import io.github.mariazevedo88.financialjavaapi.exception.NotParsableContentException;
import io.github.mariazevedo88.financialjavaapi.exception.TransactionInvalidUpdateException;
import io.github.mariazevedo88.financialjavaapi.exception.TransactionNotFoundException;
import io.github.mariazevedo88.financialjavaapi.model.enumeration.PageOrderEnum;
import io.github.mariazevedo88.financialjavaapi.model.transaction.Transaction;
import io.github.mariazevedo88.financialjavaapi.service.transaction.TransactionService;
import io.github.mariazevedo88.financialjavaapi.util.FinancialApiUtil;
Expand All @@ -55,7 +56,7 @@
@RequestMapping("/financial/v1/transactions")
public class TransactionController {

private TransactionService transactionService;
TransactionService transactionService;

@Autowired
public TransactionController(TransactionService transactionService) {
Expand Down Expand Up @@ -93,9 +94,9 @@ public TransactionController(TransactionService transactionService) {
*/
@PostMapping
@ApiOperation(value = "Route to create a transaction")
public ResponseEntity<Response<TransactionDTO>> create(@RequestHeader(value=FinancialApiUtil.HEADER_FINANCIAL_API_VERSION, defaultValue="${api.version}")
String apiVersion, @RequestHeader(value=FinancialApiUtil.HEADER_API_KEY, defaultValue="${api.key}") String apiKey,
@Valid @RequestBody TransactionDTO dto, BindingResult result) throws NotParsableContentException {
public ResponseEntity<Response<TransactionDTO>> create(@RequestHeader(value=FinancialApiUtil.HEADER_FINANCIAL_API_VERSION, defaultValue="${api.version}") String apiVersion,
@RequestHeader(value=FinancialApiUtil.HEADER_API_KEY, defaultValue="${api.key}") String apiKey, @Valid @RequestBody TransactionDTO dto, BindingResult result)
throws NotParsableContentException {

Response<TransactionDTO> response = new Response<>();

Expand Down Expand Up @@ -155,9 +156,9 @@ public ResponseEntity<Response<TransactionDTO>> create(@RequestHeader(value=Fina
*/
@PutMapping(path = "/{id}")
@ApiOperation(value = "Route to update a transaction")
public ResponseEntity<Response<TransactionDTO>> update(@RequestHeader(value=FinancialApiUtil.HEADER_FINANCIAL_API_VERSION, defaultValue="${api.version}")
String apiVersion, @RequestHeader(value=FinancialApiUtil.HEADER_API_KEY, defaultValue="${api.key}") String apiKey, @Valid @RequestBody TransactionDTO dto,
BindingResult result) throws TransactionNotFoundException, TransactionInvalidUpdateException, NotParsableContentException {
public ResponseEntity<Response<TransactionDTO>> update(@RequestHeader(value=FinancialApiUtil.HEADER_FINANCIAL_API_VERSION, defaultValue="${api.version}") String apiVersion,
@RequestHeader(value=FinancialApiUtil.HEADER_API_KEY, defaultValue="${api.key}") String apiKey, @Valid @RequestBody TransactionDTO dto, BindingResult result)
throws TransactionNotFoundException, TransactionInvalidUpdateException, NotParsableContentException {

Response<TransactionDTO> response = new Response<>();

Expand Down Expand Up @@ -199,8 +200,9 @@ public ResponseEntity<Response<TransactionDTO>> update(@RequestHeader(value=Fina
* @param apiKey - API Key to access the routes
* @param startDate - the start date of the search
* @param endDate - the end date of the search
* @param page - the page that will be return in the search
* @param order - the sort order that the results should be shown: ASC - ascending order; DESC - descending order
* @param pageable Object for pagination information: the page that will be return in the search,
* the size of page, and sort direction that the results should be shown: ASC - ascending order;
* DESC - descending order.
*
* @return ResponseEntity with a <code>Response<Page<TransactionDTO>></code> object and the HTTP status
*
Expand All @@ -217,16 +219,15 @@ public ResponseEntity<Response<TransactionDTO>> update(@RequestHeader(value=Fina
@ApiOperation(value = "Route to find all transactions of the API in a period of time")
public ResponseEntity<Response<Page<TransactionDTO>>> findAllBetweenDates(@RequestHeader(value=FinancialApiUtil.HEADER_FINANCIAL_API_VERSION, defaultValue="${api.version}")
String apiVersion, @RequestHeader(value=FinancialApiUtil.HEADER_API_KEY, defaultValue="${api.key}") String apiKey, @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd")
LocalDate startDate, @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endDate, @RequestParam(name="page", defaultValue = "0") int page,
@RequestParam(name="order", defaultValue = "ASC") String order) throws TransactionNotFoundException {
LocalDate startDate, @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endDate, @PageableDefault(page = 1, size = 10, sort = {"id"}) Pageable pageable)
throws TransactionNotFoundException {

Response<Page<TransactionDTO>> response = new Response<>();

LocalDateTime startDateTime = FinancialApiUtil.convertLocalDateToLocalDateTime(startDate);
LocalDateTime endDateTime = FinancialApiUtil.convertLocalDateToLocalDateTime(endDate);

Page<Transaction> transactions = transactionService.findBetweenDates(startDateTime, endDateTime,
page, PageOrderEnum.getSortDirection(order));
Page<Transaction> transactions = transactionService.findBetweenDates(startDateTime, endDateTime, pageable);

if (transactions.isEmpty()) {
throw new TransactionNotFoundException("There are no transactions registered between startDate=" + startDate
Expand All @@ -236,7 +237,7 @@ public ResponseEntity<Response<Page<TransactionDTO>>> findAllBetweenDates(@Reque
Page<TransactionDTO> itemsDTO = transactions.map(t -> t.convertEntityToDTO());
itemsDTO.stream().forEach(dto -> {
try {
createSelfLinkInCollections(apiVersion, apiKey, dto, null);
createSelfLinkInCollections(apiVersion, apiKey, dto);
} catch (TransactionNotFoundException e) {
log.error("There are no transactions registered between startDate= {} and endDate= {}", startDate, endDate);
}
Expand Down Expand Up @@ -292,7 +293,7 @@ public ResponseEntity<Response<List<TransactionDTO>>> findByNsu(@RequestHeader(v

transactionsDTO.stream().forEach(dto -> {
try {
createSelfLinkInCollections(apiVersion, apiKey, dto, null);
createSelfLinkInCollections(apiVersion, apiKey, dto);
} catch (TransactionNotFoundException e) {
log.error("There are no transactions registered with the nsu= {}", transactionNSU);
}
Expand Down Expand Up @@ -420,10 +421,10 @@ private void createSelfLink(Transaction transaction, TransactionDTO transactionD
* @param transactionDTO
* @throws TransactionNotFoundException
*/
private void createSelfLinkInCollections(String apiVersion, String apiKey, final TransactionDTO transactionDTO, String fields)
private void createSelfLinkInCollections(String apiVersion, String apiKey, final TransactionDTO transactionDTO)
throws TransactionNotFoundException {
Link selfLink = linkTo(methodOn(TransactionController.class).findById(apiVersion, apiKey,
transactionDTO.getId(), fields)).withSelfRel();
Link selfLink = linkTo(methodOn(TransactionController.class).findById(apiVersion, apiKey, transactionDTO.getId(), null))
.withSelfRel().expand();
transactionDTO.add(selfLink);
}

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
import java.util.List;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import io.github.mariazevedo88.financialjavaapi.dto.model.transaction.TransactionDTO;
import io.github.mariazevedo88.financialjavaapi.exception.TransactionNotFoundException;
import io.github.mariazevedo88.financialjavaapi.model.enumeration.PageOrderEnum;
import io.github.mariazevedo88.financialjavaapi.model.transaction.Transaction;

/**
Expand Down Expand Up @@ -79,14 +79,13 @@ public interface TransactionService {
*
* @param startDate - the start date of the search
* @param endDate - the end date of the search
* @param page - the page that will be return in the search
* @param order - the sort order that the results should be shown:
* ASC - ascending order; DESC - descending order
* @param pageable - object for pagination information: the page that will be return in the search,
* the size of page, and sort direction that the results should be shown: ASC - ascending order;
* DESC - descending order.
*
* @return <code>Page<Transaction></code> object
*/
Page<Transaction> findBetweenDates(LocalDateTime startDate, LocalDateTime endDate, int page,
PageOrderEnum order);
Page<Transaction> findBetweenDates(LocalDateTime startDate, LocalDateTime endDate, Pageable pageable);

/**
* Method to build a partial response in requests regarding Transaction.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,9 @@
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import com.fasterxml.jackson.databind.ObjectMapper;
Expand All @@ -18,7 +15,6 @@

import io.github.mariazevedo88.financialjavaapi.dto.model.transaction.TransactionDTO;
import io.github.mariazevedo88.financialjavaapi.exception.TransactionNotFoundException;
import io.github.mariazevedo88.financialjavaapi.model.enumeration.PageOrderEnum;
import io.github.mariazevedo88.financialjavaapi.model.transaction.Transaction;
import io.github.mariazevedo88.financialjavaapi.repository.transaction.TransactionRepository;
import io.github.mariazevedo88.financialjavaapi.service.transaction.TransactionService;
Expand All @@ -34,9 +30,6 @@ public class TransactionServiceImpl implements TransactionService {

TransactionRepository transactionRepository;

@Value("${pagination.items_per_page}")
private int itemsPerPage;

@Autowired
public TransactionServiceImpl(TransactionRepository transactionRepository) {
this.transactionRepository = transactionRepository;
Expand Down Expand Up @@ -79,17 +72,13 @@ public Transaction findById(Long id) throws TransactionNotFoundException {
}

/**
* @see TransactionService#findBetweenDates()
* @see TransactionService#findBetweenDates(LocalDateTime, LocalDateTime, Pageable)
*/
@Override
public Page<Transaction> findBetweenDates(LocalDateTime startDate, LocalDateTime endDate, int page,
PageOrderEnum order) {
Sort sort = Direction.ASC.name().equals(order.getValue()) ?
Sort.by("id").ascending() : Sort.by("id").descending();
PageRequest pg = PageRequest.of(page, itemsPerPage, sort);
public Page<Transaction> findBetweenDates(LocalDateTime startDate, LocalDateTime endDate, Pageable pageable) {
return transactionRepository.
findAllByTransactionDateGreaterThanEqualAndTransactionDateLessThanEqual(startDate,
endDate, pg);
endDate, pageable);
}

/**
Expand Down
Loading

0 comments on commit 9ee9bbd

Please sign in to comment.