본문 바로가기

프로젝트

TourAPI 따오기

공공데이터포탈과 TourAPI는 다른 사이트지만 연결돼 있는 하나의 시스템이다. 

도메인 data.go.kr tourapi.or.kr
역할 API 총집합 플랫폼
(정부기관/지자체 모든 API 검색 & 신청)
한국관광공사에서 제공하는 관광 API 전용 포털
인증키 발급 보통 여기서 발급 여기서도 가능, 동일 계정 연동
실제 데이터 제공 기관마다 다름 (관광 = 한국관광공사) 관광지, 음식, 숙박, 축제에 특화된 API
회원가입 해야 함 (API 신청하려면) 여기서도 가능, but data.go.kr에서 대부분 처리

 

왼쪽이 공공데이터포털, 오른쪽이 한국관광공사 TourAPI

 

 

  • data.go.kr에서 가입 → TourAPI 신청 → 인증키 발급
  • tourapi.or.kr에서 문서 보고 → 파라미터 맞춰서 요청 만들기
  • Dart/Flutter에서 HTTP 요청 → 데이터 받아서 Firestore에 저장

이런식으로 하면된다.

 


구체적인 방법

1. 공공데이터포털 접속

2. 회원가입, 로그인 진행

3. 활용신청 후 활용목적 쓰고 신청완료

 

데이터는 Dart 언어로 파일 하나만들어서 API 불러오고 파싱하는 코드 구현해서 콘솔로 돌려보겠다.

 

Error: 'SemanticsFlag' isn't a type.

콘솔 환경에 Flutter 전용 위젯이나 타입이 들어갔을 때 발생, 그냥 작업하던 프로젝트 안에서 돌리면 될까 해서 돌렸더니 이런 오류가 떴다. 

 

결론부터 말하면:

✔️ 새로운 Dart 콘솔 프로젝트로 분리하는 게 더 깔끔하고 안정적이야.
(데이터 수집은 백엔드처럼 별도 처리!)

라고 한다. UI는 읽어오기만 하면 되고, flutter 실행 속도도 느리거니와 ui 의존성도 달라서 데이터 불러오는건 새 프로젝트를 파서 거기에서 실행해봐야겠다.

 

터미널에

dart create -t console my_place_data_uploader
cd my_place_data_uploader

입력후 순수 dart 콘솔 생성

 

생긴 프로젝트 루트 디렉토리에 .env 파일 만들고 그 안에 이런 정보가 들어있어야 한다.

 

# 🔑 TourAPI 인증키
TOUR_API_KEY=여기_공공데이터포털에서_받은_키

# 🔥 Firebase Web 설정
FIREBASE_API_KEY=AIz...yourKey
FIREBASE_PROJECT_ID=myproject-id
FIREBASE_APP_ID=1:1234567890:web:abcdef123456
FIREBASE_AUTH_DOMAIN=myproject-id.firebaseapp.com
FIREBASE_STORAGE_BUCKET=myproject-id.appspot.com
FIREBASE_SENDER_ID=1234567890

 

난리 났다, dotenv 라이브러리 load, env 인식 오류 문제 해결나고나서 이번엔 FireStore가 문제라네.. firebase_dart안에 있다고 해서 import 바꿔보고 난리쳐보고 있다.

 

원인은 애초에 firebase_dart는 FireStore 지원 자체를 안했던 것이었다... (내 두시간이 ㅠㅠㅠㅠ)

library firebase_dart;

export 'implementation/pure_dart.dart' show FirebaseDart;
export 'auth.dart';
export 'database.dart';
export 'storage.dart';
export 'core.dart';

 

저 database가 RTDB(실시간 DB) 이다. 난 도대체 무슨 뻘짓을 하고있었던거지 ㅠㅠㅠㅠ

 

dart 콘솔에서 직접 FireStore를 쓸수 없으므로 REST 방식으로 저장해보기로 결정했다.

 

프로젝트 만들어뒀던것은 그대로 두고 bin 안에 있는 코드만 바꿨다.

import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:dotenv/dotenv.dart' as dotenv;

Future<void> main() async {
  final env = dotenv.DotEnv()..load();

  final projectId = env['FIREBASE_PROJECT_ID'];
  final apiKey = env['FIREBASE_API_KEY'];

  final url = Uri.parse(
    'https://firestore.googleapis.com/v1/projects/$projectId/databases/(default)/documents/places?key=$apiKey',
  );

  final place = {
    "fields": {
      "pname": {"stringValue": "대전엑스포과학공원"},
      "address": {"stringValue": "대전 유성구 엑스포로"},
      "place_photo": {"stringValue": "https://example.com/photo.jpg"},
      "location": {
        "mapValue": {
          "fields": {
            "lat": {"doubleValue": 36.3762},
            "lng": {"doubleValue": 127.3861}
          }
        }
      },
      "pmood": {
        "arrayValue": {
          "values": [
            {"stringValue": "자연"},
            {"stringValue": "힐링"}
          ]
        }
      },
      "created_at": {
        "timestampValue": DateTime.now().toUtc().toIso8601String()
      }
    }
  };

  final response = await http.post(
    url,
    headers: {'Content-Type': 'application/json'},
    body: jsonEncode(place),
  );

  if (response.statusCode == 200) {
    print('✅ 저장 완료!');
  } else {
    print('❌ 저장 실패: ${response.statusCode}');
    print(response.body);
  }
}

 

너허어ㅓㅓㅎ너어머ㅓㅁㅎ 드디어 저장됐다. 이제 이걸로 API 안의 정보들을 자동 크롤러 코드를 사용하여 반복해서 데려올거다.