malgleam (맑을림)

Package Version Hex Docs

기상청 Open API 3종의 타입 안전 Gleam 래퍼. Erlang/JavaScript 양쪽 타겟 지원.

gleam add malgleam@1

왜 malgleam인가?

기상청 API를 직접 호출하려면 격자 변환 공식, 카테고리 코드표, 지역번호 목록, XML/JSON 파싱을 모두 직접 처리해야 합니다. malgleam은 이 모든 번거로움을 타입 시스템 뒤에 숨깁니다.

직접 호출 시malgleam 사용 시
서울 위경도를 Lambert Conformal Conic 공식으로 격자 변환location.seoul
"T1H", "PTY", "SKY" 코드표 참조obs.temperature, obs.precipitation_type
하늘상태 "1" → 맑음 매핑case obs { Clear -> ... }
중기육상예보 구역코드 "11B00000" 조회region.land_seoul_incheon_gyeonggi
생활기상지수 행정구역코드 "1100000000" 조회area.seoul
URL 조립 + JSON 파싱 + 에러코드 처리요청 빌더 + 디코더가 전부 처리

빠른 시작

서울의 현재 날씨

import malgleam/short_term
import malgleam/location
import gleam/httpc

let request = short_term.ultra_srt_ncst(
  service_key: "my-service-key",
  location: location.seoul,
  base_date: "20240701",
  base_time: "0600",
)
let assert Ok(response) = httpc.send(request)
let assert Ok(obs) = short_term.decode_ultra_srt_ncst(response)

obs.temperature         // 24.5 (℃)
obs.humidity            // 78 (%)
obs.precipitation_type  // NoPrecipitation
obs.wind_direction      // W (16방위)
obs.wind_speed          // 2.1 (m/s)

8개 관측 카테고리(T1H, RN1, UUU, VVV, REH, PTY, VEC, WSD)가 의미 있는 필드명의 단일 레코드로 반환됩니다.

위경도로 위치 지정

let busan = location.from_coords(lat: 35.1796, lng: 129.0756)
let request = short_term.vilage_fcst(
  service_key: "my-key",
  location: busan,
  base_date: "20240701",
  base_time: "0500",
)

Lambert Conformal Conic 격자 변환이 자동으로 처리됩니다.

단기예보 해석

let assert Ok(items) = short_term.decode_vilage_fcst(response)

// 시간별 그룹핑
let groups = short_term.group_by_time(items)
// [#("20240701", "0600", [TMP항목, SKY항목, ...]),
//  #("20240701", "0900", [...]), ...]

// 개별 아이템 해석
short_term.parse_sky(sky_item)             // Ok(Clear)
short_term.parse_float_value(tmp_item)     // Ok(25.0)
short_term.parse_wind_direction(vec_item)  // Ok(S)

중기예보

import malgleam/mid_term
import malgleam/region

let request = mid_term.mid_land_fcst(
  service_key: "my-key",
  region: region.land_seoul_incheon_gyeonggi,
  forecast_time: "202407010600",
)
let assert Ok(response) = httpc.send(request)
let assert Ok(forecast) = mid_term.decode_mid_land_fcst(response)

// days 4~7은 AM/PM, days 8~10은 하루 단위
list.each(forecast.days, fn(day) {
  case day.weather_am {
    Some(MidClear) -> "오전 맑음"
    Some(MidOvercastWithRain) -> "오전 비"
    _ -> "..."
  }
})

지역 코드를 외울 필요가 없습니다. 잘못된 코드 타입은 컴파일 타임에 차단됩니다.

// OK: mid_land_fcst에 LandRegionId 전달
mid_term.mid_land_fcst(key, region.land_seoul_incheon_gyeonggi, time)

// 컴파일 에러: SeaRegionId는 mid_land_fcst에 전달 불가
mid_term.mid_land_fcst(key, region.sea_west_central, time)

생활기상지수

import malgleam/living_index
import malgleam/area

let request = living_index.uv_idx(
  service_key: "my-key",
  area: area.seoul,
  time: "2024070618",
)
let assert Ok(response) = httpc.send(request)
let assert Ok(uv) = living_index.decode_uv_idx(response)

uv.tomorrow  // Some(8) — 내일 자외선지수 매우높음

시간별 지수 조회:

let assert Ok(freeze) = living_index.decode_freeze_idx(response)
living_index.find_hourly(freeze.hourly, 6)  // Some(75) — 6시간 후 동파 위험 높음

선택 파라미터는 파이프라인으로

let request = short_term.vilage_fcst(key, location.seoul, "20240701", "0500")
  |> short_term.with_rows(100)
  |> short_term.with_page(2)

지원 엔드포인트 (12개)

단기예보 (malgleam/short_term)

함수API설명반환 타입
ultra_srt_ncstgetUltraSrtNcst초단기실황Observation
ultra_srt_fcstgetUltraSrtFcst초단기예보List(ForecastItem)
vilage_fcstgetVilageFcst단기예보List(ForecastItem)
fcst_versiongetFcstVersion예보버전List(ForecastVersion)

중기예보 (malgleam/mid_term)

함수API설명반환 타입
mid_fcstgetMidFcst중기전망MidOutlook
mid_land_fcstgetMidLandFcst중기육상예보MidLandForecast
mid_tagetMidTa중기기온MidTempForecast
mid_sea_fcstgetMidSeaFcst중기해상예보MidSeaForecast

생활기상지수 (malgleam/living_index)

함수API설명반환 타입
freeze_idxgetFreezeIdxV2동파가능지수FreezeIndex
uv_idxgetUVIdxV2자외선지수UvIndex
air_diffusion_idxgetAirDiffusionIdxV2대기확산지수AirDiffusionIndex
sen_ta_idxgetSenTaIdxV2체감온도SensibleTemperature

설계 원칙

HTTP 클라이언트 독립

모든 요청 빌더는 gleam/http/request.Request(String)를 반환합니다. HTTP 클라이언트를 자유롭게 선택할 수 있습니다.

Result 기반 에러 처리

모든 디코더는 Result(T, ApiError)를 반환합니다.

case short_term.decode_vilage_fcst(response) {
  Ok(items) -> // 성공
  Error(ApiServiceError(InvalidRequestParameter, msg)) -> // API 에러
  Error(JsonDecodeError(msg)) -> // JSON 파싱 실패
  Error(UnexpectedResponse(body)) -> // 예상치 못한 응답
}

기상청 API 에러코드(01~99) 전체가 ErrorCode variant로 매핑되어 있습니다.

주요 도시 상수

위치, 지역, 지점 코드를 상수로 제공합니다.

// 단기예보 — 18개 도시 격자좌표
location.seoul  location.busan  location.daegu  location.jeju ...

// 중기예보 — 지점번호, 육상/해상/기온 구역코드
region.seoul_incheon_gyeonggi       // StationId
region.land_seoul_incheon_gyeonggi  // LandRegionId
region.temp_seoul                   // TempRegionId
region.sea_west_central             // SeaRegionId

// 생활기상지수 — 17개 시도 행정구역코드
area.seoul  area.busan  area.gyeonggi  area.jeju ...

Development

gleam build        # 빌드
gleam test         # 테스트
gleam format       # 포맷
gleam docs build   # API 문서 생성
Search Document