본문 바로가기
개발 Study/Node

[Node.js] 공공 오픈 API 이용하기 - 지하철 노선 전체 정보 가져오기

by jiyoon_92 2022. 12. 16.
반응형

지하철 노선 전체 정보 오픈 API

철도데이터포털

 

1. API 신청하기

오픈API를 여러 방면으로 찾아봤는데 내가 원하는 데이터는 지하철 노선 전체 정보와 노선에 따른 역 정보였기 때문에 하단 링크에 있는 API를 사용하게 되었다.

https://data.kric.go.kr/rips/M_01_02/detail.do?id=431&service=trainUseInfo&operation=subwayRouteInfo 

 

철도 데이터 포털

열차이용정보 도시철도 전체노선정보 일반/고속철도 제공기관 : 전국도시철도운영기관등록일 : 2019.05.13활용신청 건수 : 230건 도시철도 전체노선정보 활용신청 기본정보 서비스 설명 도시철도

data.kric.go.kr

활용 신청 버튼을 클릭하고 요청하는 정보를 입력한 후 등록 버튼을 누르면 그냥 그대로 창이 닫힌다.

처음에 당황해서 고객센터에 메일도 보내고 그랬는데 알고보니 다음날 입력한 이메일 주소로 필요한 서비스키와 1년 동안 이용할 수 있다는 안내문이 메일로 온다.

확인 메일

이 메일을 받았다면 일단 신청에 성공했으며 서비스를 바로 사용할 수 있다.

반응형

2. API 사용법

2-1. 파라미터 관련 정보 다운받기

요청하는 방법을 확인하면 링크에 몇가지 파라미터를 넣어 요청해야하는데, 필요한 정보는 아래와 같다. 이메일로 받은 서비스키와 format 정보, 그리고 선코드(노선코드), 권역 코드 를 파라미터로 넣어야 한다. 선코드는 그럼 어디서 얻어올까?

사용 변수

 

철도 데이터 포털에서 정보공유 -> 자료실을 가보면 최신 노선 정보에 대한 코드 정보 리스트를 다운 받을 수 있다.

https://data.kric.go.kr/rips/M_04_02/intro.do

 

철도 데이터 포털

 

data.kric.go.kr

excel 파일로 제공되는 정보들은 그대로 DB에 가공하여 넣을 수도 있지만 언제 업데이트될지 모르기 때문에 추후 Python으로 크롤링을 만들어 다운받을 예정이다. 그러나 역정보는 노선코드만 알면 다운받기가 가능한데, 권역코드는 위에 나온대로 (01:수도권, 02:부산, 03:대구, 04:광주, 05:대전) 으로 고정되어있으므로 DB에 그대로 입력했다.

운영기관_역사_코드정보_2022.09.28.xlsx
0.05MB

 

권역에 따른 노선 정보는 Excel에 나와있으며 각 노선에 대한 색상 코드도 넣기 위해 아래 링크를 참조해서 노선 코드/노선명/노선 컬러 에 대한 정보를 테이블에 저장했다.

https://ko.wikipedia.org/wiki/%ED%8B%80:%ED%95%9C%EA%B5%AD_%EC%B2%A0%EB%8F%84_%EB%85%B8%EC%84%A0%EC%83%89

 

틀:한국 철도 노선색 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전.

ko.wikipedia.org

여기까지가 노선 정보를 세팅하는 방법이고 다음으로는 이 정보들을 이용해 역 정보를 가져온다.


2-2. 노선별 역 정보 가져오기

Node 모듈 중 axios를 이용해 api request를 날린다. GET 방식으로 파라미터를 아래와 같이 넣어 날리면 완전 실시간은 아니지만 정보가 날아온다.

const url = `https://openapi.kric.go.kr/openapi/trainUseInfo/subwayRouteInfo`;
const { data } = await axios.get(url, {
        params : {
          serviceKey : process.env.SUBWAY_SERVICE_KEY,
          format : 'json',
          mreaWideCd : area.area_code,
          lnCd : line.line_code
        }
        });

JSON 방식으로 받아 내가 원하는 노선별 Station Code, Station Name을 받고 가공하여 만들어 놓은 테이블에 집어 넣는 로직을 짰다.

Subway Area(권역정보) - Line(노선정보) - Station(역정보) 이런 식으로 연결되어 있으며 1 : N, 1 : N 부모와 자식 관계는 1:N으로 되어있다.

아래 코드를 살펴보자.

const fetchAllStationInfo = async () => {
  const url = `https://openapi.kric.go.kr/openapi/trainUseInfo/subwayRouteInfo`;
  const subwayArea = await SubwayArea.findAll({include : [{ as : 'lines', model : SubwayLine}]});
  if (subwayArea) {
    subwayArea.forEach(area => {
      area.lines.forEach(async (line) => {
        const { data } = await axios.get(url, {
        params : {
          serviceKey : process.env.SUBWAY_SERVICE_KEY,
          format : 'json',
          mreaWideCd : area.area_code,
          lnCd : line.line_code
        }
        });
        if (data) {
          if (data.body) {
            const filtered_data = data.body.filter((x: { lnCd: string; }) => x.lnCd == line.line_code);
            const station_list = filtered_data.map((element : any) => {
             const station : SubwayNameDto = {
              subway_line_id : line.subway_line_id,
              station_code : element.stinCd,
              station_name : element.stinNm,
             }
             return station;
            });
            const result = await ORM.getInstance().transaction(async (t) => {
              const subwayNames = await SubwayName.bulkCreate(station_list, {transaction : t});
              return subwayNames.length > 0 ? true : false;
            });
          }
        }
      });
    });
  }
 }

bulk insert

기존에 등록된 SubwayArea-SubwayLine 정보를 호출하여 각 권역별 - 노선을 foreach로 돌면서 api 요청을 한다. 요청에 따라 데이터가 오면 filter와 map 함수로 원하는 정보 형태만 받고 가공하여 역 정보 리스트를 만든다. 리스트를 만든 후 해당 노선에 따른 역 정보들을 한번에 bulk로 insert 한다. 

내부적으로만 쓸거라서 따로 error처리는 안했지만 추후 리팩토링해야겠다. 아무래도 주기적으로 이 함수를 호출하여 DB에 저장된 역 정보를 업데이트해야할 것 같다.

다음엔 등록된 정보를 이용하여 역 검색어 자동완성 기능을 구현해야하므로 그 때 다시 포스팅하도록 하겠다.

 

반응형

댓글