Uma visão geral de como construir APIs de forma produtiva utilizando os frameworks Spring Boot, Spring Data e Spring MVC integrados.
Apresentação TDC São Paulo 2017, trilha de Java EE
13. SPRING MVC
Spring MVC
FACILIDADE NA
LEITURA DE
PARÂMETROS
ABSTRAÇÃO NA
SERIALIZAÇÃO /
DESERIALIZAÇÃO
SIMPLICIDADE NA
EXPOSIÇÃO DE APIS
CONSTRUÇÃO
SIMPLES
ESTRUTURA DE
RETORNO
TRATAMENTO DE
ERROS
14. SIMPLICIDADE NA EXPOSIÇÃO DE APIS
@RestController
@RequestMapping("/customers")
public class CustomerController {
@RequestMapping(method = RequestMethod.GET)
public List<Customer> findAll() {
return customerService.findAll();
}
}
http://localhost:8080/customers
15. ABSTRAÇÃO NA SERIALIZAÇÃO / DESERIALIZAÇÃO
@RequestMapping(method = RequestMethod.GET)
public List<Customer> findAll() {
return customerService.findAll();
}
@RequestMapping(method = RequestMethod.POST)
public void save(@RequestBody BillDTO billDTO) {
billService.save(billDTO);
}
16. ABSTRAÇÃO NA SERIALIZAÇÃO / DESERIALIZAÇÃO
import com.fasterxml.jackson.annotation.JsonFormat;
public final class BillDTO {
@JsonFormat(pattern = "yyyy-MM")
private YearMonth yearMonth;
17. FACILIDADE NA LEITURA DE PARÂMETROS
@RequestMapping(value = "/byUk/{customerId}/{identifier}/{yearMonth}",
method = RequestMethod.GET)
public Bill findByUk(@PathVariable("customerId") Long customerId,
@PathVariable("identifier") String identifier,
@PathVariable("yearMonth") YearMonth yearMonth) {
return billService.findByUk(customerId, identifier, yearMonth);
}
@RequestMapping(value = "/search", method = RequestMethod.GET)
public List<Customer> search(
@RequestParam(value = "id", required = false) Long id,
@RequestParam(value = "name", required = false) String name){
return customerService.search(new CustomerSearchTO(id, name));
}
22. ABSTRAÇÃO NO ACESSO AOS DADOS
public Customer save(Customer customer) {
return customerRepository.save(customer);
}
public List<Customer> findAll() {
return customerRepository.findAll();
}
public Page<Customer> findPaginable(int page, int size) {
final Sort sort = new Sort(Sort.Direction.DESC, "name");
return customerRepository.findAll(
new PageRequest(page, size, sort));
}
23. ABSTRAÇÃO NO ACESSO AOS DADOS
Bill findByCustomerIdAndIdentifierAndYearMonth(Long customerId,
String identifier, YearMonth yearMonth);
@Modifying
@Query("delete from BillItem where bill.id = :#{#billId}")
void deleteByBillItem(@Param("billId") Long billId);
Hibernate: select bill… from bill bill0_ where bill0_.customer_id=? and
bill0_.identifier=? and bill0_.year_month=?
Hibernate: delete from bill where id=?
24. ABSTRAÇÃO NO ACESSO AOS DADOS
‣ Integração com QueryDSL
public interface BillRepository extends JpaRepository<Bill, Long>,
QueryDslPredicateExecutor<Bill> {
public Page<Bill> search(BillSearchTO searchTO) {
return billRepository.findAll(searchTO.toPredicate(),
new PageRequest(searchTO.getPage(), searchTO.getSize(),
new Sort(Sort.Direction.DESC, "id")));
}
public class BillSearchTO {
public BooleanBuilder toPredicate() {
final QBill qBill = QBill.bill;
final BooleanBuilder predicate = new BooleanBuilder();
if(!Strings.isNullOrEmpty(identifier)) {
predicate.and(qBill.identifier.eq(identifier));
}
if(initYearMonth != null) {
predicate.and(qBill.yearMonth.goe(initYearMonth));
}
25. ACESSO AOS DADOS
‣ Repositorios customizados
public interface BillRepositoryCustom {
Page<BillDTO> findAll(BillSearchTO searchTO);
}
public interface BillRepository extends JpaRepository<Bill, Long>,
QueryDslPredicateExecutor<Bill>, BillRepositoryCustom {
...
public class BillRepositoryImpl implements BillRepositoryCustom {
@PersistenceContext
private EntityManager entityManager;
@Override
public Page<BillDTO> findAll(BillSearchTO searchTO) {
final JPQLQuery jpaQuery = new JPAQuery(entityManager)
.from(qBill)
.join(qBill.carrier).fetchJoin()
.join(qBill.customer).fetchJoin()
.join(qBill.items).fetchJoin();
...
26. SUPORTE A DIFERENTE FONTES DE DADOS
‣ Módulos da Spring
‣ Módulos da comunidade
JPA LDAP
REST
27. SUPORTE A DIFERENTE FONTES DE DADOS
public interface BillFileRepository extends MongoRepository<BillFile, String> {
}
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
@Document(collection = "bill_file")
@Getter
public class BillFile {
@Id
private String id;
private String date;
private String content