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