기록 목록자유게시판

실 운영에서 드러난 SPA/API 런타임 계약 문제들 정리 ( 그누보드7 )

humanpchumanpc ·
05-2753
최근 운영 중인 그누보드7 기반 환경을 점검하면서, 문서/설계 의도와 실제 런타임 계약(runtime contract) 사이가 어긋나는 지점들을 몇 가지 발견하게 되었습니다. 단순히 "버그 수정"이라기보다는, 실제 운영 환경에서만 드러나는 경계 조건에 가까운 사례들이었습니다. 이번에 확인한 것들 중 인상적이었던 것은 아래 2가지였습니다. * Accept 헤더 유무에 따라 보호 API가 JSON 401 대신 HTTP 500을 반환하던 문제 * 존재하지 않는 public SPA 경로가 404 대신 SPA shell 200으로 응답하던 문제 첫 번째는 꽤 흥미로웠습니다. SPA/API 중심 구조에서는 login route가 아예 없는 경우가 자연스러운데, 특정 조건에서 Laravel의 unauthenticated redirect 흐름이 여전히 route('login') 을 시도하면서 Route [login] not defined 예외가 발생하고 있었습니다. 즉, curl -i https://example.com/api/me 는 500이 되고, curl -i -H 'Accept: application/json' https://example.com/api/me 는 정상적으로 JSON 401이 되는 상태였습니다. 운영 환경에서는 API 클라이언트나 crawler/tooling이 항상 Accept 헤더를 정확히 넣는다는 보장이 없기 때문에, 실제로는 꽤 중요한 차이였습니다. 두 번째는 SPA catch-all 관련 문제였습니다. 존재하지 않는 경로도 모두 SPA shell로 fallback되면서 HTTP 200을 반환하고 있었는데, Googlebot UA까지 동일하게 200을 받는 상태였습니다. 결국 crawler 입장에서는 "없는 페이지도 정상 페이지처럼 보이는" 상태가 됩니다. 이 부분은: * 등록된 template route인지 먼저 확인 * 미등록 public path는 명시적으로 404 반환 구조로 정리했습니다. 이번 점검 과정에서는 그 외에도: * bundled template i18n contract 불일치 * runtime driver source-of-truth 혼선 * SEO/static renderer parity 문제 * lazy chunk topology 경계 문제 * public/storage symlink serving 정책 같은 운영 레벨의 계약 불일치들도 함께 확인했습니다. 재미있었던 점은, 대부분이 "기능 자체는 동작"하고 있었지만: * crawler * static renderer * API client * 운영자 * 배포 환경 같은 서로 다른 소비자 관점에서는 계약이 조금씩 달라지고 있었다는 부분입니다. 결국 실제 운영 안정성은 "기능이 된다"보다: * 동일한 계약이 유지되는가 * 모든 소비자가 같은 결과를 보는가 * fallback이 의도된 방식으로 동작하는가 쪽에 훨씬 가까운 문제라는 생각이 들었습니다. 최근에는 이런 식으로 "문서/설계/런타임/운영"이 실제로 얼마나 일치하는지를 계속 점검해 보고 있습니다.

댓글과 작업 영역을 나중에 불러옵니다

필요할 때 댓글과 작업 영역을 불러옵니다. 댓글 0개