ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 3. 그레이들 멀티프로젝트 - RestTemplate
    스프링개발자/301 - 아키텍처 2020. 8. 30. 04:29

    [배경]

    앞서 구현한 두개의 어플리케이션 간의 호출이 일어나게 하자.

     


    1. RestController 만들기

    weather-application내에 비가 오는 확율을 계산해주는 ForecastController를 만든다.

    package com.example.monorepo;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.*;
    
    import java.util.List;
    
    @RestController
    @RequestMapping(value = "/weather")
    public class ForecastController {
    
        @Autowired
        ForecastService forecastService;
    
        @GetMapping(value = "/forecast/{days}")
        public List<Double> forecast(@PathVariable int days) {
            return forecastService.predict(days);
        }
    }
    

     Autowired로 주입받는 ForecastService는 다음과 같다;

    package com.example.monorepo;
    
    import org.springframework.stereotype.Service;
    
    import java.util.ArrayList;
    import java.util.List;
    
    @Service
    public class ForecastService {
    
        public List<Double> predict(int days) {
            List<Double> rainProbabilityList = new ArrayList<>();
            for (int i = 1; i <= days; i++) {
                if (i == 5) {
                    rainProbabilityList.add(1.0);
                } else if (i % 2 == 0) {
                    rainProbabilityList.add(0.5);
                } else{
                    rainProbabilityList.add(0.1);
                }
            }
            return rainProbabilityList;
        }
    }
    

    오늘부터 5일 후의 비가 올 확율이 100%, 오늘부터 짝수만큼의 날들은 비올 확율 50%, 그 외엔 10%라고 임시 설정. 

     

    2. RestController 동작 확인

    WeatherApplication을 구동시킨다.

    http://localhost:8081/weather/forecast/7

     

    [
    0.1,
    0.5,
    0.1,
    0.5,
    1,
    0.5,
    0.1
    ]

     

    3. 어플리케이션간의 호출

    main-application의 MainController에서 weather-application의 ForecastController호출해보자.

    RestTemplate을 이용한다.

     

    앞으로 1주일의 야외수업 여부를 알아보는 api endpoint 이다.

    임의의 임계치인 0.4보다 같거나 높은 비 올 확률이면, 야외수업을 가지 않고, 0.4보다 낮으면 야외수업을 간다고 알려준다.

     

    main-application에 PlanService를 만든다.

    package com.example.monorepo;
    
    import org.springframework.http.HttpHeaders;
    import org.springframework.http.MediaType;
    import org.springframework.http.ResponseEntity;
    import org.springframework.stereotype.Service;
    import org.springframework.web.client.RestTemplate;
    
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    
    @Service
    public class PlanService {
    
        public List<Boolean> canGoOutsideForWeek(double threshold) {
            RestTemplate restTemplate = new RestTemplate();
    
            // create headers
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
    
            // send POST request
            String url = "http://localhost:8081/weather/forecast/7";
            ResponseEntity<Object[]> response = restTemplate.getForEntity(url, Object[].class);
            ArrayList<Double> body = new ArrayList(Arrays.asList(response.getBody()));
            ArrayList<Boolean> yesno = new ArrayList<>();
            for (Double d : body) {
                if (d < threshold) {
                    yesno.add(true);
                } else {
                    yesno.add(false);
                }
            }
            return yesno;
        }
    }
    

    RestTemplate call에 대한 자세한 내용은 이전 글(https://2ndprince.tistory.com/12) 참고

     

    MainController에도 PlanService를 주입받고, endpoint 하나를 더 추가했다.

    package com.example.monorepo;
    
    import com.example.monorepo.model.User;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import java.util.List;
    
    @RestController
    @RequestMapping(value = "/main")
    public class MainController {
    
        @Autowired
        PlanService planService;
    
        @GetMapping(value = "/demo")
        public User demo(){
            User myUser = new User();
            myUser.setAge(10);
            myUser.setName("2nd prince");
            myUser.setId("1");
            return myUser;
        }
    
        @GetMapping("/weekly")
        public String makeWeeklyPlan(){
            List<Boolean> booleans = planService.canGoOutsideForWeek(0.4);
            return booleans.toString();
        }
    }
    

    http://localhost:8080/main/weekly를 get으로 실행해본다.

    [true, false, true, false, false, false, true]

    WeatherApplication을 호출하여 받은 비올 확율 값을 이용하여 야외수업을 나갈지 여부를 결정해주는 endpoint를 만들었다.

     

    Client Request -> MainController -> PlanService -> ForestController -> ForecastService -> ForecastController -> PlanService -> MainController -> Client Response 의 흐름이다.

     

    소스코드

    https://github.com/2ndPrince/monorepo/tree/monorepo_restTemplate


    [TroubleShooting]

    1. restTemplate call으로 List<Double>을 받아온다. Object[].class으로 하였다. type safe하지 못한 좋지 않은 방법인데, 이것을 해결하려면 ParameterizedTypeReference 을 사용하면 되지만, Double에 막혀서 못 구현했다.

Designed by Tistory.