본문 바로가기
back/springframework

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

by jkoogi 2025. 4. 14.
반응형

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 사용

반응형