TIL 2023/11/10 Spring RestTemplate & Open API

YEONGDO·2023년 11월 13일

1. RestTemplate

1) Server To Server

  • 지금까지는 Client 즉, 브라우저로부터 요청을 받는 서버의 입장에서 개발을 진행했다.
  • 서비스 개발을 진행하다보면 라이브러리 사용만으로는 구현이 힘든 기능들이 무수히 많이 존재한다.
  • 예를 들어 우리의 서비스에서 회원가입을 진행할 때 사용자의 주소를 받아야 한다면?
    • 주소를 검색할 수 있는 기능을 구현해야하는데 직접 구현을 하게되면 많은 시간과 비용이 들어가게 된다.
  • 이 때, 카카오에서 만든 주소 검색 API를 사용한다면 해당 기능을 간편하게 구현할 수 있다.

  • 이럴 때 우리의 서버는 Client의 입장이 되어 Kakao 서버에 요청을 진행해야한다.
  • Spring에서는 서버에서 다른 서버로 간편하게 요청할 수 있도록 RestTemplate 기능을 제공하고 있다.

2) RestTemplate 사용방법

프로젝트 2개를 만들어서 Client 입장의 서버는 8080 port, Server 입장의 서버는 7070 port로 동시에 실행

2. RestTemplate의 Get 요청

RestTemplate을 주입 받는다.

private final RestTemplate restTemplate;

// RestTemplateBuilder의 build()를 사용하여 RestTemplate을 생성합니다.
public RestTemplateService(RestTemplateBuilder builder) {
    this.restTemplate = builder.build();
}

요청 받은 검색어를 Query String 방식으로 Server 입장의 서버로 RestTemplate를 사용하여 요청

public ItemDto getCallObject(String query) {
    // 요청 URL 만들기
    URI uri = UriComponentsBuilder
            .fromUriString("http://localhost:7070")
            .path("/api/server/get-call-obj")
            .queryParam("query", query)
            .encode()
            .build()
            .toUri();
    log.info("uri = " + uri);

    ResponseEntity<ItemDto> responseEntity = restTemplate.getForEntity(uri, ItemDto.class);

    log.info("statusCode = " + responseEntity.getStatusCode());

    return responseEntity.getBody();
}
  • Spring의 UriComponentsBuilder를 사용해서 URI를 손쉽게 만들 수 있다.
  • RestTemplate의 getForEntity는 Get 방식으로 해당 URI의 서버에 요청을 진행한다.
    • 첫 번째 파라미터에는 URI, 두 번째 파라미터에는 전달 받은 데이터와 매핑하여 인스턴스화할 클래스의 타입을 주면 된다.
  • 요청의 결과값에 대해서 직접 JSON TO Object를 구현할 필요없이 RestTemplate을 사용하면 자동으로 처리
    • 따라서 response.getBody() 를 사용하여 두 번째 파라미터로 전달한 클래스 타입으로 자동 변환된 객체를 가져올 수 있다.

3. RestTemplate의 Post 요청

요청 받은 검색어를 Query String 방식으로 Server 입장의 서버로 RestTemplate를 사용하여 요청

public ItemDto postCall(String query) {
    // 요청 URL 만들기
    URI uri = UriComponentsBuilder
            .fromUriString("http://localhost:7070")
            .path("/api/server/post-call/{query}")
            .encode()
            .build()
            .expand(query)
            .toUri();
    log.info("uri = " + uri);

    User user = new User("Robbie", "1234");

    ResponseEntity<ItemDto> responseEntity = restTemplate.postForEntity(uri, user, ItemDto.class);

    log.info("statusCode = " + responseEntity.getStatusCode());

    return responseEntity.getBody();
}
  • UriComponentsBuilder의 expand를 사용하여 {query} 안의 값을 동적으로 처리할 수 있다.
  • RestTemplate의 postForEntity는 Post 방식으로 해당 URI의 서버에 요청을 진행
  • 첫 번째 파라미터에는 URI, 두 번째 파라미터에는 HTTP Body에 넣어줄 데이터를 넣는다.
  • Java 객체를 두 번째 파라미터에 넣으면 자동으로 JSON 형태로 변환된다.
  • 세 번째 파라미터에는 전달 받은 데이터와 매핑하여 인스턴스화할 클래스의 타입을 주면 된다.

4. RestTemplate의 exchange

1) 요청 Header에 정보를 추가하고 싶다면?

  • RestTemplate으로 요청을 보낼 때 Header에 특정 정보를 같이 전달 하고 싶다면?

  • Client 입장 서버
    RestTemplate의 exchange를 사용

      ```java
      public List<ItemDto> exchangeCall(String token) {
          // 요청 URL 만들기
          URI uri = UriComponentsBuilder
                  .fromUriString("http://localhost:7070")
                  .path("/api/server/exchange-call")
                  .encode()
                  .build()
                  .toUri();
          log.info("uri = " + uri);
      
          User user = new User("Robbie", "1234");
      
          RequestEntity<User> requestEntity = RequestEntity
                  .post(uri)
                  .header("X-Authorization", token)
                  .body(user);
      
          ResponseEntity<String> responseEntity = restTemplate.exchange(requestEntity, String.class);
      
          return fromJSONtoItems(responseEntity.getBody());
      }
      ```
      
      - [코드 스니펫] RestTemplateService - exchangeCall
          
          ```java
          public List<ItemDto> exchangeCall(String token) {
              // 요청 URL 만들기
              URI uri = UriComponentsBuilder
                      .fromUriString("http://localhost:7070")
                      .path("/api/server/exchange-call")
                      .encode()
                      .build()
                      .toUri();
              log.info("uri = " + uri);
          
              User user = new User("Robbie", "1234");
          
              RequestEntity<User> requestEntity = RequestEntity
                      .post(uri)
                      .header("X-Authorization", token)
                      .body(user);
          
              ResponseEntity<String> responseEntity = restTemplate.exchange(requestEntity, String.class);
          
              return fromJSONtoItems(responseEntity.getBody());
          }
          ```
          
  • exchange 메서드의 첫 번째 파라미터에 RequestEntity 객체를 만들어 전달해주면 uri, header, body의 정보를 한번에 전달할 수 있다.

5. Naver Open API

네이버 서비스를 코드로 이용할 수 있는 서비스

  • API 목록 살펴보기
https://developers.naver.com/products/intro/plan/
profile
개발 블로그

0개의 댓글