Back-end/Spring

[JAVA/Springboot] open API 사용법(공공데이터)

Nellie Kim 2024. 4. 3. 15:09
728x90

1. OPEN API 신청

 

사용하고 싶은 오픈 API를 골라서 활용신청을 해준다. 나는 아래 사이트에서 영양정보를 제공하는 공공API를 사용하였다.

 

https://www.data.go.kr/iim/api

 

활용신청 클릭

 

활용내용은 대충 '웹사이트 개발용' 이라고 적었다.

 

그러면 기다릴 필요도 없이 자동 승인이 되고, 인증키를 사용할 수 있게 된다.

 

 

 

 

참고문서의 .doc 파일을 보니 아주 자세히 요청을 어떻게 하는지 나와있다.

 

이렇게 해도 되지만, URL마지막 부분을 type=json으로 해주면 JSON으로 반환되어 편리하다.  아래처럼 호출해주었다. 

 

http://apis.data.go.kr/1470000/FoodNtrIrdntInfoService/getFoodNtrItdntList?ServiceKey=서비스키(URL Encode)&numOfRows=3&pageNo=1&type=json

 

 

받은 일반인증키(인코딩된것)만 넣고 그대로 주소창에 넣어보았다.

아래와 같이 잘 출력이 된다.

 

 

이제 진짜로 백엔드에 넣고 요청을 해보자.


2. 백엔드에서 사용하기

2-1. 컨트롤러

@RestController
@RequestMapping("/diet")
public class DietCtrl {
    @Autowired
    public DietSvc dietSvc;

    // 음식 목록을 오픈 API로 조회
    @GetMapping("/getFoodList")
    public FoodInfoResponseDto getFoodList(@ModelAttribute FoodInfoRequestDto request) {
        return dietSvc.getFoodList(request);
    }
}

 

 

2-2. 서비스

@Service
public class DietSvcImpl implements DietSvc {
    @Autowired
    private CallApi callApi;

    @Override
    public FoodInfoResponseDto getFoodList(FoodInfoRequestDto request) {
        return callApi.getRequest(FOOD_NUTRIENT_URL, request, FoodInfoResponseDto.class);
    }
}

 

 

2-3. 호출 클래스 

오픈API를 호출하는 클래스이다.

@Component
public class CallApi {
    // API 호출에 필요한 인증 키
    public static final String AUTH_ENCODING_KEY = "6pHHT~~~~~2FEjrQ%3D%3D";

    // 식품의약품안전처_식품 영양성분 정보 API 엔드포인트 URL
    public static final String FOOD_NUTRIENT_URL = "https://apis.data.go.kr/1470000/FoodNtrIrdntInfoService/getFoodNtrItdntList";

    private final ObjectMapper objectMapper = new ObjectMapper();

    // 호스트 이름 확인을 수행하는 OkHttpClient 생성
    OkHttpClient.Builder client = new OkHttpClient.Builder().hostnameVerifier(new HostnameVerifier() {
        @Override
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    });

    // GET 요청을 수행하고 결과를 객체로 반환하는 메서드
    public <T, C> C getRequest(String url, T requestMap, Class<C> clazz) {
        try {
            // ObjectMapper 설정
            ObjectMapper objectMapper = new ObjectMapper();
            objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
            Map<String, Object> queryParams;

            // 요청 맵이 맵인지 확인하여 변환
            if (requestMap instanceof Map) {
                queryParams = (Map<String, Object>) requestMap;
            } else {
                queryParams = objectMapper.convertValue(requestMap, Map.class);
            }

            // 쿼리 매개변수를 사용하여 URL 생성
            StringBuilder urlString = new StringBuilder(url);
            if (queryParams != null && !queryParams.isEmpty()) {
                urlString.append("?");
                for (Map.Entry<String, Object> entry : queryParams.entrySet()) {
                    urlString.append(entry.getKey())
                            .append("=")
                            .append(entry.getValue())
                            .append("&");
                }
                urlString.deleteCharAt(urlString.length() - 1); // 마지막 '&' 제거
            }
            
            // GET 요청 객체 생성
            Request request = new Request.Builder()
                    .url(urlString.toString()) // 생성된 URL 문자열 사용
                    .get()
                    .addHeader("Connection", "keep-alive")
                    .build();

            // 요청을 수행하고 응답을 받음
            Response response = client.build().newCall(request).execute();

            // 응답 내용을 객체로 변환하여 반환
            return objectMapper.readValue(response.body().string(), clazz);
        } catch (JsonProcessingException e) { 
            log.error("실패 - JsonProcessingException {}", e.getMessage());
            return null;
        } catch (IOException e) {
            log.error("실패 - IOException {}", e.getMessage());
            return null;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

 

 

백엔드 포스트맨 호출도 성공적으로 되었고,

 

프론트에서도 아래와 같이 요청을 했다. 

성공적으로 호출이 완료되었다. 

 

 

프론트에서 오픈API를 사용하여 음식 검색하는 화면을 완성했다.