[채찍피티] 2일차. 공공데이터포털 오픈 API 사용법

채찍피티·2024년 4월 10일

채찍피티

목록 보기
4/8

프론트엔드 멘토링을 진행하며

첫 수업에서는 피그마를 이용한 개발 단 활용 방법에 대해 소개했고,

2일차에서는 실제로 API를 어떻게 호출하고 가져올 수 있는지

공공데이터포털 오픈 API를 활용하여 실습을 진행하였다.

공공 데이터 포털 오픈 API 란?

공공 데이터 포털에서 제공하는 데이터 중 오픈 API로 제공하는 데이터 들을 쉽게 이용할 수 있는 서비스이다.

접근할 수 있는 엔드포인트를 제공하며, 로그인 후 키 발급 요청시 무료로 이용할 수 있는 데이터들도 많이있다.

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

그 중 이번 프로젝트에서는 투두리스트에 오늘 날씨를 보여주는 서비스를 기획하였다.

실제 멘티님이 직접 작업하신 디자인으로 프론트단 개발과 공공 날씨 api 호출, TodoList CRUD를 위한 백엔드단 api호출 및 데이터베이스 저장까지 진행해 볼 예정이다.

상단부터 페이지에 들어가는 기능을 설명하자면,

  1. 선택자를 이용한 지역 선택
  2. 랜덤으로 날씨 아이콘 변경
  3. 공공 api를 통해 받아온 선택한 지역의 온도
  4. 오늘 날짜, 시간
  5. 투두리스트 생성, 수정, 삭제, 조회

로 진행해볼 예정이다.

하면서 나도 한번 구현해 보고 설명할 수 있도록 해야겠다.

1. 적절한 공공 API 찾기

처음 api 호출을 하신다고 해서 가장 접근하기 쉬운 데이터를 고려하다 날씨 데이터로 선택하였다.

그 중 기상청에서 제공하는 단기예보 조회서비스로 진행하게되었다.

보통 API 활용 가이드를 제공하는데 해당 서비스는 꽤 자세하게 나와있기 때문에
초보자도 쉽게 적용해 볼 수 있을거라 생각해 선택하게 되었다.

https://www.data.go.kr/tcs/dss/selectApiDataDetailView.do?publicDataPk=15084084

2. OPEN API 읽는 방법

해당 페이지에서 확인할 수 있는 중요 정보로는

  • API 유형: REST -> 리엑트에서 fetch, axios 등의 통신으로 요청 가능하다.
  • 비용 : 무료 -> 요청 트래픽이 많으면 비용이 발생하기도 한다.
  • 제공기관 : 기상청 -> 해당 사이트로 이동시 더 많은 정보를 확인할 수도 있다.
  • 데이터 포멧 : JSON+XML -> 주로 JSON 데이터를 많이 이용한다.
  • 신청가능 트래픽: 10,000 -> 요청할 수 있는 트래픽 양이 정해져있다.
  • 참고문서 : 활용가이드 -> 해당 문서를 통해 사용 방법을 알 수 있다.

API를 요청에 성공하기 위해서는 이러한 정보를 잘 확인하여야 한다.

상단에 있는 '활용신청' 버튼을 클릭하여 사용 가능한 서비스 키를 제공받을 수 있다.

단기예보 조회 서비스 같은 경우는 바로 신청 승인이 된다.

로그인 후 마이페이지 > 데이터 활용 > Open API > 활용 신청 현황에서 확인할 수 있다.

상세 페이지에서는 엔드포인트와 인증키, 기능 정보, 상세 정보에서 미리보기가 가능하다.

미리보기를 통해 어떤 요청 변수(Request Parameter)를 요청해야하는지,

어떤 형식으로 결과 값이 들어오는지 미리 확인해 볼 수 있다.

제공해준 참고문서를 확인해 보면

요청시 필요한 지역 별 격자 정보와

실질적인 요청 URL, 응답 메시지

응답 메시지 코드값과 규칙들을 확인할 수 있다.

해당 정보들을 이용해서 리엑트 RESTAPI 를 요청하는 코드를 작성해보자.

요청시에는 필수 요청 변수를 함께 전송해 주어야 값을 제대로 받아올 수 있다.

제공해 주는 자바스크립트 샘플 코드를 이용하여

리엑트에서 활용해 보자.

3. React API 요청 코드 작성(fetch)

/* Javascript 샘플 코드 */


var xhr = new XMLHttpRequest();
var url = 'http://apis.data.go.kr/1360000/VilageFcstInfoService_2.0/getUltraSrtNcst'; /*URL*/
var queryParams = '?' + encodeURIComponent('serviceKey') + '='+'서비스키'; /*Service Key*/
queryParams += '&' + encodeURIComponent('pageNo') + '=' + encodeURIComponent('1'); /**/
queryParams += '&' + encodeURIComponent('numOfRows') + '=' + encodeURIComponent('1000'); /**/
queryParams += '&' + encodeURIComponent('dataType') + '=' + encodeURIComponent('XML'); /**/
queryParams += '&' + encodeURIComponent('base_date') + '=' + encodeURIComponent('20240410'); /**/
queryParams += '&' + encodeURIComponent('base_time') + '=' + encodeURIComponent('0600'); /**/
queryParams += '&' + encodeURIComponent('nx') + '=' + encodeURIComponent('55'); /**/
queryParams += '&' + encodeURIComponent('ny') + '=' + encodeURIComponent('127'); /**/
xhr.open('GET', url + queryParams);
xhr.onreadystatechange = function () {
    if (this.readyState == 4) {
        alert('Status: '+this.status+'nHeaders: '+JSON.stringify(this.getAllResponseHeaders())+'nBody: '+this.responseText);
    }
};

xhr.send('');
  • 초단기실황조회 서비스를 호출하는 코드이다.
  • '서비스키'에서는 발급받은 본인의 인증 키로 대체해 주어야 한다.

정보를 불러올 컴포넌트에서

useEffect를 사용하여 데이터를 가지고 올 수 있다.

useEffect란?

리엑트 컴포넌트가 렌더링 될 때마다 특정 작업을 실행할 수 있도록 하는 리엑트 훅이다. 컴포넌트가 렌더링 된 이후에 비동기로 처리되어야 하는 일들을 실행가능하다.

이번에는 컴포넌트가 마운트 되었을때 해당 정보를 받아오기위해 사용되었다.

그렇기 때문에 deps는 비워둔 채로 코드를 작성하였다.

deps가 있게 되면 지정한 값이 업데이트 될때 useEffect를 실행 시킬 수 있다.

왜 fetch를 사용할까?

fetch는 자바스크립트의 내장 API 이기 때문에 별도의 라이브러리 설치 없이 이용이 가능하다.

또한 아래와 같이 직관적으로 사용 가능하기 때문에 초보자가 쉽게 접근하기 좋다.

이외에는 주로 axios와 같은 라이브러리를 많이 이용한다.

axios는 프로미스 기반으로 비동기 작업을 처리하는데 있어 직관적이고 편리한 방법을 제공하기도 한다.(get, post 메서드 제공 등)

 useEffect(() => {
    const fetchData = async () => {
      const url =
        "http://apis.data.go.kr/1360000/VilageFcstInfoService_2.0/getUltraSrtNcst"; 
      let queryParams =
        "?" +
        encodeURIComponent("serviceKey") +
        "=" +
        "서비스키";
      queryParams +=
        "&" + encodeURIComponent("pageNo") + "=" + encodeURIComponent("1");
      queryParams +=
        "&" +
        encodeURIComponent("numOfRows") +
        "=" +
        encodeURIComponent("1000");
      queryParams +=
        "&" + encodeURIComponent("dataType") + "=" + encodeURIComponent("JSON");
      queryParams +=
        "&" +
        encodeURIComponent("base_date") +
        "=" +
        encodeURIComponent("20240409");
      queryParams +=
        "&" +
        encodeURIComponent("base_time") +
        "=" +
        encodeURIComponent("0600");
      queryParams +=
        "&" + encodeURIComponent("nx") + "=" + encodeURIComponent('55');
      queryParams +=
        "&" + encodeURIComponent("ny") + "=" + encodeURIComponent('127');

      try {
        const response = await fetch(url + queryParams);
        console.log(response);
      } catch (error) {
        console.error("Error fetching data: ", error);
      }
    };

    fetchData();
  },[]);

"서비스키" 위치에는 발급받은 서비스 키를 복사해 붙여넣으면 된다.

깃허브 같은 클라우드 서비스에 코드 관리를 하게 될 경우

보안키는 .env 파일에 담아 관리할 수 있다.

이는 사용방법을 따로 게시글을 작성해 보겠다.

또한, 이 서비스는 최대 24시간 이내 정보만 불러올 수 있으므로

base_date 값과 base_time을 원하는 정보로 변경해 주어야 한다.

그렇지 않으면 아래와 같이 오류가 발생한다.

{"response":{"header":{"resultCode":"10","resultMsg":"최근 1일 간의 자료만 제공합니다."}}}

변경 후 해당 코드를 실행시키면

콘솔에 응답 내용을 받아올 수 있다.

{
 "response": {
   "header": {
     "resultCode": "00",
     "resultMsg": "NORMAL_SERVICE"
   },
   "body": {
     "dataType": "JSON",
     "items": {
       "item": [
         {
           "baseDate": "20240410",
           "baseTime": "0600",
           "category": "PTY",
           "nx": 55,
           "ny": 127,
           "obsrValue": "0"
         },
         {
           "baseDate": "20240410",
           "baseTime": "0600",
           "category": "REH",
           "nx": 55,
           "ny": 127,
           "obsrValue": "67"
         },
         {
           "baseDate": "20240410",
           "baseTime": "0600",
           "category": "RN1",
           "nx": 55,
           "ny": 127,
           "obsrValue": "0"
         },
         {
           "baseDate": "20240410",
           "baseTime": "0600",
           "category": "T1H",
           "nx": 55,
           "ny": 127,
           "obsrValue": "10.4"
         },
         {
           "baseDate": "20240410",
           "baseTime": "0600",
           "category": "UUU",
           "nx": 55,
           "ny": 127,
           "obsrValue": "0.4"
         },
         {
           "baseDate": "20240410",
           "baseTime": "0600",
           "category": "VEC",
           "nx": 55,
           "ny": 127,
           "obsrValue": "193"
         },
         {
           "baseDate": "20240410",
           "baseTime": "0600",
           "category": "VVV",
           "nx": 55,
           "ny": 127,
           "obsrValue": "1.8"
         },
         {
           "baseDate": "20240410",
           "baseTime": "0600",
           "category": "WSD",
           "nx": 55,
           "ny": 127,
           "obsrValue": "1.8"
         }
       ]
     },
     "pageNo": 1,
     "numOfRows": 1000,
     "totalCount": 8
   }
 }
}

이중에서 기온 정보를 가지고 와야함으로

해당 값들의 카테고리 정보는 상단의 코드값 이미지를 참조하시길 바란다.

response > body > items > item > "category"가 "T1H"인 > obsrValue 를 찾아 데이터를 저장할 수 있다.

따라서 try - catch 문을

try {
       const response = await fetch(url + queryParams);
       const data = await response.json();
       const newTemp = data.response.body.items.item.find(
         (item) => item.category === "T1H"
       ).obsrValue;
       setTemp(newTemp);
} catch (error) {
       console.error("Error fetching data: ", error);
}

이렇게 바꿔 호출해주었다.

그럼 해당 온도 값을(temp) 가지고 올 수 있게 된다!


자료를 따로 만들지 않고 라이브로만 수업을 진행하니

멘티님이 이해하시기에 어려움이 있다 판단되어

직접 코드를 작성하여 설명하면서 멘토링을 진행하고 있다.

쉽게 설명하기 위해 더 작은 단위로 컴포넌트를 구성하고,

기초 코드부터 단단히 쌓아갈 수 있어서 나도 많이 배우게 되는 것 같다.

이왕 이렇게 된거 교육 자료도 만들어볼까

profile
어? 왜 되지?

0개의 댓글