도리쓰에러쓰

[React] 공공데이터 API에 있는 데이터 출력하기 본문

React

[React] 공공데이터 API에 있는 데이터 출력하기

강도리 2022. 2. 22. 02:51

이번에 개인 프로젝트를 공공데이터포털에서 제공하고 있는 Open API를 기반으로 만들려고 한다.

아래 공공데이터포털 사이트에 가입하여 원하는 API에 대해 활용신청을 하면 된다.

 

공공데이터 포털

국가에서 보유하고 있는 다양한 데이터를『공공데이터의 제공 및 이용 활성화에 관한 법률(제11956호)』에 따라 개방하여 국민들이 보다 쉽고 용이하게 공유•활용할 수 있도록 공공데이터(Datase

www.data.go.kr


React 프로젝트 기본 세팅은 아래와 같다.

🔶 프로젝트 기본 세팅
1. 터미널에 npx create-react-app 프로젝트명 입력하여 프로젝트 생성
2. 터미널에 npm install add axios 입력하여 axios 라이브러리 설치
3. App.js에 axios 라이브러리 import 하기 ( import axios from 'axios'; )

1. Api Key 숨기기

- Api Key는 민감한 정보이기 때문에 .env 파일에 환경변수로 만들 예정이다.

 

1️⃣ 전역 파일 .env 생성하기

💡 env란?
Web, App 개발을 하다보면 API_KEY, 포트번호 등 외부에 공개되면 안되는 값들이 있다.
즉, git 등의 오픈소스에 올리면 안되는 값들이 있다.
이 때 필요한 것이 dotenv 패키지이고, 환경변수 파일을 외부에 만들어 API_KEY 등을 저장시켜 소스코드 내에 하드코딩하지 않고 사용할 수 있다.
.env 파일은 프로젝트의 최상위 루트에 위치하여야 한다.

 

 

2️⃣ dotenv 라이브러리 설치 후 .gitignore 파일에서 .env 파일 숨기기

- 터미널에 npm install dotenv 작성하여 dotenv 라이브러리 설치하기

- .gitignore 파일에서 아래 내용 작성하여 .env 파일 숨기기

# API KEY
.env

 

 

3️⃣ .env 파일에 api key 작성하기

💡 변수명은 아무렇게 작성하는 것이 아니다.

   React에서는 반드시 변수명을 REACT_APP 으로 시작해야 한다.

 

 

4️⃣ GET 요청을 할 파일에 api key 입력하기

- api key 작성하는 부분을 process.env.REACT_APP_API_KEY 로 작성하면 api key가 숨겨진다.

const URL = "http://apis.data.go.kr/B551182/";

const response = axios.get(URL, {
    params: {
      serviceKey: process.env.REACT_APP_API_KEY,
      numOfRows: 1,
      pageNo: 10
    }
});

 

 

🚨 실행하였더니 아래와 같은 CORS 에러가 발생했다.

Access to XMLHttpRequest at 'http://apis.data.go.kr/B551182/rprtHospService?numOfRows=1&pageNo=10' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

2. CORS 에러 해결하기

- CORS란 ?

참고 사이트 : https://evan-moon.github.io/2020/05/21/about-cors/

 

CORS는 왜 이렇게 우리를 힘들게 하는걸까?

이번 포스팅에서는 웹 개발자라면 한번쯤은 얻어맞아 봤을 법한 정책에 대한 이야기를 해보려고 한다. 사실 웹 개발을 하다보면 CORS 정책 위반으로 인해 에러가 발생하는 상황은 굉장히 흔해서

evan-moon.github.io

 

- 그래서 CORS 에러를 해결하기 위해 아래 사이트를 참고했다.

참고 사이트 : https://xiubindev.tistory.com/115

 

나를 너무나 힘들게 했던 CORS 에러 해결하기 😂

🔥 사건의 발단 : 외부 API 호출 때는 바야흐로 2020년 3월. 프론트엔드 공부를 시작한 지 얼마 되지 않은 채 홀로 토이 프로젝트를 진행하던 중이었다. 코로나 바이러스 관련 웹서비스를 만들고자

xiubindev.tistory.com

위 사이트를 참고하여 local과 공공데이터포털의 Open Api Server 둘을 프록시 서버로 연결할 예정이다.


1️⃣ package.json 파일에서 proxy 작성하기

- "proxy": "접근할 도메인"

"proxy": "http://apis.data.go.kr"

 

 

2️⃣ GET 요청을 할 파일에 URL 수정하기

1.4 에서 작성했던 변수 URL에서 도메인을 제외하고 남은 path를 입력해준다.

const URL = "/B551182/";

const response = axios.get(URL, {
    params: {
      serviceKey: process.env.REACT_APP_API_KEY,
      numOfRows: 1,
      pageNo: 10
    }
});

 

 

3️⃣ App.js에 요청 관리할 3개의 state를 만들기

const [data, setData] = useState(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);

- 요청의 결과 : data

- 로딩 상태 : loading

- 에러 : error

 

 

4️⃣ 아래 코드 작성하기

const fetchData = async () => {
    try {
      setError(null);
      setData(null);
      setLoading(true);

      const response = await axios.get(URL, {
        params: {
          serviceKey: process.env.REACT_APP_API_KEY,
          numOfRows: 1,
          pageNo: 10
        }
      });

      setData(response.data);
    } catch(e) {
      setError(e);
    }
    setLoading(false);
  };

  useEffect(() => {
    fetchData();
  }, []);
  
  if(loading) return <div>Loading...</div>;
  if(error)   return <div>Error...</div>;
  if(!data)   return null;

- setError(null), setData(null) : 요청 시작할 때 error와 data 초기화

- setLoading(true) : loading 상태 true로 변환

- const response : API에서 불러온 응답값을 response 변수에 저장

- setData(response) : response 값을 data에 저장

- useEffect : App Component가 처음 load될 때만 실행

 

 

5️⃣ return 값을 아래 코드와 같이 작성하여 화면에 출력하기

return (
    <div className="App">
      <p>병원명 : { data.response.body.items.item.yadmNm }</p>
      <p>주소 : { data.response.body.items.item.addr }</p>
      <p>전화번호 : { data.response.body.items.item.telno }</p>
      <p>RAT(신속항원검사) 가능 여부 : { data.response.body.items.item.ratPsblYn }</p>
      <p>PCR 가능 여부 : { data.response.body.items.item.pcrPsblYn }</p>
    </div>
  );

 

 

6️⃣ 터미널에 npm start 작성하여 데이터 출력되는지 확인하기

- 병원 개인정보가 많아 출력 이미지는 따로 가져오지 않았다.


3. 전체 코드

App.js

import './App.css';
import axios from 'axios';
import { useState, useEffect } from 'react';

const URL = "/B551182/";

function App() {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);

  const fetchData = async () => {
    try {
      setError(null);
      setData(null);
      setLoading(true);

      const response = await axios.get(URL, {
        params: {
          serviceKey: process.env.REACT_APP_API_KEY,
          numOfRows: 1,
          pageNo: 10
        }
      });

      setData(response.data);
    } catch(e) {
      setError(e);
    }
    setLoading(false);
  };

  useEffect(() => {
    fetchData();
  }, []);

  if(loading) return <div>Loading...</div>;
  if(error)   return <div>Error...</div>;
  if(!data)   return null;

  return (
    <div className="App">
      <p>병원명 : { data.response.body.items.item.yadmNm }</p>
      <p>주소 : { data.response.body.items.item.addr }</p>
      <p>전화번호 : { data.response.body.items.item.telno }</p>
      <p>RAT(신속항원검사) 가능 여부 : { data.response.body.items.item.ratPsblYn }</p>
      <p>PCR 가능 여부 : { data.response.body.items.item.pcrPsblYn }</p>
    </div>
  );
}

export default App;
Comments