[외부 API] 외부 api 호출해 MySQL 데이터베이스에 데이터 인풋하기
우리 프로젝트는 사실상 데이터가 매우 중요한 서비스이다. 온라인 청년센터에서 제공해주는 신뢰성 있는 내용들을 보기 좋게 정리해주고 필터링해주는 서비스이기 때문에, 온라인 청년센터의 api를 사용해야 했다. 오늘은 외부 api 를 호출해 데이터를 인풋/저장하는 과정을 기록해보기로!! 💪
청년정책 api 신청하기
온라인 청년센터 에 들어가 회원가입 및 로그인을 한 후 인증키 신청과정을 거친다. 처음에는 공공데이터포털처럼 심사가 하루면 될 줄 알았는데 아니었다. 답답해서 청년정책 오픈카톡방에 문의해보니 일주일 내외로 걸린다고 하셨으니 참고가 되길 바랍니당 ㅜㅜ
마이페이지에서 인증키 확인이 된다면 성공이다.
Postman으로 확인하기
참고로 우리는 MVP 단계에서는 범위를 좁혀 주거/금융 카테고리의 정책들 중 중앙부처의 정책들만 다루기로 했다. 서비스에 맞게 파라미터를 입력해준 뒤 리스트가 응답으로 잘 오는지 확인한다.
데이터 인풋 코드 작성
우리 개발 환경은 node express + typescript, 디비는 mysql 이다. 파이썬으로 input 코드 작성은 꽤 해봤는데 이번에 기왕 js 로 개발하는거 인풋 코드도 스크립트 언어로 짜보기로 했다.
온라인 청년센터의 api는 결과를 json이 아닌 xml로 전달해주는데, json이 다루기 더 편하기 때문에 xml에서 json 으로 변환해주는 xml-js 라이브러리를 설치해주었다. 또한 외부 api 호출하는 데에 사용되는 request 라이브러리도 install 및 import 해준다.
인증키와 디비 관련 정보들은 .env 파일에 안전하게 저장해주고 dotenv 방식으로 호출한다.
아래는 작성한 전체 코드 내용이다 🤓
const convert = require('xml-js');
const request = require('request');
const mysql = require('mysql');
require('dotenv').config();
const OPEN_API_KEY = process.env.OPEN_API_KEY;
const connection = mysql.createConnection({
host: process.env.DB_HOST,
user: process.env.DB_USERNAME,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
});
const requestUrl = `https://www.youthcenter.go.kr/opi/empList.do?display=100&pageIndex=1&bizTycdSel=004003&openApiVlak=${OPEN_API_KEY}`;
request.get(requestUrl, (err, res, body) => {
if (err) {
console.log(`err => ${err}`);
} else {
if (res.statusCode == 200) {
const xmlToJson = convert.xml2json(body, { compact: true, spaces: 4 });
const json = JSON.parse(xmlToJson); // json 객체로 파싱
const emp = json.empsInfo.emp;
emp.forEach((data) => {
// 중앙부처 정책만
if (data.polyBizTy._cdata === '중앙부처') {
connection.query(
`SELECT count(*) FROM policy where name = "${data.polyBizSjnm._cdata}"`,
(err, results) => {
if (err) throw err;
// 정책 이름이 같은 데이터가 존재하지 않는다면 데이터 삽입
if (results[0]['count(*)'] == 0) {
connection.query(
`INSERT INTO policy(name, number, summary, content, limit_age, work_status, specialization, operating_institute, application_period, application_process, announcement, application_site) VALUES(?,?,?,?,?,?,?,?,?,?,?,?)`,
[
data.polyBizSjnm._cdata,
data.bizId._text,
data.polyItcnCn._cdata,
data.sporCn._cdata,
data.ageInfo._cdata,
data.empmSttsCn._cdata,
data.splzRlmRqisCn._cdata,
data.cnsgNmor._cdata,
data.rqutPrdCn._cdata,
data.rqutProcCn._cdata,
data.jdgnPresCn._cdata,
data.rqutUrla._cdata,
],
(err, results) => {
if (err) throw err;
console.log('results: ', results);
}
);
} else {
// 정책 이름이 같은 데이터가 존재한다면 넘어감
console.log('same policy already in db');
}
}
);
}
});
}
}
});
우선 request.get 으로 응답을 받아온다.
만약 성공적으로 응답을 받아 200 코드가 반환되었다면 밑의 코드들을 실행하게 되는데, 이때
const xmlToJson = convert.xml2json(body, { compact: true, spaces: 4 });
const json = JSON.parse(xmlToJson);
이 두 라인은 xml 결과인 body를 넣어 json으로 변환해준 뒤 json 객체로 파싱해주는 작업을 한다.
이후 forEach로 데이터를 훑으며 중앙부처의 정책만 저장했다.
sql 쿼리를 실행하기 위해서는 connection.query()를 사용하면 되는데, 특정 컬럼에 대해 중복되는 값이 있는지 확인하기 위해
SELECT count(*) FROM policy where name = "${data.polyBizSjnm._cdata}"
count를 가져오는 구문을 이용했다. policy 테이블의 name 컬럼에 대해 비교값과 일치하는 데이터가 존재한다면 쿼리 결과가 0보다 클 것이다.
이미 존재한다면 그 데이터는 넘어가고, 디비에 존재하지 않는 데이터는 insert 해준다.
connection.query(`INSERT INTO policy(컬럼) VALUES(?)`, [ 삽입할 값들 ]);
참고로 당연한 얘기겠지만 컬럼 개수와 물음표 개수, 삽입할 값의 개수는 모두 같아야 한다.
requestUrl의 파라미터 중 pageIndex 값을 11까지 늘려가며 인풋했으며
node (코드의 경로)
를 터미널에 입력해 코드를 실행할 수 있다.
디비에 저장되면서 이런 식으로 저장된 결과가 출력되고,
같은 이름의 정책이 이미 저장되어있다면 아래와 같이 "same policy already in db" 라고 출력되는 모습을 볼 수 있다 🧚
Author And Source
이 문제에 관하여([외부 API] 외부 api 호출해 MySQL 데이터베이스에 데이터 인풋하기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@julia/외부-API-외부-api-호출해-MySQL-데이터베이스에-데이터-인풋하기저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)