옷장 앱 2편! 날씨를 기상청 공공 API로 갈아탔어요 — 하루 1만 건이라더니 429가 떴어요

개인용 날씨 옷장 웹앱 (2편). 공공데이터포털 신청부터 격자좌표·체감온도 직접 계산, 검증하다 만난 429 차단, 위치 자동 전환까지


🎯 바쁘시면 이것만 읽어도 돼요

  • 옷장 앱의 날씨 소스를 외국 API(OpenWeather)에서 기상청 단기예보(공공데이터포털)로 갈아탔어요. 개인 계정으로 신청하면 자동승인이라 키는 바로 나와요

  • 단순 교체가 아니었어요. 격자좌표 변환, 체감온도 직접 계산이 필요했고, 검증 중엔 "하루 1만 건"이라던 API가 몰아친 호출 십여 건에 429로 잠겼어요

  • 마무리로 위치 기반 지역 자동 전환까지 붙였는데, 코드보다 먼저 한 건 "예상되는 충돌 있어?"라고 물어본 거였어요

  • 이번 작업을 그대로 살려서, 이 앱을 개인용 24시간 서버에도 올릴 예정이에요!

👀 이런 분들께 도움돼요

  • 공공데이터포털 API가 신청부터 연동까지 실제로 어떤지 궁금한 분

  • 외국 날씨 API와 한국 기상청 API가 뭐가 다른지 궁금한 분

  • API 문서에 없는 제한(순간 호출량 같은)에 부딪혀본 분

  • 기능 추가 전에 AI한테 뭘 물어봐야 하는지 궁금한 분

😮 Before: 잘 돌아가던 앱의 날씨가 외국산이었어요

날씨 보고 옷 골라주는 개인 앱을 한동안 굴리고 있었어요. 원래 OT 과제로 시작한 앱인데, 그 뒤로도 계속 손보고 있고요 (이 앱을 만든 이야기는 따로 한 편에 있어요, 안 적은 걸 확인해서 덧붙이자면 원래는 GET/ ~~ 와 대시보드에서 시작한 작업이에요). 다만 날씨 소스가 외국 API라 우리나라 예보랑 미묘하게 다를 때가 있었고, 언젠가 기상청으로 바꾸고 싶다는 생각만 하고 있었죠. 그러다 스터디장님께서 공공데이터포털에 날씨 API가 있다고 알려주셔서, 그럼 한번 적용해보자 싶어 갈아타기로 했어요.

✨ After: 기상청 실황이 뜨고, 지역은 알아서 바뀌어요

지금은 앱을 열면 기상청 초단기실황 기준 날씨와 직접 계산한 체감온도가 떠요. 등록한 지역이 여러 개면, 지금 있는 곳에서 가장 가까운 지역으로 알아서 전환되고요. 갈아타는 김에 429 대응(순차 호출·재시도)까지 넣어서 오히려 전보다 튼튼해졌어요.

다양한 유형의 정보를 보여주는 웹사이트의 스크린샷

맨 위 날씨 카드가 기상청 실황이에요. 체감 30도는 앱이 직접 계산한 값이고, 옷은 데모 데이터예요.

🛠️ 이번에 바꾼 것 (배경 30초)

  1. 날씨 소스: OpenWeather → 기상청 단기예보 조회서비스 (현재 실황 + 예보 병합)

  2. 지역 표현: 도시 이름 → 기상청 격자좌표(nx, ny) 자동 변환 (전국 37개 시)

  3. 체감온도: API 제공값 → 기상청 공식으로 직접 계산 (겨울엔 바람, 여름엔 습도)

  4. 신기능: 브라우저 위치 기반 지역 자동 전환 (50km 이내, 수동 선택 우선)

🔨 과정: 검색 함정 → 좌표와 공식 → 429 → 자동 전환

1️⃣ '날씨 정보'를 검색하면 경마 기록이 나와요 (?)

공공데이터포털에서 "날씨 정보"를 검색했더니 태풍정보, 방사성폐기물처분장 기상데이터, 심지어 경마 경주 기록까지 떴어요. 정작 필요한 건 기상청 단기예보 조회서비스 하나였고요. 뭘 신청해야 하는지 아는 게 검색보다 중요하더라고요. 신청 자체는 싱거웠어요. 개인 계정으로 활용신청하면 자동승인이라 키가 바로 나와요. 사업자 등록 같은 건 필요 없어요.

키를 서버에 등록하는 단계에선 예상 못 한 복병이 있었어요. 지난 글 사고 때 만들어둔 보안 훅이 이번엔 저와 AI를 막아선 거예요. "민감 정보 노출 위험 명령어 차단됨"이라면서, .env가 들어간 명령은 파일 열기도 클립보드 복사도 전부 차단이라 결국 제가 터미널에 직접 쳤어요. 불편했는데, 이 불편함이 그날 사고의 보험료라고 생각하니 기분이 묘하더라고요.

2️⃣ 기상청은 도시 이름도, 체감온도도 안 받아줘요

연동을 시작하니 외국 API와 문법이 달랐어요. 기상청은 "부산"이 아니라 격자좌표(nx=98, ny=76)를 받아요. 위경도를 격자로 바꾸는 공식이 공개돼 있어서 그걸 넣고, 전국 37개 시를 등록했어요. 변환이 맞는지는 기상청 공식 좌표표와 대조해서 서울 60,127 / 부산 98,76이 정확히 나오는 걸 확인했고요.

체감온도는 한 번 더 손이 갔어요. 외국 API는 체감온도를 계산해서 주는데, 기상청은 기온·습도·풍속만 줘요. 그래서 기상청이 쓰는 공식(겨울엔 바람 반영, 여름엔 습도 반영)을 찾아서 직접 계산했어요. 검증해보니 기온 27.5도에 습도 75%면 체감 29.2도, 영하 5도에 바람 초속 5m면 체감 영하 11.2도가 나왔어요. 계절별로 공식이 갈리는 이유를 숫자로 체감했죠.

3️⃣ 😲 하이라이트: 하루 1만 건이라더니, 십여 건에 잠겼어요

교체를 끝내고 배포 전 검증을 돌리는데 이상한 장면이 나왔어요. 분명 기상청으로 바꿨는데 화면엔 옛날 외국 API 데이터가 그대로 떠 있는 거예요. 버그인가 싶어 코드를 다시 봤는데, 범인은 버그가 아니라 1시간 캐시였어요. 캐시가 안 지났으면 이전 데이터를 쓰는 게 설계였고, 캐시는 그냥 자기 일을 하고 있었던 거죠.

그럼 새 경로를 눈으로 확인해야 하니까, 캐시를 비우고 검증을 다시 돌렸어요. 여기서부터가 진짜였어요. 화면에 "이전 데이터 (갱신 실패)" 배지가 뜨고, 서버 로그엔 같은 줄이 반복돼 있었어요. "기상청 응답 429". 응답 본문은 더 직설적이었어요. "API rate limit exceeded".

예상이 뒤집힌 순간이었죠. 신청할 때 "일 10,000건"이라길래 하루 수십 건 쓰는 개인 앱엔 무한대나 다름없다고 생각했거든요. 그런데 검증하느라 짧은 시간에 십여 건을 몰아 보낸 게 별도의 순간 호출 제한에 걸린 거예요. 이 제한은 문서 어디에도 없었어요. 얼마나 지속되는지도 몰라서 30초 간격으로 재시도를 걸어두고 지켜봤더니, 5분쯤 지나서야 풀렸어요.

결말은 코드 보강이었어요. 실황과 예보를 동시에 쏘던 병렬 호출을 순차로 바꾸고, 429가 오면 1초, 3초 간격으로 재시도하게 했어요. 실사용에선 1시간 캐시 덕에 걸릴 일이 거의 없지만, 문서에 없는 제한은 부딪혀야 안다는 걸 확실히 배웠어요. 검증이 실패하는 순간에도 앱이 죽는 대신 "이전 데이터" 배지를 달고 버텼는데, 처음 만들 때 넣어둔 폴백 설계가 일한 거라 오히려 반가웠어요.

4️⃣ "자동 전환 붙여줘" 전에 충돌부터 물어봤어요

마지막으로 위치 기반 자동 전환을 붙였는데, 코드보다 먼저 "붙이기 전에 예상되는 충돌이나 에러 있어?"라고 물어봤어요. 그랬더니 진짜 문제 목록이 나왔어요. 드롭다운으로 서울을 골랐는데 GPS가 부산으로 되돌리면 앱과 사용자가 계속 싸운다, 대전에 있는데 등록 지역이 부산·서울뿐이면 160km 밖 서울로 점프한다, 같은 것들요.

그래서 규칙 세 개를 정하고 시작했어요. 첫 진입에만 자동 전환, 직접 고르면 자동은 물러나기, 50km 이내일 때만 전환. 위치 좌표는 브라우저 안에서만 계산하고 서버로는 지역 이름만 가는 것도 확인했고요. 규칙을 먼저 합의하니 구현은 한 번에 끝났어요.

한국사이트 스크린샷

여기에 지역을 여러 개 넣어두면, 첫 진입 때 가장 가까운 곳으로 알아서 바뀌어요.

📊 결과: 숫자로 보면

항목

숫자

지원 지역

전국 37개 시 (격자좌표 자동 변환)

하루 API 호출

최대 수십 건 (1시간 캐시, 한도는 1만 건)

429 차단 지속

약 5분 (몰아친 호출 십여 건에 발동)

429 대응

병렬 → 순차 호출 + 1초·3초 재시도

체감온도 검증

27.5°C·습도 75% → 29.2°C / -5°C·바람 5m/s → -11.2°C

위치 자동 전환 기준

등록 지역 50km 이내, 수동 선택 우선

💡 효과적이었던 것

  • 기능을 붙이기 전에 충돌부터 물어봤어요. 요구사항을 코드로 받기 전에 위험 목록으로 먼저 받으니, 자동 전환처럼 꼬이기 쉬운 기능도 재작업 없이 자리잡았어요!

  • 배포 전 스크린샷 검증 게이트를 뒀어요. 빌드 통과와 화면 정상은 다른 문제라, 캐시 착시도 429 배지도 전부 스크린샷에서 눈으로 잡았어요!

  • API가 잠겨도 앱은 이전 데이터로 버텼어요. 이건 처음 만들 때 넣어둔 폴백 설계라, 장애가 난 그날 급하게 할 수 있는 일이 아니었어요!

⚠️ 이런 건 아쉬웠어요

  • 공공데이터포털 검색이 좀 험해요. 키워드 검색보다 "단기예보 조회서비스"라는 정답 이름을 아는 게 빨라요

  • 순간 호출 제한은 문서에 없어요. 일 한도만 믿고 검증을 몰아 돌리면 저처럼 5분씩 기다리게 돼요. 꼭 확인할 것.

📋 따라하려면

  1. 공공데이터포털 가입(개인 계정 OK) → "기상청_단기예보 조회서비스" 활용신청 → 자동승인 키 발급

  2. 키는 Decoding 버전을 서버 전용 환경변수로 넣으세요. 브라우저에 노출되면 안 돼요

  3. 도시 이름 → 격자좌표(nx, ny) 변환식을 넣고, 공식 좌표표와 대조해 검증하세요

  4. 체감온도가 필요하면 기상청 공식으로 직접 계산해요 (겨울·여름 공식이 달라요)

  5. 호출은 순차로, 429엔 재시도로, 그리고 캐시는 꼭 두세요. 몰아 보내면 잠겨요

지피터스 뉴스레터

이번 주 AI, 딱 쓸 것만

매주 월요일 아침,
읽고 바로 써먹을 AI 소식만