클라이언트가 가장 두려워하는 요청이 있습니다. "돌아가는 걸 다시 짜 주세요."
기능은 그대로여야 하고, 서비스는 멈추면 안 되고, 무엇이 빠졌는지는 아무도 모릅니다. 명세가 코드에만 있기 때문입니다.
지금 그 작업을 하는 중이고, 이 글은 완료 보고가 아니라 진행 중인 방법에 대한 기록입니다.
무엇을 하고 있나
기존 백엔드 서비스들을 새 런타임과 프레임워크 위로 옮기고 있습니다. 단일 저장소 안에 애플리케이션 일곱 개와 공용 패키지 열여섯 개로 정리했습니다.
여기까지는 흔한 이야기입니다. 중요한 건 어떻게 빠뜨리지 않느냐입니다.
손으로 옮기면 반드시 빠뜨린다
엔드포인트가 수백 개입니다. 하나씩 열어서 새 코드로 옮기고, 돌려 보고, 맞는 것 같으면 넘어갑니다. 이 방식의 문제는 빠뜨린 것을 빠뜨린 줄 모른다는 점입니다.
거의 안 쓰이는 경로, 특정 조건에서만 도는 분기, 응답에 있는지도 몰랐던 필드 — 이런 것들은 옮길 때 안 보이고 몇 달 뒤에 터집니다.
그래서 기계가 비교하게 했다
기존 서비스의 경로 정보를 계약으로 뽑아냈습니다. 생성된 파일이 1 만 2 천 줄입니다. 사람이 관리하는 목록이 아니라 코드에서 추출한 것이라, 실제와 어긋날 수가 없습니다.
그리고 CI 에 두 개의 관문을 뒀습니다.
빠진 것 검사. 기존에 있는데 새 쪽에 없는 것을 찾아 실패시킵니다. 기준선을 정해 두고 그보다 나빠지면 통과하지 못합니다.
타입 검사. 이관 대상 경로들의 요청·응답 타입이 계속 맞는지 별도로 확인합니다.
빠뜨림이 리뷰어의 주의력에 달려 있지 않게 만드는 것이 이 구조의 목적입니다. 사람은 수백 개를 비교하다 보면 반드시 놓칩니다. 기계는 안 놓칩니다.
기준선을 두는 이유
"차이 0 건이어야 통과"로 하면 첫날부터 아무것도 머지할 수 없습니다. 이관은 몇 달짜리 작업이고, 그동안 CI 가 계속 빨간불이면 아무도 안 봅니다.
현재 차이를 기준선으로 기록하고, 그보다 늘어나면 실패하게 했습니다. 줄어드는 건 언제든 환영이고, 늘어나는 것만 막습니다. 진행 중인 이관에서 이 구분이 없으면 게이트가 무력해집니다.
아직 진행 중입니다
전부 옮기지 않았습니다. 일부 경로는 여전히 기존 코드로 돕니다. 환경에 따라 새 경로와 옛 경로가 갈리는 곳도 있습니다.
이걸 "완료했다"고 쓸 수 있을 때까지 기다렸다가 쓸 수도 있었습니다. 그런데 이 작업에서 실제로 값어치 있는 부분은 결과가 아니라 방법이라고 생각합니다. 큰 이관을 안전하게 진행하는 방법이요.
역할
커밋 기준 46%, 소스 라인 기준 59% 로 단일 최다 기여자입니다. 게이트웨이, 공용 패키지, 그리고 위에 적은 CI 검증 계층이 제가 맡은 부분입니다.