Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
TRILHA JAVA EE
CONSTRUINDO APIS DE FORMA PRODUTIVA COM
SPRING BOOT, SPRING DATA E SPRING MVC
Emmanuel Neri
PROBLEMA
Quais os obstáculos da construção de APIs?
Ambiente Objeto <—> JSON Acessos aos dados
AGENDA
Spring Boot
Spring MVC Spring Data
SPRING BOOT
GERENCIAMENTO
DE DEPENDÊNCIAS
EMBEDDED
SERVLET
CONTAINERS
AUTO
CONFIGURAÇÃO
GERENCIAMENTO DE DEPENDÊNCIAS
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</ar...
GERENCIAMENTO DE DEPENDÊNCIAS
AUTO CONFIGURAÇÃO
@SpringBootApplication
public class AppConfig {
public static void main(String[] args) {
SpringApplicati...
AUTO CONFIGURAÇÃO
mvn spring-boot:run -Ddebug
=========================
AUTO-CONFIGURATION REPORT
========================...
AUTO CONFIGURAÇÃO
/src/main/resources/application.properties
spring.profiles.active=dev
server.port=8090
server.context-pa...
AUTO CONFIGURAÇÃO
spring.profiles.active=
spring.mail.host=
spring.sendgrid.api-key=
flyway.enabled=true # Enable flyway
liqu...
EMBEDDED SERVLET CONTAINERS
mvn spring-boot:run
s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s)...
SPRING MVC
SIMPLICIDADE NA
EXPOSIÇÃO DE APIS
ABSTRAÇÃO NA
SERIALIZAÇÃO /
DESERIALIZAÇÃO
FACILIDADE NA
LEITURA DE
PARÂMETRO...
SIMPLICIDADE NA EXPOSIÇÃO DE APIS
@RestController
@RequestMapping("/customers")
public class CustomerController {
@Request...
ABSTRAÇÃO NA SERIALIZAÇÃO / DESERIALIZAÇÃO
@RequestMapping(method = RequestMethod.GET)
public List<Customer> findAll() {
r...
ABSTRAÇÃO NA SERIALIZAÇÃO / DESERIALIZAÇÃO
import com.fasterxml.jackson.annotation.JsonFormat;
public final class BillDTO ...
FACILIDADE NA LEITURA DE PARÂMETROS
@RequestMapping(value = "/byUk/{customerId}/{identifier}/{yearMonth}",
method = Reques...
CONSTRUÇÃO SIMPLES ESTRUTURA DE RETORNO
ResponseEntity.ok(bill);
ResponseEntity.badRequest().build();
@RequestMapping(meth...
TRATAMENTO DE ERROS
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ConstraintViolationException...
SPRING DATA
IMPLEMENTAÇÕES
PADRÕES
ABSTRAÇÃO NO
ACESSO AOS
DADOS
SUPORTE A
DIFERENTE FONTES
DE DADOS
CACHE
IMPLEMENTAÇÕES PADRÕES
public interface BillRepository extends JpaRepository<Bill, Long> {
‣ findAll()
‣ save(T object)
‣ s...
ABSTRAÇÃO NO ACESSO AOS DADOS
public Customer save(Customer customer) {
return customerRepository.save(customer);
}
public...
ABSTRAÇÃO NO ACESSO AOS DADOS
Bill findByCustomerIdAndIdentifierAndYearMonth(Long customerId,
String identifier, YearMonth...
ABSTRAÇÃO NO ACESSO AOS DADOS
‣ Integração com QueryDSL
public interface BillRepository extends JpaRepository<Bill, Long>,...
ACESSO AOS DADOS
‣ Repositorios customizados
public interface BillRepositoryCustom {
Page<BillDTO> findAll(BillSearchTO se...
ACESSO AOS DADOS
‣ Repositorios customizados
public interface BillRepository extends JpaRepository<Bill, Long>,
QueryDslPr...
SUPORTE A DIFERENTE FONTES DE DADOS
‣ Módulos Spring
‣ Módulos da comunidade
JPA LDAP
REST
SUPORTE A DIFERENTE FONTES DE DADOS
public interface BillFileRepository extends MongoRepository<BillFile, String> {
}
impo...
CACHE
‣ JSR-107
‣ Caffeine
‣ Guava cache
‣ EhCache
‣ GemFire
@SpringBootApplication
@EnableCaching
public class AppConfig ...
https://github.com/emmanuelneri/productivity-with-spring
OBRIGADO!
emmanuelnerisouza@gmail.com
https://github.com/emmanuel...
Upcoming SlideShare
Loading in …5
×

TDC2017 | São Paulo - Trilha Java EE How we figured out we had a SRE team at - Construindo APIs de forma produtiva com Spring Boot, Spring Data e Spring MVC

64 views

Published on

Trilha Java EE How we figured out we had a SRE team at -

Published in: Education
  • Be the first to comment

  • Be the first to like this

TDC2017 | São Paulo - Trilha Java EE How we figured out we had a SRE team at - Construindo APIs de forma produtiva com Spring Boot, Spring Data e Spring MVC

  1. 1. TRILHA JAVA EE CONSTRUINDO APIS DE FORMA PRODUTIVA COM SPRING BOOT, SPRING DATA E SPRING MVC Emmanuel Neri
  2. 2. PROBLEMA Quais os obstáculos da construção de APIs? Ambiente Objeto <—> JSON Acessos aos dados
  3. 3. AGENDA Spring Boot Spring MVC Spring Data
  4. 4. SPRING BOOT GERENCIAMENTO DE DEPENDÊNCIAS EMBEDDED SERVLET CONTAINERS AUTO CONFIGURAÇÃO
  5. 5. GERENCIAMENTO DE DEPENDÊNCIAS <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <version>1.5.3.RELEASE</version> </dependency> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>1.5.3.RELEASE</version> </plugin> </plugins> </build>
  6. 6. GERENCIAMENTO DE DEPENDÊNCIAS
  7. 7. AUTO CONFIGURAÇÃO @SpringBootApplication public class AppConfig { public static void main(String[] args) { SpringApplication.run(AppConfig.class, args); } } @EnableAutoConfiguration @AutoConfigureTestDatabase @AutoConfigureMockMvc
  8. 8. AUTO CONFIGURAÇÃO mvn spring-boot:run -Ddebug ========================= AUTO-CONFIGURATION REPORT ========================= Positive matches: ----------------- EmbeddedServletContainerAutoConfiguration matched: ... DataSourceConfiguration.Tomcat matched: ... Negative matches: ----------------- ActiveMQAutoConfiguration: Did not match: RedisAutoConfiguration: Did not match:
  9. 9. AUTO CONFIGURAÇÃO /src/main/resources/application.properties spring.profiles.active=dev server.port=8090 server.context-path=/api spring.http.encoding.charset=UTF-8 spring.datasource.url=jdbc:postgresql://localhost:5432/db spring.datasource.username=postgres spring.datasource.password=postgres spring.datasource.driver-class-name=org.postgresql.Driver spring.jpa.show-sql=true
  10. 10. AUTO CONFIGURAÇÃO spring.profiles.active= spring.mail.host= spring.sendgrid.api-key= flyway.enabled=true # Enable flyway liquibase.enabled=true spring.data.cassandra.cluster-name= spring.data.elasticsearch.cluster-name= spring.data.mongodb.database=test spring.data.redis.repositories.enabled=true spring.activemq.broker-url= …. https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
  11. 11. EMBEDDED SERVLET CONTAINERS mvn spring-boot:run s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http) <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
  12. 12. SPRING MVC SIMPLICIDADE NA EXPOSIÇÃO DE APIS ABSTRAÇÃO NA SERIALIZAÇÃO / DESERIALIZAÇÃO FACILIDADE NA LEITURA DE PARÂMETROS TRATAMENTO DE ERROS CONSTRUÇÃO SIMPLES ESTRUTURA DE RETORNO
  13. 13. 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
  14. 14. 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); }
  15. 15. ABSTRAÇÃO NA SERIALIZAÇÃO / DESERIALIZAÇÃO import com.fasterxml.jackson.annotation.JsonFormat; public final class BillDTO { @JsonFormat(pattern = "yyyy-MM") private YearMonth yearMonth;
  16. 16. 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)); }
  17. 17. CONSTRUÇÃO SIMPLES ESTRUTURA DE RETORNO ResponseEntity.ok(bill); ResponseEntity.badRequest().build(); @RequestMapping(method = RequestMethod.GET) public ResponseEntity ok() { return ResponseEntity.ok().build(); } 200 400 200 {      "id":1,    "customer":{         "name":"Customer"    },    "carrier":{         "name":"TIM"    },    "identifier":"23326",    “yearMonth”:"2017/06"  } ResponseEntity.status(UNAUTHORIZED).build(); 401
  18. 18. TRATAMENTO DE ERROS @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(ConstraintViolationException.class) public ResponseEntity<Set<ExceptionTO>> handleError(ConstraintViolationException ex) { final Set<ExceptionTO> erros = ex.getConstraintViolations().stream() .map(c -> new ExceptionTO(c.getMessage())) .collect(Collectors.toSet()); return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(erros); } @ExceptionHandler(Exception.class) public ResponseEntity handleError(Exception ex) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) .body("O sistema se encontra indisponível”); }
  19. 19. SPRING DATA IMPLEMENTAÇÕES PADRÕES ABSTRAÇÃO NO ACESSO AOS DADOS SUPORTE A DIFERENTE FONTES DE DADOS CACHE
  20. 20. IMPLEMENTAÇÕES PADRÕES public interface BillRepository extends JpaRepository<Bill, Long> { ‣ findAll() ‣ save(T object) ‣ save(Iterable<T> objects) ‣ flush() ‣ getOne(ID id) ‣ delete(ID id) ‣ deleteInBatch(Iterable<T> objects)
  21. 21. 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)); }
  22. 22. ABSTRAÇÃO NO ACESSO AOS DADOS Bill findByCustomerIdAndIdentifierAndYearMonth(Long customerId, String identifier, YearMonth yearMonth); Hibernate: select bill… from bill bill0_ where bill0_.customer_id=? and bill0_.identifier=? and bill0_.year_month=? @Modifying @Query("delete from BillItem where bill.id = :#{#billId}") void deleteByBillItem(@Param("billId") Long billId); Hibernate: delete from bill where id=?
  23. 23. 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)); }
  24. 24. ACESSO AOS DADOS ‣ Repositorios customizados public interface BillRepositoryCustom { Page<BillDTO> findAll(BillSearchTO searchTO); } 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(); ...
  25. 25. ACESSO AOS DADOS ‣ Repositorios customizados public interface BillRepository extends JpaRepository<Bill, Long>, QueryDslPredicateExecutor<Bill>, BillRepositoryCustom { ...
  26. 26. SUPORTE A DIFERENTE FONTES DE DADOS ‣ Módulos Spring ‣ Módulos da comunidade JPA LDAP REST
  27. 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
  28. 28. CACHE ‣ JSR-107 ‣ Caffeine ‣ Guava cache ‣ EhCache ‣ GemFire @SpringBootApplication @EnableCaching public class AppConfig { @Cacheable("carriers") public List<Carrier> findAll() { return carrierRepository.findAll(); }
  29. 29. https://github.com/emmanuelneri/productivity-with-spring OBRIGADO! emmanuelnerisouza@gmail.com https://github.com/emmanuelneri @emmanuelnerii www.emmanuelneri.com.br

×