포스트

[업무일지] 참조 0건이 증명하지 못한 API 사용처

레거시 Spring API의 사용처를 여러 저장소에서 확인한 뒤, 호출이 없다고 판단한 엔드포인트를 지웠습니다. 그날부터 관리자 화면이 부르던 경로가 드러나기 시작했고, 다음 날에는 어드민 기능 하나가 404를 받았습니다. 관리자 코드의 문자열 경로 몇 개가 삭제 목록 검토에서 빠져 있었거든요. 전체를 되돌리지 않고 확인되는 경로만 되살리면서, 관리자용 API 는 요청 경로로 검색한 뒤에 지우기로 기준을 바꿨습니다.

Java 17, Spring Boot 2.6.x, MyBatis를 쓰는 레거시 API 서버입니다. 이 서버를 호출하는 관리자 페이지는 PHP이고 저장소도 따로입니다.

사용 중인 API부터 목록으로 만들었다

오래된 API 서버를 정리하고 있습니다. 컨트롤러는 남아 있는데 실제로 누가 호출하는지 알기 어려운 코드가 많았습니다. 서비스와 쿼리까지 따라가면 한 엔드포인트를 지우는 것만으로 파일 여러 개가 같이 없어지는 구조였고요.

바로 지우지는 않았습니다. 먼저 컨트롤러의 전체 엔드포인트를 목록으로 만들었습니다. 서버 내부 참조를 찾고, 이 서버를 호출하는 다른 API 서버와 관리자 저장소도 검색했습니다. 그 과정에서 다른 API 서버나 관리자 저장소에서 호출이 확인된 18개는 삭제 대상에서 뺐죠. 목록은 AI 리뷰를 세 번 돌려 가며 다듬었습니다.

남은 후보를 지운 뒤에는 Java 컴파일도 확인했습니다. 라우팅되지 않는 요청을 잡기 위해 404 로그도 보강했고요. 요청 경로와 HTTP 메서드, 호출자 정보를 남기도록 했습니다.

여기까지 했을 때는 근거가 충분하다고 봤습니다. 서버 안에서 호출이 없고, 알고 있는 호출 저장소에서도 찾지 못했고, 컴파일도 통과했으니까요.

어드민의 수동 처리 화면이 404를 받았다

배포 다음 날, 운영자가 회수 건의 역입금을 수동으로 보정하는 화면이 동작하지 않았는데, 버튼을 누르면 삭제한 API로 요청이 나가고 있었습니다. 사실 배포 당일에도 관리자 화면이 부르던 경로가 나와서 이미 두 번 되살린 참이었습니다.

배포 전에 보강해둔 404 로그에도 그 요청이 남아 있었습니다. 그런데 정작 그 로그가 아니라 운영자 문의로 먼저 알게 됐고요.

서버 쪽에는 그 컨트롤러를 직접 부르는 코드가 없습니다. HTTP 엔드포인트니까 그게 정상입니다. 실제 호출은 오래된 관리자 저장소에 문자열 경로로 남아 있었습니다.

관리자 화면은 별도 애플리케이션이라 서버를 컴파일해도 이 호출은 검사되지 않고, Spring 컨트롤러 메서드의 사용처 찾기를 실행해도 당연히 나오지 않습니다.

서버 저장소 안에서 참조 0건이라는 사실을 시스템 전체에서 사용 0건으로 넓혀 받아들였습니다.

관리자 저장소도 조사 대상에는 들어 있었습니다. 같은 관리자 파일에서 같은 모양으로 경로를 부르는 호출 대부분은 목록에 들어갔는데, 몇 개가 빠져 있었습니다. 검색 방식이 틀렸다기보다 항목 단위로 빠진 거죠. 전체 엔드포인트와 모든 호출 문자열을 기계적으로 대조한 결과물이 없었는데, 완성된 목록처럼 다룬 겁니다.

확인된 호출 경로만 복구했다

삭제를 전부 되돌리지 않고, 실제 호출이 확인되는 API만 그때그때 복구했습니다. 컨트롤러만 되살려서는 안 됐습니다. 서비스와 DAO, 요청·응답 모델, MyBatis 쿼리까지 한 호출 경로를 같이 복원했습니다.

전체 변경을 되돌리는 방법도 있었습니다. 그러면 장애 복구는 빨랐겠지만, 사용하지 않는 것으로 확인한 코드까지 다시 돌아오고 이미 분리해둔 삭제 근거도 사라집니다.

운영 기능을 먼저 살리고, 나머지 삭제 결과는 유지했습니다.

이 선택에도 비용은 있었습니다. 레거시 코드는 한 API가 여러 쿼리와 상태 변경을 묶고 있어서 복구 diff가 작지 않았습니다. 컨트롤러 메서드 한 개만 보고 영향 범위를 짐작할 수 없는 구조였죠.

관리자용 API 는 요청 경로로 찾아본 뒤에 지운다

바꾼 기준은 하나입니다. 관리자 화면이 부르는 API 는 목록에 있든 없든, 지우기 직전에 하나씩 관리자 프론트(PHP 와 React) 코드에서 API 경로 문자열로 검색합니다.

오래된 관리자 코드는 공통 클라이언트에 URL을 넘기는 방식이라, Java 메서드 이름이 아니라 실제 요청 경로로 찾아야 걸립니다. 메뉴가 남아 있는지, 그 메뉴에서 어떤 컨트롤러를 거쳐 요청을 만드는지도 같이 봅니다.

404 로그는 보조 수단으로 남겼습니다. 삭제한 경로로 요청이 들어오면 어느 화면에서 왔는지 추적하는 데는 도움이 됩니다. 하지만 이건 요청이 실패한 뒤에야 알려주는 장치입니다. 삭제해도 된다는 사전 증명은 아니었습니다.

계약 테스트 없이 남은 문자열 경로

OpenAPI 기반 클라이언트나 소비자 계약 테스트까지 만들지는 않았습니다. 관리자 페이지가 문자열로 경로를 조합하는 구조도 남아 있습니다. 정적 검색과 404 로그를 같이 보는 수준이라, 동적으로 만들어지는 경로나 드물게 쓰는 운영 기능은 다시 놓칠 수 있습니다.

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.