구형 클라이언트를 위한 레거시 API 지원을 추가하고자 하던 시도

들어가며

클라이언트와 서버 모두 새로운 API로 전환하고자 할 때, 고민이 생긴다. 업데이트는 앱이 먼저인가, 아니면 서버가 먼저인가.

지금 진행중인 카페테리아 프로젝트에서는 서버를 먼저 업데이트하고 후에 앱을 업데이트하는 방향으로 가닥을 잡았다. 그 과정에서 이전 앱이 참조하던 기존의 서버는 유지함으로써 새 클라이언트만 새 서버로 연결되도록 계획하였다.

대참사(?)

그 계획이 깨진 것은 어제 아침이었다. 새 서버의 가장 중요한 클라이언트 중 하나인 학식당 키오스크가 새 서버를 참조하도록 url을 변경해야 이전 작업이 완료되는데, 이 부분을 거의 1년 내내 요청해도 아무 일이 일어나지 않는 것이었다. 그래서 구 서버를 가리키던 url을 새 서버로 리다이렉트시켜 버렸다.

그러면서 기존의 안드로이드 클라이언트도 의도치 않게 새 서버로 요청을 보내게 되었다. 그런데 기존 클라이언트는 당연히 이전 API를 사용하고 있었고, 새 서버로 엉뚱한 요청을 보낸 셈이 되었다. 하여 앱이 실행되자 마자 치명적인 오류를 이야기하며 종료되었다.

치명적인 오류는 카페테리아 안드로이드 앱 3.0.0을 만들 때에 추가하였다. 당시에는 서버가 API를 마음대로 바꿀 거라는 고려는 하지 않았고, 그게 맞다. url을 막 변경하면서 생긴 부작용이었다.

새 서버에 레거시 지원 추가하기

하여 기존의 url을 새로운 서버로 보내고자 한다면 새 서버에 기존 클라이언트를 위한 API를 추가할 필요가 생긴다. 구형 클라이언트는 다음 API를 사용한다:

  • version.json
  • login
  • logout
  • activeBarcode
  • notice.json
  • food
  • cafecode.json

Endpoint 포워딩

이들로 향하는 요청을 구 서버의 백업 url로 포워드하면 문제를 간단하게 해결할 수 있다. 그러나 곧 이 방법으로는 불가능함을 깨달았다.

loginlogout은 구 서버와 새 서버가 모두 지원하나 요청 규격과 구현 모두 다르다. 즉, 서버를 완전히 이전하면 예전 클라이언트와 새 클라이언트 모두 새 서버로 요청을 보낼 것인데, 이때 서버는 클라이언트가 어떤 login을 기대하고 요청을 보낸 것인지 알 수가 없다.

이는 구 클라이언트는 구 API에만 요청을 보낼 것이며, API는 path와 method로 구분된다는 생각 때문이었다. 구 클라이언트는 구 API에만 요청을 보내는 것은 맞는데, login 같은 경우는 구 API와 새 API를 구분할 수 없기 때문이다.

모름지기 이런 상황을 대비하여 제대로 된 서비스를 운영하는 주체들은 보통 헤더나 페이로드에 API 버전을 달아놓는다. 그게 아니면 API endpoint 이름을 최대한 겹치지 않게 하기라도 한다.

수작업으로 버전 구분

다만 path와 method가 같아도 API 버전을 구분하는 방법이 있긴 하다.

구 API와 새 API 모두 login을 정의하고는 있지만 둘이 요구하는 페이로드 규격은 다르다. 따라서 해당 path로 들어오는 요청을 하나 하나 뜯어 클라이언트가 어떤 응답을 원하는 것인지 알아내면 되긴 하다. 그런데 이 방법은 좀 지저분하다. 소스 코드 여기저기를 건드려야 하고, 나중에 다시 되돌리기도 귀찮다.

레거시 지원 포기

레거시 앱이 아직까지 남아있는 것이 마음에 걸려 한참 전에 개발을 시작해 몇 주 전에 이미 디자인부터 코드까지 뜯어고친 새 버전의 앱을 완성해 놓은 터였다. 서버의 레거시 지원을 포기하고 빠르게 이 새 앱을 배포하기로 결정하였다.

방금 플레이스토어에 개선된 앱 4.0.0 버전 출시를 시작했고, 출시가 완료된다면 서버 이전 후 반강제(?)적인 업데이트 수요가 폭발할 것이다. 따라서 레거시 앱은 빠른 시일 내에 소멸될 것이다. 그 후에는 레거시 지원의 필요가 사라질 것이다. 이는 지금 상황에서는 레거시 지원을 위한 삽질이 딱 한 달 정도만 쓸모있을 것 이라는 뜻이다.

따라서 이번에 한하여 새 서버에서 레거시 API를 지원하기 위한 노력은 하지 않기로 했다. 플레이스토어에 검토 통과만 되면 서버 이전을 속행하고자 한다. 요즘 플레이스토어 검토가 느리다. 구글아 일해라

그래서 수습은 어떻게 했냐면

앱이 로그인되지 않자 오전 9시 조금 넘어서 학식당에서 전화가 왔다. 새벽부터 긴장이 되어 잠 안자고 로그를 들여다보고 있긴 하였으나 구버전 클라이언트의 실행 이슈는 포착하지 못 하였기에 조금 당황했다. 결국 전화를 받고 식은땀을 흘리며, 바코드만 발급받을 수 있는 페이지 주소를 급히 전달해 주었다.

카페테리아 바코드 생성 페이지는 몇 달 전에 iOS 앱(새 것)과 서버(이전 것)의 불일치로 인해 발생한 문제를 임시로 떼우기 위해 만들어 놓았다.

이대로 놓아 둘 수는 없어서 일단 기존 url이 다시 구 서버를 가리키도록 레코드를 업데이트하였다. DNS 전파가 일어날 때까지 30분에서 한 시간 가까이 걸렸던 것 같다. 새 서버로 오는 트래픽은 10시가 되자 모두 사라졌다.

마치며

오늘 일로 얻은 교훈은 아래 세 개다:

  • URL을 바꿀 때에는 그를 참조하는 모든 클라이언트에서 테스트를 먼저 해야 한다.
  • 헤더에 API 버전을 써놓든가 하는 등 레거시 지원을 위한 장치를 만들어 놓아야 한다.
  • 플레이스토어에 출시할 생각이라면 미리 올려서 심사를 받아 놓자.

댓글