목차
- 서론
- 본론
- 요구사항 분석
- 구현 방법 결정
- 구현
- 결론
서론
저는 현재 10월부터 간단한 서비스에 대한 외주 프로젝트를 시작하여 슬슬 마무리 지어가고 있습니다.
농부 분들이 서로 정보를 공유하거나 작물 생육에 도움이 되는 정보를 제공하는 서비스인데요.
이번 글은 서비스를 만들어 나가며 가장 빈번하게 변경이 발생했던 일기예보 기능과 관련해 서비스를 개선시켰던 과정입니다.
이번 글에서는 초기 기능 구현 과정을 다루고자 합니다.
간단한 서비스라 백엔드 개발자가 저뿐이어서 문제해결 과정이나 결과가 미숙할 수 있습니다.
관련한 부분 피드백을 댓글로 남겨주시면 감사하겠습니다.
본론
요구사항 분석 및 명세 도출
기능 개발에 앞서 가장 중요한 절차로 먼저 클라이언트 측의 요청은 다음과 같았습니다.
- 기상청 API를 이용한 오늘의 날씨 및 2일간의 날씨 정보 표기
- 일주일 간의 날씨 정보(최고 기온, 최저 기온, 강수확률 등) 표기
이를 토대로 기획자 겸 디자이너분께서 기획한 내용을 다음과 같이 디자인해주셨습니다.
위 요구사항과 디자인으로부터 다음과 같은 명세를 도출할 수 있었습니다.
- 일간 일기예보 조회
- 시간대별 기온, 기상, 풍속, 강수 확률
- 최고, 최저 기온
- 주간 일기예보 조회
- 일별 최고 기온, 최저 기온, 기상 정보, 강수 확률
이렇게 API의 명세를 작성했고 외에도 비기능적 요구사항으로 평균 500ms 이내의 응답시간 정도를 추가했습니다.
구현 방법 결정
다음 절차는 구현체에 대한 고민이었습니다.
다양한 일기예보 API 중 크게 기상청 API, OpenWeatherMap, SK Weather Planet 세 개를 비교해 하나를 선택하고자 했습니다.
서비스의 이용자와 예산 등 특성을 고려하여 기상청 API를 최종 선택하였고 그 과정에서 고려했던 부분은 다음과 같습니다.
기상청 | OpenWeatherMap | SK Weather Planet | |
호출 시 매개변수 | 격자 정보, 좌표(위도, 경도) | 좌표(위도, 경도) | 좌표(위도, 경도) |
호출 제한 | 일 10,000회 | 초당 60회 | 일 500회 |
중기 예보 지원 여부 | 3~10일 | 지원하나 유료 | 3~10일 |
가장 먼저 과금 여부를 고려했습니다.
클라이언트 측에서 추가적인 요금 발생을 원치 않았기 때문에 OpenWeatherMap을 제외하게 되었습니다.
이후로 트래픽을 고려했습니다.
클라이언트로부터 MAU가 대략 300 ~ 400 정도 될 것 같다는 답변을 받았고 기상청, SK Weather Planet 모두 현재 단계에서는 무리없이 사용 가능하다고 판단했습니다.
지역 조합 측에서 농부 분들을 대상으로 서비스하는 플랫폼이기 때문에, 현재 조합 가입자가 400여분 정도라 이를 토대로 추산할 수 있었습니다.
마지막으로 호출 시 매개변수의 차이였는데요.
기상청의 경우, 일간 일기예보 조회 시 좌표에 기반한 격자 정보를 SK Weather Planet의 경우, 일, 주간 모두 좌표 정보를 사용한다는 점이 달랐습니다.
두 API가 차이를 보일 수 있는 일간 일기예보 기능의 성격에 따라 선택하고자 했고 이에 따라 최종적으로 기상청 API를 선택하게 되었으며 이유는 다음과 같습니다.
- 일간 일기예보의 경우, 메인화면에 노출되기 때문에 호출이 잦아 트래픽 초과 우려가 있음
- 추후 사용자가 많아져 한도에 가까워지는 경우, 캐시를 태울 때 쿼드트리, 지오해시 등을 통해 격자 정보를 토대로 캐시를 태우고자 함.
따라서 트래픽도 더 넉넉하고 이미 제공되어있는 격자 정보를 토대로 캐시를 구성하기가 쉬울 것이라 판단하여 기상청 API를 최종 선택하였습니다.
구체적인 구현
이제 사용하고자 할 API도 결정되었고 명세도 완성했으니 남은 것은 기능구현입니다.
개략적인 기능의 초안은 다음과 같았습니다.
- 일간 일기예보
- 좌표 값을 토대로 기상청 API에 격자 정보 요청
- 격자 정보 값을 토대로 기상청 API에 일기예보 데이터 요청
- 텍스트 형태의 일기예보 데이터를 내부 객체로 변환
- 불필요한 데이터 필터링(2, 3일 후의 일기예보 등) 후 내부 도메인 객체로 변환
- 도메인 객체를 dto로 변환하여 클라이언트에 전달
- 주간 일기예보
- 좌표 값을 토대로 기상청 API에 단기(~ 3일), 중기예보(3 ~ 10일) 데이터 요청
- JSON 형태의 두 일기예보 데이터를 내부 객체로 변환
- 두 일기예보 데이터 병합 후 불필요한 데이터 필터링(8일 이후의 일기예보 등)
- 필터링된 데이터를 토대로 내부 도메인 객체로 변환
- 도메인 객체를 dto로 변환하여 클라이언트에 전달
해당 흐름을 토대로 두 기능을 구현하였고 응답시간 역시 평균 350ms 이내로 찍히며 별다른 개선없이 기능 구현을 마감했습니다.
당시에 구현한 내용을 토대로 더 생각해볼 수 있는 부분은 다음과 같습니다.
1. 기상청 API에 대한 의존성
- 일간의 경우 텍스트를, 주간의 경우 JSON을 응답으로 받고 있기 때문에 내부 도메인이 직접적으로 해당 값을 참조하는 것을 방지하고자 응답에 대한 내부 객체를 추가적으로 두어 영향력을 줄이고자 했습니다.
2. 추후 캐싱 시 어떤 객체를 태울 것인가?
- 내부 도메인 객체를 캐싱하고자 했습니다. 격자 정보를 키로 매핑하여 즉각적인 응답을 제공하고자 했습니다.
3. 기상청 API에 오류가 발생하는 경우 어떻게 처리할 것인가?
- API 클라이언트 객체가 오류를 발견하면 먼저 1회 재시도 후, 재차 오류 발생 시, 기본적으로 생성되는 데이터를 내려주도록 했습니다.
- 하지만 이 역시 미봉책이었기 때문에 클라이언트 측 요구사항에 따라 재설계가 필요한 부분이었습니다.
- 이에 대해서는 크게 다른 외부 API 사용, API 사용 대신 캐싱한 데이터 내려주기 등을 방안으로 염두에 두고 넘어갔습니다.
결론
이렇게 구현된 기능은 일주일 여 정도의 테스트에서도 큰 문제가 발견되지 않았고 정상적으로 종료되었습니다.
다음 글에서는 기상청 API의 응답속도가 일시적으로 3초 정도로 느려져 생겼던 이슈와 이에 대한 대응을 다뤄보겠습니다.
감사합니다!
'Back End' 카테고리의 다른 글
객체 지향 설계 원칙 SOLID는 뭘까? (0) | 2025.03.30 |
---|---|
Real MySQL 8.0 1권을 읽고 (2) (1) | 2024.11.09 |
Real MySQL 8.0 1권을 읽고 (1) (0) | 2024.10.26 |
단위 테스트를 가볍게 알아보자 (0) | 2024.10.13 |
인증 로직 (0) | 2023.08.22 |