Server-To-Server 통신하기

  • 지금까지 살펴본 부분은 Server로서 Client에 API를 제공하는 방법을 학습했다.
  • Back-end에서 다른 Server에 요청을 보내서 받는 것을 필수적이다.
  • RestTemplate, WebClient, Apache Client… 등이 있다.
  • 이 중에 스프링에서 전통적으로 사용하는 RestTemplate에 대해 알아보자.

RestTemplate(1)

Client 생성

API요청을 받을 Client서버를 먼저 만들자.
Port는 8081로 설정했다.

먼저 서버에 요청을 보내는 로직을 구현할 RestTemplateService를 만들자.

@Service
@Slf4j
public class RestTemplateService {

    // http://localhost/api/server/hello
    // response
    public ResponseEntity<String> hello(){
        URI uri = UriComponentsBuilder
                .fromUriString("http://localhost:9091")
                .path("/api/server/hello")
                .encode()
                .build()
                .toUri();

        log.info(uri.toString());

        RestTemplate restTemplate = new RestTemplate();
        // rest메소드를 전부 지원한다.
        // getForEntity 같은 경우는 ResponseType을 지정해줘야한다.
        // getForObject 같은 경우는 지정한 타입으로 받을 수 있다.

        // getFor~~ 를 호출하는 시점이 Client가 http로 서버에 붙는 시점이다.
        ResponseEntity<String> result = restTemplate.getForEntity(uri, String.class);

        log.info("{}", result.getStatusCode());
        log.info("{}", result.getBody());

        return result;
    }
}

컨트롤러에는 간단하게 getMapping하나만 만들어주고, RestTemplateService의 hello를 호출하여 반환하도록 하자.

@RestController
@RequestMapping("/api/client")
@RequiredArgsConstructor
public class ApiController {

    private final RestTemplateService restTemplateService;

    @GetMapping("")
    public ResponseEntity<String> getHello(){
        return restTemplateService.hello();
    }
}

Server 생성

서버쪽에서는 해당하는 url에서 “server hello”를 반환하는 컨트롤러를 만들어주자.

@RestController
@RequestMapping("/api/server")
public class ServerApiController {

    @GetMapping("/hello")
    public String hello(){
        return "server hello";
    }
}

JSON으로 통신하기

Server에서 내려온 JSON 받기

일단 응답내려줄 JSON을 먼저 만들어보자.

{
  "name" : "dboo",
  "age" : 31
}

그리고 JSON을 받을 dto를 정의한다.

@Data
public class UserResponse {

    private String name;
    private int age;
}

이제 Client에서 ResponseEntity 타입으로 응답을 받는 것을 ResponseEntity 로 받도록 수정한다.

@Service
@Slf4j
public class RestTemplateService {

    // http://localhost/api/server/hello
    // response
    public UserResponse hello(){
        URI uri = UriComponentsBuilder
                .fromUriString("http://localhost:9091")
                .path("/api/server/hello")
                .encode()
                .build()
                .toUri();

        log.info(uri.toString());

        RestTemplate restTemplate = new RestTemplate();
        // rest메소드를 전부 지원한다.
        // getForEntity 같은 경우는 ResponseType을 지정해줘야한다.
        // getForObject 같은 경우는 지정한 타입으로 받을 수 있다.

        // getForObject호출하는 시점이 Client가 http로 서버에 붙는 시점이다.
        ResponseEntity<UserResponse> result = restTemplate.getForEntity(uri, UserResponse.class);
//        ResponseEntity result = restTemplate.getForObject(uri, UserResponse.class); // 비추천

        log.info("{}",result.getStatusCode());
        log.info("{}",result.getBody());

        return result.getBody(); //UserResponse 타입이기 때문에 컨트롤러에서도 UserResponse를 반환하도록 한다.
    }
}
@RestController
@RequestMapping("/api/client")
@RequiredArgsConstructor
public class ApiController {

    private final RestTemplateService restTemplateService;

    @GetMapping("")
    public UserResponse getHello(){
        return restTemplateService.hello();
    }
}

그다음 서버에서 JSON을 응답하도록 해보자.

dto를 하나 만들어준다.

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class User {
    private String name;
    private int age;
}

그리고 name, age에 값을 넣어서 User객체를 리턴해주도록 하자.

@RestController
@RequestMapping("/api/server")
public class ServerApiController {

    @GetMapping("/hello")
    public com.example.server.controller.dto.User hello(){

        return User.builder()
                .name("dboo")
                .age(31)
                .build();
    }
}

클라이언트에서 보낸 query-param을 받아서 리턴하기

클라이언트에서 UriBuilder를 통해 query-param을 담아서 던져보자.

URI uri = UriComponentsBuilder
        .fromUriString("http://localhost:9091")
        .path("/api/server/hello")
        .queryParam("name", "dboo-param")
        .queryParam("age", 131)
        .encode()
        .build()
        .toUri();

그리고 서버에서 queryParam을 받아서 리턴하도록 해보자.

@RestController
@RequestMapping("/api/server")
public class ServerApiController {

    @GetMapping("/hello")
    public User hello(@RequestParam String name, @RequestParam int age){

        return User.builder()
                .name(name)
                .age(age)
                .build();
    }
}