back/springframework

공공데이터 날씨 조회 서비스 프로젝트 구성

jkoogi 2025. 4. 14. 02:21
반응형

Spring Boot 프로젝트에 공공데이터 조회를 위한 서비스를 만들어봅니다.
안녕하세요! 공공데이터의 날씨예보 API를 이용하여 날씨를 조회하는 기능을 대상으로 
Spring Boot와 FeignClient 를 사용하여 간단한 조회서비스를 만들어보겠습니다.

 

0. 공공데이터 포털에서 날씨 API를 찾아 응답정보를 확인합니다. 

* 대상 API 

 - 공공데이터 : https://www.data.go.kr/index.do

 - 기상청_단기예보 ((구)_동네예보) 조회서비스  https://www.data.go.kr/data/15084084/openapi.do
 - 초단기실황예보  URL : http://apis.data.go.kr/1360000/VilageFcstInfoService_2.0/getUltraSrtNcst

 > 공공데이터 포털에 가입하고 API 활용신청을 하여 서비스키를 발급받아야 합니다. 

 

 

1. Spring Boot 프로젝트 생성하기
Spring Initializr를 통해 기본 프로젝트를 생성하겠습니다. 

 - 빌드 : gradle-groovy

 - 언어 : java 24

 - boot : 3.5

 - 패키지 : jar

 - 의존성 : Spring Web, Spring Boot DevTools, Spring Cloud OpenFeign, Lombok



2. FeignClient 설정하기
FeignClient를 사용하여 공공데이터 API를 호출할 수 있도록 설정하겠습니다. API 호출을 위한 인터페이스를 정의하고, 필요한 메소드를 추가 합니다.

@FeignClient(name = "weatherClient", url = "${weather.api.url}")
public interface WeatherClient {
    // /getUltraSrtNcst?ServiceKey=${openData.key}&pageNo=1&numOfRows=10&dataType=JSON&base_date=20250413&base_time=0600&nx=55&ny=127
    @GetMapping("/getUltraSrtNcst?ServiceKey=${openData.key}")
    WeatherResponse getUltraSrtNcst(
            @RequestParam("pageNo") int pageNo,
            @RequestParam("numOfRows") int numOfRows,
            @RequestParam("dataType") String dataType,
            @RequestParam("base_date") String baseDate,
            @RequestParam("base_time") String baseTime,
            @RequestParam("nx") int nx,
            @RequestParam("ny") int ny
    );
}


3. API 호출을 위한 DTO 클래스 만들기
API 응답을 매핑할 DTO 클래스를 생성하겠습니다. JSON 응답 구조에 맞게 필드를 정의해 주세요.

@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class WeatherResponse {
    @JsonProperty
    private Response response;

    @Data
    public static class Response {
        @JsonProperty("header")
        Header header;
        @JsonProperty("body")
        Body body;
    }

    @Data
    public static class Header {
        @JsonProperty("resultCode")
        String resultCode;
        @JsonProperty("resultMsg")
        String resultMsg;
    }
    @Data
    public static class Body {
        @JsonProperty("dataType")
        String dataType;
        @JsonProperty("items")
        Items items;
        @JsonProperty("pageNo")
        String pageNo;
        @JsonProperty("numOfRows")
        String numOfRows;
        @JsonProperty("totalCount")
        String totalCount;
    }
    @Data
    public static class Items {
        @JsonProperty("item")
        List<Item> items;
    }
    @Data
    public static class Item {
        @JsonProperty("baseDate")
        private String baseDate;
        @JsonProperty("baseTime")
        private String baseTime;
        @JsonProperty("nx")
        private String nx;
        @JsonProperty("ny")
        private String ny;
        @JsonProperty("category")
        private String category;
        @JsonProperty("obsrValue")
        private String obsrValue;
    }
}



4. 서비스 클래스 구현하기
날씨 조회 기능을 포함하는 서비스 클래스를 작성하겠습니다. FeignClient를 통해 API를 호출하고, 응답 데이터를 처리하는 로직을 구현해 주세요.

 - 응답정보 확인을 위해 문자열로 응답을 확인하는 getUltraSrtNcstS 메서드를 임시로 구성함

@Log4j2
@Component
public class WeatherService {

    private final WeatherClient weatherClient;
    public WeatherService(WeatherClient weatherClient){
        this.weatherClient = weatherClient;
    }
    public WeatherResponse getUltraSrtNcst(WeatherDto weatherDto) {
        String baseDate = weatherDto.getBaseDate();
        String baseTime = weatherDto.getBaseTime();
        int nx = weatherDto.getNx();
        int ny = weatherDto.getNy();

        WeatherResponse response = weatherClient.getUltraSrtNcst(1, 10, "JSON", baseDate, baseTime, nx, ny);
        log.debug("# getUltraSrtNcst - response : {}",response);
        return response;
    }

    public String getUltraSrtNcstS(WeatherDto weatherDto) {
        String baseDate = weatherDto.getBaseDate();
        String baseTime = weatherDto.getBaseTime();
        int nx = weatherDto.getNx();
        int ny = weatherDto.getNy();

        String response = weatherClient.getUltraSrtNcstS(1, 10, "JSON", baseDate, baseTime, nx, ny);
        log.debug("# getUltraSrtNcstS - response : {}",response);
        return response;
    }
}

 

 

5. Controller 구현하기

@Log4j2
@RestController
@RequiredArgsConstructor
public class WeatherController {
    private final WeatherService weatherService;

    @GetMapping("/api/weather")
    public WeatherResponse getUltraSrtNcst( @ModelAttribute WeatherDto weatherDto){
        log.debug("# getUltraSrtNcst - weatherParam : {}", weatherDto);
        WeatherResponse response = weatherService.getUltraSrtNcst(weatherDto);
        return response;
    }
    @GetMapping("/api/weatherS")
    public String getUltraSrtNcstS( @ModelAttribute WeatherDto weatherDto){
        log.debug("# getUltraSrtNcstS - weatherParam : {}", weatherDto);
        String response = weatherService.getUltraSrtNcstS(weatherDto);
        return response;
    }
}



6. Spring Boot 애플리케이션 설정하기
application.properties 파일에 API 키 및 기본 URL을 설정합니다.

 - 공공데이터의 키와 날씨 api 설정을 분리

spring.application.name=junit5test
openData.key={발급받은키값}
weather.api.url=http://apis.data.go.kr/1360000/VilageFcstInfoService_2.0

 

 

7. 서비스 응답 확인

* 응답 전문

더보기
{
    "response": {
        "header": {
            "resultCode": "00",
            "resultMsg": "NORMAL_SERVICE"
        },
        "body": {
            "dataType": "JSON",
            "items": {
                "item": [
                    {
                        "baseDate": "20250413",
                        "baseTime": "0600",
                        "nx": "55",
                        "ny": "127",
                        "category": "PTY",
                        "obsrValue": "0"
                    },
                    {
                        "baseDate": "20250413",
                        "baseTime": "0600",
                        "nx": "55",
                        "ny": "127",
                        "category": "REH",
                        "obsrValue": "63"
                    },
                    {
                        "baseDate": "20250413",
                        "baseTime": "0600",
                        "nx": "55",
                        "ny": "127",
                        "category": "RN1",
                        "obsrValue": "0"
                    },
                    {
                        "baseDate": "20250413",
                        "baseTime": "0600",
                        "nx": "55",
                        "ny": "127",
                        "category": "T1H",
                        "obsrValue": "6.4"
                    },
                    {
                        "baseDate": "20250413",
                        "baseTime": "0600",
                        "nx": "55",
                        "ny": "127",
                        "category": "UUU",
                        "obsrValue": "4.5"
                    },
                    {
                        "baseDate": "20250413",
                        "baseTime": "0600",
                        "nx": "55",
                        "ny": "127",
                        "category": "VEC",
                        "obsrValue": "253"
                    },
                    {
                        "baseDate": "20250413",
                        "baseTime": "0600",
                        "nx": "55",
                        "ny": "127",
                        "category": "VVV",
                        "obsrValue": "1.4"
                    },
                    {
                        "baseDate": "20250413",
                        "baseTime": "0600",
                        "nx": "55",
                        "ny": "127",
                        "category": "WSD",
                        "obsrValue": "4.7"
                    }
                ]
            },
            "pageNo": "1",
            "numOfRows": "10",
            "totalCount": "8"
        }
    }
}
 

기상청_단기예보 ((구)_동네예보) 조회서비스

초단기실황, 초단기예보, 단기((구)동네)예보, 예보버전 정보를 조회하는 서비스입니다. 초단기실황정보는 예보 구역에 대한 대표 AWS 관측값을, 초단기예보는 예보시점부터 6시간까지의 예보를,

www.data.go.kr

 

 

 


[추가 포인트]

 

* 롬복 추가시 build.gradle 에 아래 코드가 빠지면 롬복 annotation이 동작을 안함

configurations {
	compileOnly {
		extendsFrom annotationProcessor
	}
}

 

* FeignClient 적용시 main 메서드가 정의된 application 클래스에 @EnableFeignClients 설정필요 - 참고

 - @FeignClient(name="이를", url="{url}") 에서 설정한 이름으로 구현체를 참조하기위한 설정으로 보임.

 

FeignClient 사용법에 대해 알아봅시다. (Spring Cloud OpenFeign)

안녕하세요 👨‍💻오늘은 웹 서버 프로그램에서 간단하게 Http Request 를 보내 주는 선언적 Http Client 기능을 하는"Feign Client" 에 대해 알아보겠습니다.프로젝트를 진행하면서 이메일 인증 시스템

velog.io

* FeignClient api 호출한 응답클래스 정의시 내부클래스는 static으로 선언 필요

@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class WeatherResponse {
    @JsonProperty
    private Response response;

    @Data
    public static class Response {
        @JsonProperty("header")
        Header header;
        @JsonProperty("body")
        Body body;
    }
    ...
}

* controller 에서 요청 파라미터 정보를 객체로 받으려면 @ModalAttribute 사용

반응형