Cheondi
개발 · API

시간대 파일 주소 하나가 환경마다 달랐다

시간대 데이터 다운로드 주소가 개발과 배포 환경에서 달라진 문제를 설정과 배포 경계로 정리한 기록입니다.

  • #api
  • #configuration
  • #deployment

시간대 정보를 갱신하는 파일은 개발 환경에서 잘 내려받아졌지만 배포된 WebGL에서는 404가 났다. 파일 이름과 요청 코드는 같았고 브라우저에서 개발 주소를 직접 열면 정상이라 한동안 데이터 문제를 의심했다. 실제 배포에서는 정적 파일의 기준 경로와 CDN prefix가 달랐다.

코드 안의 상대 주소 하나가 실행 위치에 따라 다른 서버를 가리키고 있었다.

URL을 현재 페이지 문자열로 만들지 않았다

window.location에 경로를 붙이는 방식은 하위 경로 배포와 CDN에서 깨졌다. 환경 설정에서 정적 자산 기준 URL을 전달하고 URL API로 결합했다.

const timezoneUrl = new URL(
  'data/timezones.json',
  window.appConfig.assetBaseUrl
).toString();

설정에는 공개 가능한 기준 주소만 넣고 인증 정보는 포함하지 않았다.

파일 존재와 응답 내용을 따로 확인했다

HTTP 200이어도 오류 페이지 HTML이 반환될 수 있었다. 상태 코드, Content-Type, JSON 버전을 순서대로 검사했다.

if (!response.IsSuccessStatusCode) return DownloadFailed.Http;
if (!IsJson(response.ContentType)) return DownloadFailed.UnexpectedContent;

var data = Parse(await response.ReadText());
if (data.Version < minimumVersion) return DownloadFailed.OldData;

전체 본문을 로그에 남기지 않고 주소의 공개 경로, 상태 코드, 콘텐츠 종류만 기록했다.

실패할 때 마지막 정상 데이터를 사용했다

시간대 파일을 못 받았다고 로그인과 전체 앱을 막을 필요는 없었다. 앱과 함께 들어 있는 기본 데이터나 마지막으로 검증된 캐시를 사용하고, 갱신 실패를 별도로 표시했다.

잘못 받은 파일로 정상 캐시를 덮지 않도록 다운로드, 검증, 교체 단계를 분리했다. 새 파일은 임시 위치에서 확인한 뒤 원자적으로 교체했다.

설정도 배포되는 코드였다

로컬에서 맞는 URL을 하드코딩하면 구현은 끝난 것처럼 보인다. 실제 서비스에서는 개발, 테스트, 운영의 자산 위치와 페이지 기준 경로가 달랐다. 코드 성공과 배포 환경 성공을 구분해야 했다.

이후 외부 파일이나 API 주소를 붙일 때 환경별 기준, 최종 생성 URL, 실패 대체 경로를 함께 확인한다. 주소 한 줄도 실행 환경과 배포 구조를 잇는 계약이었다.