본문 바로가기
개발서적

스프링 인 액션 - (3)

by 공부 안하고 싶은 사람 2022. 8. 10.
반응형

part 2. 통합된 스프링

chapter 6 REST 서비스 생성하기

GET : 읽기

  • POST : 쓰기
  • PUT : 전체 변경
  • PATCH : 일부 변경
  • DELETE : 삭제

@RestController ( @Controller + @ResponseBody )

반환 값이 뷰를 통해 HTML로 변환되지 않고, 직접 HTTP 응답으로 브라우저에 전달

@CroosOrigin(origins="*")

CORS를 해결할 수있다.

@PathVariable

특정 도메인만 가져오는 엔드포인트를 만들고 싶을때 사용

@ResponseStatus(HttpStatus.CREATED)

성공시 인자의 HTTP 응답값을 전달한다

 

 

HATEOAS

클라이언트가 URL을 하드코딩하지 않도록

json 응답에 URL을 포함한다(자신과 전이가능한 URL)

<dependency>
  <groupId>org.sptringframework.boot</groupId>
<artifactiId>spring-boot-starter-hateoas</artifactiId>
</dependency>
public Class DesignTacoController {
  @GetMapping("/recent")
  public Resources<Resource<Taco>> recentTacos() {
    ...
    Resources<Resource<Taco>> recentResource = Resources.wrap(tacos);
 recentResource.add( // URL 생략하여 만들 수 있음
  linkTo(methodOn(DesignTacoController.class).recentTacos())
   .withRel("recents"); // Link의 관계 이름
 )
  }
}
​

리소스 어셈블러를 이용한 List에 Link를 추가하는 방법은 생략(사용하게 된다면 그때 디테일 하게 알아보자)

spring-data, spring-data-rest를 통해서 Entity를 REST하게 반환할 수 있다.(단, Entity와 DTO는 구분해서 사용해야한다.)


 

 

chapter 7 서비스 사용하기

JDBC -> JBDCTemplate 사용처럼 HTTP -> RestTemplate 사용한다. (열고,닫고,예외처리 등 해결)

여러 Client가 있을 수 있으니 빈으로 등록하여 사용

@Bean
public RestTemplate client1Template() {
return new RestTemplate();
}
ResponseEntity<Taco> entity = restTemplate.exchange( // 가장 저수준의 api
url, // url
HttpMethod.POST, // HTTP method
new HttpEntity<>(
 request, // body
 header // 헤더 HttpHeaders
),
Taco.class // 응답 모델
);

Travewrson은 HATEOAS와 짝꿍이므로 생략


 

 

chapter 8 비동기 메시지 전송하기

비동기는 어플리케이션 간의 결합도를 낮추고 확장성을 높힌다

예시) JMS, RabbitMQ, AMQP, Kafka

JMS, RabbitMQ, AMQP (생략)

Apache Kafka

다른 큐와는 다르게 클러스터링 된다.

토픽은 클러스터의 모든 브로커에 복제

클러스터의 각 노드는 하나 이상의 토픽에 대한 리더로 동작 -> 다른 클러스터에 복제

설정

<dependency>
  <groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
</dependency>

KafkaTemplate으로 메시지를 전송, 수신할 수 있다.

spirng.kafka:
  bootstrap-servers:
  - xxxx:9092 # 복수
  - xxxx:9093 
// 토픽과 메시지
ProducerRecord<String, Object> record = new ProducerRecord<>(topic, message);
ListenableFuture<SendResult<String, Object>> future = kafkaTemplate.send(record);
​
future.addCallback(new ListenableFutureCallback<SendResult<String, Object>>() {
@Override
public void onSuccess(SendResult<String, Object> result) {
 log.info("Sent! ==> [{}], [{}]", result.getRecordMetadata(), message);
}
​
@Override
public void onFailure(Throwable e) {
 log.error("Unable to send due to : {}, [{}]", e.getMessage(), message);
}
});
// 어느 토픽의 어느 그룹으로 컨슘할지
@KafkaListener(topics = "토픽명", containerFactory = "팩토리명")
public void handle(ConsumerRecord<Order> record) {
// ..objectMapper로 convert하여 사용
}

 

chapter 9 스프링 통합하기

생략

 

728x90
반응형

댓글