[React] 공공데이터 API 활용하여 웹페이지 만들기

borderline0px·2021년 8월 27일
2

React

목록 보기
2/3

🍒 공공데이터 포털
https://www.data.go.kr

공공데이터 포털을 통해 두번째 프로젝트를 하다가 몇 가지 이슈들을
공유하면 좋을 것 같아서 작성해본다

✔️프로젝트 세팅
create-react-app, axios 라이브러리를 사용하여
프로젝트를 진행하고 있다

1. open API 활용 신청 후, 승인 받았는데 인증키가 유효하지 않다는 메시지를 받는다면?

💡 활용 신청 후 맘 편하게 하루 지나고 사용해보자

우리는 데이터 활용 신청 시 바로 데이터에 접근할 수 있는 것은 아니라는
팝업을 접할 것이다(이건 캡쳐를 깜빡해서,,)
한 시간 또는 24시간이 걸릴 수도 있다고 말해준다

그러니까 만약 이런 이슈가 발생한다면 그냥 하루 기다려보고
다시 진행해보자🥺

2. api key 숨기기

create react app을 활용하면 api key는 쉽게 숨길 수 있었다

2.1 전역 폴더에 .env파일 생성하기

2.2 .gitignore 파일에서 .env파일 숨기기

.env 

ignore 된 파일은 다른 파일보다 흐리게 보인다!!!
위의 이미지를 자세히 보면 확인 가능하다

2.3 .env 파일에 API key 적어주기

REACT_APP_API_KEY=인증키

위와 같은 형식으로 작성해주면 된다

2.4 get요청을 해줄 파일로 가서 api키 사용하기

api_key 부분을 process.env.REACT_APP_API_KEY 형태로
받아오면 api key 숨기는 과정은 끝난다


3. CORS 이슈🥺

CORS(Cross-Origin Resource Sharing)
참고 사이트: https://evan-moon.github.io/2020/05/21/about-cors/

위와 같은 오류가 떴다면 proxy를 통해 해결할 수 있다

⭐️ 그러나 이와 같은 해결방법은 개발환경에서만 가능하다
=> yarn start 즉, devServer에서만 가능하다는 이야기⭐️

yarn build를 했을 경우에는 data를 받아오지 못한다

개발환경에서는 CRA가 지원해주는 devServer가 존재하기 때문에
local과 공공데이터포털의 해당 api server, 둘을 proxy로 연결이 가능했다

그러나 build 된 이후에는 build라는 이름의 정적 디렉토리만 남기 때문에 위와 같은 해결법으로는 데이터를 받아올 수 없다


일단, 개발환경에서 proxy를 설정하는 방법은 아래와 같다

3.1 package.json 파일로 이동해 proxy를 작성

package.json에서 마지막 부분에 위와 같이

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

을 작성해준다

3.2 GET 요청할 파일로 가서 path를 작성해주기


도메인을 제외하고 남은 path를 입력해준다

서버를 다시 시작해서 확인해보자😊

3.3 build시 CORS 해결법

📎
https://xiubindev.tistory.com/115
📎 https://velog.io/@recordboy/Express-React-연동-및-Heroku에-배포하기

위의 두 블로그 글을 대부분 참고하였다
정말 감사했다ㅜㅜ🥺

  • 나는 express를 사용하여 직접 프록시 서버를 구축하는 방법으로 사용했다
  • 최종 배포: heroku
🐾 디렉토리 나누기(client와 server)


create-react-app으로 만든 프론트는 client 디렉토리에 담고
현재 디렉토리에 npm init하여 server.js 파일을 만들어주었다

🐾 server가 있는 디렉토리에 디펜던시 추가하기
npm install express nodemon

nodemon은 node monitor의 약자로 파일이 수정되면 자동으로 감지하여 따로 명령어 없이 서버가 재실행되도록 해준다

🐾 server가 있는 디렉토리의 package.json에 scripts 추가하기
"scripts": {
    "start": "node server.js",
    "client": "cd client && npm start"
  },
🐾 server.js 파일 작성

나의 프로젝트는 코로나19 시도감염 현황과 연령별 성별 감염 현황, 두 가지 open api를 가져온다
그래서 두 가지 경로로 요청이 들어올 수 있도록 하였다

const express = require("express");
const axios = require("axios");
const path = require("path");

const app = express();

const port = process.env.PORT || 5000;
app.listen(port);

const covid_baseURL = "http://openapi.data.go.kr/openapi/service/rest/Covid19";

const getGenAgeData = async (request) => {
  let response;
  try {
    response = await axios({
      method: "get",
      url: `${covid_baseURL}/getCovid19GenAgeCaseInfJson`,
      params: {
        serviceKey: request.query.serviceKey,
        pageNo: request.query.pageNo,
        numOfRows: request.query.numOfRows,
        startCreateDt: request.query.startCreateDt,
        endCreateDt: request.query.endCreateDt,
      },
    });
  } catch (error) {
    console.log(error);
  }

  response = response.data.response.body.items.item;
  return response;
};

const getSidoData = async (request) => {
  let response;
  try {
    response = await axios.get(`${covid_baseURL}/getCovid19SidoInfStateJson`, {
      params: {
        serviceKey: request.query.serviceKey,
        pageNo: request.query.pageNo,
        numOfRows: request.query.numOfRows,
        startCreateDt: request.query.startCreateDt,
        endCreateDt: request.query.endCreateDt,
      },
    });
  } catch (error) {
    console.log(error);
  }
  response = response.data.response.body.items.item;

  return response;
};

app.get("/api/gen-age", (req, res) => {
  getGenAgeData(req).then((response) => {
    return res.json(response);
  });
});

app.get("/api/sido", (req, res) => {
  getSidoData(req).then((response) => {
    return res.json(response);
  });
});

// heroku가 client의 정적 파일에 접근할 수 있도록
app.use(express.static(path.join(__dirname, "client/build")));

app.get("*", (req, res) => {
  res.sendFile(path.join(__dirname + "client/build/index.html"));
});

(반복되는 코드는 개선 예정)

client로부터 각각의 path(/api/gen-age, /api/sido)로 요청이 오면
요청시 같이 보내진 params를 그대로 받아서
open API 서버에 다시 request를 보내도록 해주었다

🐾 client에서의 요청

클라이언트에서는 요청을
open API로 보내주는 것이 아니라
자신이 서버에서 설정한 경로로 보내주면 된다


무작정 CORS에러를 해결하는 것에 초점을 맞추다보니
많은 것을 간과했을 것이다

heroku 배포에 관한 사항은 연재 예정

앞으로 더 보완해나가겠다

profile
어려운 게 아니라 낯설어서 그런거야

1개의 댓글

comment-user-thumbnail
2021년 12월 22일

localhost:3000 인데 url 부분에 http 나 https 부분 필요없나요?

답글 달기