mirror of
https://github.com/NomaDamas/k-skill.git
synced 2026-06-24 02:04:11 +00:00
✨ feat: 생활쓰레기 조회 스킬 및 프록시 라우트 구현
생활쓰레기 조회 스킬 문서와 기능 가이드를 추가하고, 프록시 라우트를 구현해 조회 흐름을 완성했다. 설치/설정 문서도 스킬 사용 흐름에 맞게 정리했다. Made-with: Cursor
This commit is contained in:
parent
79dacba05a
commit
bcd32ac7cc
7 changed files with 276 additions and 2 deletions
|
|
@ -26,6 +26,7 @@ Claude Code, Codex, OpenCode, OpenClaw/ClawHub 등 각종 코딩 에이전트
|
|||
| 한강 수위 정보 조회 | self-host 또는 배포 확인이 끝난 `k-skill-proxy` 경유로 관측소 기준 현재 수위·유량·기준수위 확인 | 프록시 URL 필요 | [한강 수위 정보 가이드](docs/features/han-river-water-level.md) |
|
||||
| 한국 법령 검색 | `korean-law-mcp` 우선 + 장애 시 `법망` fallback으로 법령/조문/판례/유권해석 조회 | 로컬 CLI/MCP면 `LAW_OC` 필요, remote endpoint/법망 fallback은 불필요 | [한국 법령 검색 가이드](docs/features/korean-law-search.md) |
|
||||
| 한국 부동산 실거래가 조회 | upstream `real-estate-mcp`로 아파트/오피스텔/빌라/단독주택 실거래가·전월세·지역코드 조회, hosted endpoint가 없으면 self-host + Cloudflare Tunnel + launchd 운영 | 로컬/stdio/self-host면 `DATA_GO_KR_API_KEY` 필요 | [한국 부동산 실거래가 조회 가이드](docs/features/real-estate-search.md) |
|
||||
| 생활쓰레기 배출정보 조회 | 행정안전부 생활쓰레기배출정보 원본 endpoint 스펙으로 조회하고 `serviceKey`는 proxy 서버에서 주입해 시군구 기준 배출장소/배출방법/배출요일·시간 안내 | 불필요 (proxy 서버에서 `DATA_GO_KR_API_KEY` 주입) | [생활쓰레기 배출정보 조회 가이드](docs/features/household-waste-info.md) |
|
||||
| 조선왕조실록 검색 | 공식 조선왕조실록 사이트에서 키워드 검색 후 왕별/연도별 필터와 기사 excerpt 조회 | 불필요 | [조선왕조실록 검색 가이드](docs/features/joseon-sillok-search.md) |
|
||||
| 근처 가장 싼 주유소 찾기 | 현재 위치를 먼저 확인한 뒤 Kakao Map anchor + Opinet 공식 API로 근처 최저가 주유소 조회 | `OPINET_API_KEY` 필요 | [근처 가장 싼 주유소 찾기 가이드](docs/features/cheap-gas-nearby.md) |
|
||||
| KBO 경기 결과 조회 | 날짜별 경기 일정, 결과, 팀별 필터링 | 불필요 | [KBO 결과 가이드](docs/features/kbo-results.md) |
|
||||
|
|
@ -75,6 +76,7 @@ Claude Code, Codex, OpenCode, OpenClaw/ClawHub 등 각종 코딩 에이전트
|
|||
- [한강 수위 정보 가이드](docs/features/han-river-water-level.md)
|
||||
- [한국 법령 검색 가이드](docs/features/korean-law-search.md)
|
||||
- [한국 부동산 실거래가 조회 가이드](docs/features/real-estate-search.md)
|
||||
- [생활쓰레기 배출정보 조회 가이드](docs/features/household-waste-info.md)
|
||||
- [조선왕조실록 검색 가이드](docs/features/joseon-sillok-search.md)
|
||||
- [근처 가장 싼 주유소 찾기 가이드](docs/features/cheap-gas-nearby.md)
|
||||
- [KBO 경기 결과 조회](docs/features/kbo-results.md)
|
||||
|
|
|
|||
55
docs/features/household-waste-info.md
Normal file
55
docs/features/household-waste-info.md
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
# 생활쓰레기 배출정보 조회 가이드
|
||||
|
||||
## 이 기능으로 할 수 있는 일
|
||||
|
||||
- 시군구 기준 생활쓰레기 배출요일/시간 조회
|
||||
- 음식물쓰레기/재활용품 배출방법 조회
|
||||
- 배출장소, 미수거일, 관리부서 연락처 확인
|
||||
- 공공데이터 원본 endpoint 스펙 기준 조회 + API 키는 프록시 주입
|
||||
|
||||
## 가장 중요한 규칙
|
||||
|
||||
Base URL은 `https://apis.data.go.kr/1741000/household_waste_info` 이다.
|
||||
사용자는 `DATA_GO_KR_API_KEY`를 직접 들고 있지 않고, `serviceKey`는 proxy 서버에서만 주입한다.
|
||||
|
||||
## 먼저 필요한 것
|
||||
|
||||
- 인터넷 연결
|
||||
- 원본 API 접근 가능 환경
|
||||
- API 키 주입용 proxy 접근 가능 환경
|
||||
|
||||
## 기본 조회 예시
|
||||
|
||||
```bash
|
||||
curl -fsS --get 'https://apis.data.go.kr/1741000/household_waste_info/info' \
|
||||
--data-urlencode 'serviceKey=${INJECTED_BY_PROXY}' \
|
||||
--data-urlencode 'returnType=json' \
|
||||
--data-urlencode 'pageNo=1' \
|
||||
--data-urlencode 'numOfRows=20' \
|
||||
--data-urlencode 'cond[SGG_NM::LIKE]=강남구'
|
||||
```
|
||||
|
||||
## 조회 흐름 권장 순서
|
||||
|
||||
1. 사용자에게 시/군/구를 먼저 확인한다.
|
||||
2. 입력이 모호하면 상위 행정구역을 포함해 재질문한다.
|
||||
3. `/info` endpoint 스펙으로 조회하고 `serviceKey`는 proxy 주입을 사용한다.
|
||||
4. 배출장소/요일/시간/미수거일/문의처를 3~6개 포인트로 요약한다.
|
||||
5. 결과가 여러 건이면 최신 `DAT_UPDT_PNT` 기준으로 우선 정렬해 보여준다.
|
||||
|
||||
## 자주 보는 필드
|
||||
|
||||
- `SGG_NM`: 시군구명
|
||||
- `MNG_ZONE_NM`, `MNG_ZONE_TRGT_RGN_NM`: 관리구역/대상지역
|
||||
- `EMSN_PLC`, `EMSN_PLC_TYPE`: 배출장소/유형
|
||||
- `LF_WST_EMSN_MTHD`, `FOD_WST_EMSN_MTHD`, `RCYCL_EMSN_MTHD`: 배출방법
|
||||
- `LF_WST_EMSN_DOW`, `FOD_WST_EMSN_DOW`, `RCYCL_EMSN_DOW`: 배출요일
|
||||
- `LF_WST_EMSN_BGNG_TM`, `LF_WST_EMSN_END_TM`: 생활쓰레기 배출시간
|
||||
- `UNCLLT_DAY`: 미수거일
|
||||
- `MNG_DEPT_NM`, `MNG_DEPT_TELNO`: 담당부서/연락처
|
||||
|
||||
## 참고 링크
|
||||
|
||||
- 공식 데이터 출처: 공공데이터포털 (`https://www.data.go.kr`)
|
||||
- upstream API: `https://apis.data.go.kr/1741000/household_waste_info/info`
|
||||
- 프록시 역할: 인증키(`DATA_GO_KR_API_KEY`) 서버 측 주입/보호
|
||||
|
|
@ -53,6 +53,7 @@ npx --yes skills add <owner/repo> \
|
|||
--skill kakaotalk-mac \
|
||||
--skill korean-law-search \
|
||||
--skill real-estate-search \
|
||||
--skill household-waste-info \
|
||||
--skill joseon-sillok-search \
|
||||
--skill cheap-gas-nearby \
|
||||
--skill fine-dust-location \
|
||||
|
|
@ -99,6 +100,8 @@ korean-law list
|
|||
|
||||
`real-estate-search` 는 별도 설치 없이 기본 hosted proxy(`k-skill-proxy.nomadamas.org`)를 통해 바로 사용할 수 있다. 사용자 쪽 `DATA_GO_KR_API_KEY` 가 불필요하다. 원본 참고: `https://github.com/tae0y/real-estate-mcp/tree/main`. 자세한 사용법은 [한국 부동산 실거래가 조회 가이드](features/real-estate-search.md)를 본다.
|
||||
|
||||
`household-waste-info` 는 원본 API(`apis.data.go.kr/1741000/household_waste_info`) endpoint 스펙으로 호출하고, `serviceKey`(`DATA_GO_KR_API_KEY`)만 proxy 서버에서 주입해 사용한다. 사용자 쪽 `DATA_GO_KR_API_KEY` 가 불필요하다. 자세한 사용법은 [생활쓰레기 배출정보 조회 가이드](features/household-waste-info.md)를 본다.
|
||||
|
||||
### `olive-young-search` upstream CLI quickstart
|
||||
|
||||
`olive-young-search` 는 upstream 원본 [`hmmhmmhm/daiso-mcp`](https://github.com/hmmhmmhm/daiso-mcp) / npm package [`daiso`](https://www.npmjs.com/package/daiso) 를 그대로 사용한다.
|
||||
|
|
@ -216,6 +219,7 @@ python3 scripts/korean_spell_check.py --text "아버지가방에들어가신다.
|
|||
- `fine-dust-location`
|
||||
- `korean-law-search`
|
||||
- `real-estate-search`
|
||||
- `household-waste-info`
|
||||
- `cheap-gas-nearby`
|
||||
|
||||
관련 문서:
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ AIR_KOREA_OPEN_API_KEY=replace-me
|
|||
KSKILL_PROXY_BASE_URL=https://your-proxy.example.com
|
||||
```
|
||||
|
||||
서울 지하철 도착정보는 hosted public route rollout 이 끝나기 전까지 self-host 또는 배포 확인이 끝난 proxy URL 만 넣는다. 미세먼지, 한강 수위, 주유소 가격은 기본 hosted proxy(`k-skill-proxy.nomadamas.org`)를 쓰므로 사용자 쪽 키가 불필요하다.
|
||||
서울 지하철 도착정보는 hosted public route rollout 이 끝나기 전까지 self-host 또는 배포 확인이 끝난 proxy URL 만 넣는다. 미세먼지, 한강 수위, 주유소 가격은 기본 hosted proxy(`k-skill-proxy.nomadamas.org`)를 쓰므로 사용자 쪽 키가 불필요하다. 생활쓰레기 배출정보는 원본 API endpoint를 쓰되 `serviceKey`만 proxy 서버에서 주입하므로 사용자 쪽 키가 불필요하다.
|
||||
|
||||
## Missing secret handling policy
|
||||
|
||||
|
|
@ -64,6 +64,6 @@ KSKILL_PROXY_BASE_URL=https://your-proxy.example.com
|
|||
- `AIR_KOREA_OPEN_API_KEY`
|
||||
- `KSKILL_PROXY_BASE_URL`
|
||||
|
||||
`LAW_OC` 는 `korean-law-mcp` 가 법제처 Open API 를 호출할 때 쓰는 표준 변수명이다. 이 값은 로컬 CLI/로컬 MCP server 경로에서만 사용자 쪽에 필요하고, upstream remote MCP endpoint 예시는 사용자 `LAW_OC` 없이 `url`만 등록한다. `DATA_GO_KR_API_KEY` 는 프록시 운영자 문맥에서만 서버에 넣는다. 부동산 실거래가 조회는 기본 hosted proxy(`k-skill-proxy.nomadamas.org`)를 경유하므로 사용자 쪽 키가 불필요하다. 근처 가장 싼 주유소 찾기는 기본 hosted proxy를 경유하므로 사용자 쪽 `OPINET_API_KEY` 가 불필요하다. `OPINET_API_KEY` 는 프록시 운영자 문맥에서만 서버에 넣는다. public 공유용 Cloudflare Tunnel/Auth0/operator secret은 사용자 기본 secrets 파일에 넣지 않는다. 프록시 운영자 문맥에서는 upstream 환경변수 `SEOUL_OPEN_API_KEY`, `AIR_KOREA_OPEN_API_KEY`, `HRFCO_OPEN_API_KEY`, `OPINET_API_KEY`, `DATA_GO_KR_API_KEY` 를 사용할 수 있다. 다만 일반 사용자/client 쪽 기본 secrets 파일에는 넣지 않는다. `KSKILL_PROXY_BASE_URL` 은 서울 지하철 route가 실제 배포된 proxy URL 로만 넣는다. 미세먼지, 한강 수위, 주유소 가격은 이 값이 없으면 기본 hosted path(`k-skill-proxy.nomadamas.org`)를 사용한다.
|
||||
`LAW_OC` 는 `korean-law-mcp` 가 법제처 Open API 를 호출할 때 쓰는 표준 변수명이다. 이 값은 로컬 CLI/로컬 MCP server 경로에서만 사용자 쪽에 필요하고, upstream remote MCP endpoint 예시는 사용자 `LAW_OC` 없이 `url`만 등록한다. `DATA_GO_KR_API_KEY` 는 프록시 운영자 문맥에서만 서버에 넣는다. 부동산 실거래가 조회는 기본 hosted proxy(`k-skill-proxy.nomadamas.org`)를 경유하고, 생활쓰레기 배출정보 조회는 원본 API endpoint를 쓰되 `serviceKey`를 proxy 서버에서 주입하므로 사용자 쪽 키가 불필요하다. 근처 가장 싼 주유소 찾기는 기본 hosted proxy를 경유하므로 사용자 쪽 `OPINET_API_KEY` 가 불필요하다. `OPINET_API_KEY` 는 프록시 운영자 문맥에서만 서버에 넣는다. public 공유용 Cloudflare Tunnel/Auth0/operator secret은 사용자 기본 secrets 파일에 넣지 않는다. 프록시 운영자 문맥에서는 upstream 환경변수 `SEOUL_OPEN_API_KEY`, `AIR_KOREA_OPEN_API_KEY`, `HRFCO_OPEN_API_KEY`, `OPINET_API_KEY`, `DATA_GO_KR_API_KEY` 를 사용할 수 있다. 다만 일반 사용자/client 쪽 기본 secrets 파일에는 넣지 않는다. `KSKILL_PROXY_BASE_URL` 은 서울 지하철 route가 실제 배포된 proxy URL 로만 넣는다. 미세먼지, 한강 수위, 주유소 가격은 이 값이 없으면 기본 hosted path(`k-skill-proxy.nomadamas.org`)를 사용한다.
|
||||
|
||||
이 레포의 credential-bearing skill은 전부 이 정책을 전제로 작성한다. 자세한 공통 설치 절차는 [공통 설정 가이드](setup.md)를 본다.
|
||||
|
|
|
|||
126
household-waste-info/SKILL.md
Normal file
126
household-waste-info/SKILL.md
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
---
|
||||
name: household-waste-info
|
||||
description: Use when the user asks for 생활쓰레기 배출 요일/시간/장소 정보 by 지역명(시군구) and wants official data.go.kr household waste guidance.
|
||||
license: MIT
|
||||
metadata:
|
||||
category: utility
|
||||
locale: ko-KR
|
||||
phase: v1
|
||||
---
|
||||
|
||||
# Household Waste Info
|
||||
|
||||
## What this skill does
|
||||
|
||||
행정안전부 생활쓰레기배출정보 Open API를 조회해
|
||||
지역별 생활쓰레기/음식물쓰레기/재활용품 배출 기준과 요일/시간 정보를 안내한다.
|
||||
|
||||
- 기본 조회 단위는 시군구명(`SGG_NM`)이다.
|
||||
- 응답은 사용자에게 이해하기 쉬운 요약 형태로 정리한다.
|
||||
- Base URL은 원본 API(`https://apis.data.go.kr/1741000/household_waste_info`)를 기준으로 한다.
|
||||
- `serviceKey`(`DATA_GO_KR_API_KEY`)만 proxy 서버에서 주입/관리한다.
|
||||
|
||||
## When to use
|
||||
|
||||
- "강남구 쓰레기 배출 요일 알려줘"
|
||||
- "우리 동네 음식물쓰레기 언제 버려?"
|
||||
- "재활용품 배출 시간 확인해줘"
|
||||
- "생활쓰레기 배출 장소/방법 찾아줘"
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- 인터넷 연결
|
||||
- `curl`, `python3` 사용 가능 환경
|
||||
- 원본 API 접근 가능 환경
|
||||
- API 키 주입용 proxy 접근 가능 환경
|
||||
|
||||
## Credential requirements
|
||||
|
||||
기본적으로 사용자 측 필수 인증키는 없다.
|
||||
|
||||
선택 환경변수:
|
||||
|
||||
- `KSKILL_PROXY_BASE_URL` (self-hosted proxy를 쓸 때)
|
||||
|
||||
인증키 사용 원칙:
|
||||
|
||||
1. endpoint/파라미터 체계는 원본 API를 따른다.
|
||||
2. `serviceKey` 값은 proxy 서버가 관리하고 주입한다.
|
||||
3. 사용자 측 로컬 환경에 `DATA_GO_KR_API_KEY`를 둘 필요가 없다.
|
||||
|
||||
## Official API surface
|
||||
|
||||
- Base URL: `https://apis.data.go.kr/1741000/household_waste_info`
|
||||
- Endpoint: `GET /info`
|
||||
- (key injection only) proxy: `k-skill-proxy`가 `serviceKey`를 서버 측에서 주입
|
||||
|
||||
## Default path
|
||||
|
||||
추가 client API 레이어는 불필요하다. Base URL은 원본 API를 기준으로 유지한다.
|
||||
|
||||
핵심 쿼리 파라미터:
|
||||
|
||||
- `serviceKey`: proxy가 서버 측에서 주입하는 인증키 (`DATA_GO_KR_API_KEY`)
|
||||
- `pageNo`: 페이지 번호
|
||||
- `numOfRows`: 페이지 크기(최대 100)
|
||||
- `returnType`: `json` 권장
|
||||
- `cond[SGG_NM::LIKE]`: 시군구명 포함 검색
|
||||
- `cond[DAT_CRTR_YMD::GTE]`, `cond[DAT_CRTR_YMD::LT]`: 데이터 기준일 필터
|
||||
- `cond[DAT_UPDT_PNT::GTE]`, `cond[DAT_UPDT_PNT::LT]`: 갱신시점 필터
|
||||
|
||||
## Workflow
|
||||
|
||||
### 1) Ask location first
|
||||
|
||||
사용자 지역 정보 없이 바로 조회하지 않는다.
|
||||
|
||||
- 권장 질문: `확인할 지역(시/군/구)을 알려주세요. 예: 강남구, 수원시 영통구`
|
||||
|
||||
### 2) Validate input and resolve query
|
||||
|
||||
- 시군구 입력이 비어 있으면 다시 물어본다.
|
||||
- 모호한 입력이면 상위 행정구역 포함 형태로 재질문한다.
|
||||
|
||||
### 3) Call via proxy (serviceKey injected server-side)
|
||||
|
||||
proxy가 `serviceKey`를 서버 측에서 주입한 뒤 원본 API로 전달한다.
|
||||
|
||||
```bash
|
||||
curl -fsS --get 'https://k-skill-proxy.nomadamas.org/v1/household-waste/info' \
|
||||
--data-urlencode "returnType=json" \
|
||||
--data-urlencode "pageNo=1" \
|
||||
--data-urlencode "numOfRows=20" \
|
||||
--data-urlencode "cond[SGG_NM::LIKE]=강남구"
|
||||
```
|
||||
|
||||
`KSKILL_PROXY_BASE_URL`이 있으면 그 값을 사용하고, 없으면 기본 hosted proxy(`k-skill-proxy.nomadamas.org`)를 사용한다.
|
||||
|
||||
### 4) Summarize for user
|
||||
|
||||
응답에서 필요한 항목만 간단히 정리한다.
|
||||
|
||||
- 관리구역/대상지역 (`MNG_ZONE_NM`, `MNG_ZONE_TRGT_RGN_NM`)
|
||||
- 배출장소/배출방법 (`EMSN_PLC`, `LF_WST_EMSN_MTHD`, `FOD_WST_EMSN_MTHD`, `RCYCL_EMSN_MTHD`)
|
||||
- 배출요일/시간 (`LF_WST_EMSN_DOW`, `FOD_WST_EMSN_DOW`, `RCYCL_EMSN_DOW`, 각 시작/종료시간)
|
||||
- 미수거일 (`UNCLLT_DAY`)
|
||||
- 문의처 (`MNG_DEPT_NM`, `MNG_DEPT_TELNO`)
|
||||
|
||||
## Done when
|
||||
|
||||
- 사용자 지역(시군구)을 확인했다.
|
||||
- 원본 endpoint 호출 스펙으로 조회에 성공했다.
|
||||
- 배출 요일/시간/장소를 3~6개 핵심 포인트로 요약해 안내했다.
|
||||
|
||||
## Failure modes
|
||||
|
||||
- 프록시 서버에 `DATA_GO_KR_API_KEY`가 없거나 만료된 경우 (`serviceKey` 주입 실패)
|
||||
- 검색 지역명이 API 데이터와 불일치하여 결과가 비는 경우
|
||||
- 공공데이터 API 일시 장애/트래픽 제한
|
||||
- 필수 파라미터 누락(`pageNo`, `numOfRows`)
|
||||
|
||||
## Notes
|
||||
|
||||
- 사용자 측에 `DATA_GO_KR_API_KEY`를 저장하지 않고 proxy 서버에서만 관리한다.
|
||||
- API raw payload를 그대로 노출하지 말고 사용자 친화적으로 요약한다.
|
||||
- 응답이 여러 건이면 최신 `DAT_UPDT_PNT` 기준으로 우선 정렬해 보여준다.
|
||||
- 공식 데이터 출처: 공공데이터포털 (`https://www.data.go.kr`)
|
||||
|
|
@ -82,6 +82,8 @@ chmod 0600 ~/.config/k-skill/secrets.env
|
|||
|
||||
한국 부동산 실거래가 조회는 기본 hosted proxy(`k-skill-proxy.nomadamas.org`)를 경유하므로 사용자 쪽 `DATA_GO_KR_API_KEY` 가 불필요하다.
|
||||
|
||||
생활쓰레기 배출정보 조회는 원본 API endpoint 스펙을 사용하되, `serviceKey`(`DATA_GO_KR_API_KEY`)는 proxy 서버에서 주입/관리하므로 사용자 쪽 `DATA_GO_KR_API_KEY` 가 불필요하다.
|
||||
|
||||
근처 가장 싼 주유소 찾기는 기본 hosted proxy를 경유하므로 사용자 쪽 `OPINET_API_KEY` 가 불필요하다.
|
||||
|
||||
|
||||
|
|
@ -96,6 +98,7 @@ chmod 0600 ~/.config/k-skill/secrets.env
|
|||
- 로컬 한국 법령 검색: `LAW_OC` + `korean-law-mcp`
|
||||
- 한국 법령 검색 remote endpoint: 사용자 `LAW_OC` 없이 `url`만 등록, 장애 시 `법망` fallback
|
||||
- 한국 부동산 실거래가 조회: 사용자 시크릿 불필요 (기본 hosted proxy 사용)
|
||||
- 생활쓰레기 배출정보 조회: 사용자 시크릿 불필요 (`serviceKey`는 proxy 서버 주입)
|
||||
- 근처 가장 싼 주유소 찾기: 사용자 시크릿 불필요 (기본 hosted proxy 사용)
|
||||
- 서울 지하철: self-host 또는 배포 확인이 끝난 `KSKILL_PROXY_BASE_URL`
|
||||
- 사용자 위치 미세먼지 조회: `KSKILL_PROXY_BASE_URL` 또는 `AIR_KOREA_OPEN_API_KEY`
|
||||
|
|
|
|||
|
|
@ -993,6 +993,90 @@ function buildServer({ env = process.env, provider = null } = {}) {
|
|||
return payload;
|
||||
});
|
||||
|
||||
app.get("/v1/household-waste/info", async (request, reply) => {
|
||||
const query = request.query || {};
|
||||
const sggNm = query["cond[SGG_NM::LIKE]"];
|
||||
|
||||
if (!sggNm || !sggNm.trim()) {
|
||||
reply.code(400);
|
||||
return {
|
||||
error: "bad_request",
|
||||
message: "cond[SGG_NM::LIKE] is required"
|
||||
};
|
||||
}
|
||||
|
||||
const pageNo = query.pageNo || "1";
|
||||
const numOfRows = query.numOfRows || "20";
|
||||
const returnType = query.returnType || "json";
|
||||
|
||||
const cacheKey = makeCacheKey({
|
||||
route: "household-waste-info",
|
||||
sggNm: sggNm.trim(),
|
||||
pageNo,
|
||||
numOfRows
|
||||
});
|
||||
const cached = cache.get(cacheKey);
|
||||
if (cached) {
|
||||
return {
|
||||
...cached,
|
||||
proxy: {
|
||||
...cached.proxy,
|
||||
cache: { hit: true, ttl_ms: config.cacheTtlMs }
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (!config.molitApiKey) {
|
||||
reply.code(503);
|
||||
return {
|
||||
error: "upstream_not_configured",
|
||||
message: "DATA_GO_KR_API_KEY is not configured on the proxy server.",
|
||||
proxy: { name: config.proxyName, cache: { hit: false, ttl_ms: config.cacheTtlMs } }
|
||||
};
|
||||
}
|
||||
|
||||
const url = new URL("https://apis.data.go.kr/1741000/household_waste_info/info");
|
||||
url.searchParams.set("serviceKey", config.molitApiKey);
|
||||
url.searchParams.set("pageNo", pageNo);
|
||||
url.searchParams.set("numOfRows", numOfRows);
|
||||
url.searchParams.set("returnType", returnType);
|
||||
url.searchParams.set("cond[SGG_NM::LIKE]", sggNm.trim());
|
||||
|
||||
let upstreamData;
|
||||
try {
|
||||
const res = await fetch(url.toString());
|
||||
if (!res.ok) {
|
||||
reply.code(502);
|
||||
return {
|
||||
error: "upstream_error",
|
||||
message: `Upstream responded with ${res.status}`,
|
||||
proxy: { name: config.proxyName, cache: { hit: false, ttl_ms: config.cacheTtlMs } }
|
||||
};
|
||||
}
|
||||
upstreamData = await res.json();
|
||||
} catch (err) {
|
||||
reply.code(502);
|
||||
return {
|
||||
error: "upstream_fetch_failed",
|
||||
message: err.message,
|
||||
proxy: { name: config.proxyName, cache: { hit: false, ttl_ms: config.cacheTtlMs } }
|
||||
};
|
||||
}
|
||||
|
||||
const payload = {
|
||||
...upstreamData,
|
||||
query: { sgg_nm: sggNm.trim(), page_no: pageNo, num_of_rows: numOfRows },
|
||||
proxy: {
|
||||
name: config.proxyName,
|
||||
cache: { hit: false, ttl_ms: config.cacheTtlMs },
|
||||
requested_at: new Date().toISOString()
|
||||
}
|
||||
};
|
||||
|
||||
cache.set(cacheKey, payload, config.cacheTtlMs);
|
||||
return payload;
|
||||
});
|
||||
|
||||
app.setErrorHandler((error, request, reply) => {
|
||||
request.log.error(error);
|
||||
const statusCode = error.statusCode && error.statusCode >= 400 ? error.statusCode : 500;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue