백엔드 개발자 온보딩 가이드 – 책소개

🗓️

모두에게 막막한 새로운 적응을 위하여

한빛미디어 <나는 리뷰어다> 활동을 위해서 책을 제공받아 작성된 서평입니다.

  • 제목 : 백엔드 개발자 온보딩 가이드
  • 저자 : 이준형, 김석현
  • 출간 : 한빛미디어, 2026

신입이든 경력이든 온보딩 이후의 세계가 익숙한 사람은 없다. 동료들과의 협업이 필연적인 직무가 바로 개발이다. 수평, 수직적으로 얽힌 다양한 이해관계 속에서 조직의 목표를 향해 개발자의 역할을 다 해야 한다. 수많은 개발의 영역 중에서도 웹, 그중에서도 백엔드 직렬도 도메인에 따라, 사업방향에 따라 방법론과 인식이 파편화된지 오래다. 그래서 온보딩 이후의 세계는 모두에게 두렵기 마련이다. 신입에겐 한번도 닿아본적 없기 때문이고, 경력에겐 그간 쌓아온 습관과 방식이 새로운 조직에서 통하지 않기 때문에 더 그렇다. 이 책은 그 막막함과 두려움을 해소해주는데 도움이 되는 책이다. 어떤 기술을 설명 할 때 기술적 깊이보다 이해관계에 미치는 영향에 대해 끊임없이 질문과 답변이 이어진다. 이 책은 대상독자를 ‘온보딩을 할 개발자’ 로 정하고 있는데, 현직자들도 ‘이해관계’에 관점을 두고 한번쯤은 읽어볼만한 책이라고 생각한다.


‘어떻게’보다 ‘왜’가 먼저인 직무

저자는 첫머리부터 백엔드라는 직무의 본질을 한 줄로 못박는다. “백엔드는 ‘어떻게’ 구현했는지보다 ‘왜’ 이렇게 만들었는지가 더 중요한 세상.” 코딩을 학습한 사람이 처음 직무를 마주할 때 가장 흔히 빠지는 함정이 ‘어떻게’에 집착하는 태도다. 저자는 그 함정을 일찍 짚어두고 다른 좌표를 제시한다.

그래서 저자가 그리는 백엔드 개발자가 하는 일은 코드 작성이 아니라 약속을 다루는 일에 가깝다. 프런트엔드와는 API라는 명확한 약속을, 기획자와 디자이너와는 비즈니스 언어라는 약속을 주고받는다. 기획자가 “사용자 등급 시스템을 만들어주세요”라고 했을 때 백엔드 개발자가 어떤 질문을 던져야 하는지를 구체적으로 풀어둔다. 등급의 기준은 무엇인지, 등급별 혜택은 어떻게 다른지, 산정은 실시간인지 일배치인지. 이 질문들이 곧 요구사항을 구체화하는 도구라고 저자는 정리한다.

레거시 코드를 ‘보물 지도’라고 부르는 시각도 인상적이었다. 신입이 처음 마주하는 복잡하고 정돈되지 않은 코드는 좌절감을 주기 마련이다. 저자는 이를 우리 팀의 비즈니스와 기술의 역사라고 다시 정의하면서 해독하는 방법까지 제시한다. 진입점인 API 엔드포인트에서 시작해 코드를 따라가고, 디버거로 변수의 흐름을 보고, 테스트 코드로 의도를 읽고, AI에게는 설명을 부탁하되 그 설명을 ‘가설’로 취급하고 디버거나 테스트로 검증하라는 조언이다. 시니어가 옆에 와서 알려주는 느낌이다.

변화에 견디는 코드, 다음 사람을 위해

객체지향을 다루면서 저자는 단순한 SOLID 강의로 흘러가지 않는다. 객체지향, 도메인 주도 설계, 테스트 주도 개발이 모두 한 가지 공통 문제의식에서 출발했다고 정리한다. 바로 ‘변화에 잘 적응하는 코드를 어떻게 만들 것인가’. 백엔드에서는 잘 돌아가는가보다 나중에 쉽게 고칠 수 있는가에 더 큰 가치를 둔다는 입장을 분명히 한다. 전체를 통틀어 가장 짧으면서 묵직한 문장 중 하나라고 느꼈다.

이 관점에서 SOLID 다섯 원칙은 모두 변경에 유연하게 대응하는 도구로 다시 묶인다. 단일 책임 원칙의 ‘책임’은 곧 ‘변경의 이유’라고 저자는 풀어준다. 클래스에 책임이 많다는 말은 그 클래스가 A 기능이 바뀌어도, B나 C 기능이 바뀌어도 수정해야 한다는 뜻이다. 이렇게 풀어주니 SRP가 그저 단어가 아니라 도구로 보인다. 도메인 주도 설계의 공통 언어 개념도 단순한 이론으로 그치지 않는다. 도메인 전문가와 개발자가 같은 단어를 사용한다는 약속이 요구사항이 코드에 도달하기까지의 왜곡을 막는다는 설명이다. 도메인 분석과 공통 언어, 모델링이라는 주제가 SOLID와 자연스럽게 이어진다.

스프링 삼각형을 소개하는 방식도 좋았다. DI는 객체 간 결합도를 낮추는 도구로, AOP는 횡단 관심사를 핵심 로직에서 분리하는 도구로, PSA는 인프라의 기술 복잡성을 감추는 추상화 도구로 각각의 역할이 분명히 정리된다. 스프링의 트랜잭션 어노테이션 하나로 JPA, JDBC, JTA 어떤 트랜잭션 기술을 쓰든 동일하게 동작하는 이유를 공통 인터페이스 추상화로 풀어주는 PSA의 설명은 한 번 읽으면 쉽게 잊히지 않는다.

필드 주입 대신 생성자 주입을 권하는 이유도 단순히 관행으로 넘기지 않는다. 테스트 용이성, final 키워드로 보장하는 불변성, 생성자 시그니처로 드러나는 명시적 의존성. 이 세 가지 모두 다음 사람이 코드를 읽었을 때 무엇이 필요한지 한눈에 보이게 만들기 위한 도구라는 시각이다. 신입 시절 가장 헷갈리는 부분이 “왜 굳이 final이고 왜 굳이 생성자인가”인데, 그 답이 차분히 정리되어 있다.

// 필드 주입
@Component
public class UserService {
    @Autowired
    private DatabaseService databaseService;
}

// 생성자 주입
@Component
public class UserService {
    private final DatabaseService databaseService;

    public UserService(DatabaseService databaseService) {
        this.databaseService = databaseService;
    }
}

예외와 로그는 운영자를 위한 기록

예외 활용을 다루는 부분은 저자의 시각이 가장 도드라지는 대목 중 하나였다. 예외를 단순한 오류 처리 도구가 아니라 설계 도구로 본다. 좋은 예외 메시지가 무엇인지에 대해서도 구체적인 항목으로 정리한다. 어떤 입력값 때문에 실패했는가, 기대한 조건은 무엇이었는가, 어느 단계나 객체나 사용자와 관련된 문제인가, 실패 당시 시스템이나 외부 API의 반응은 무엇이었는가. 운영자가 새벽에 알람을 받고 로그를 펼쳤을 때 추론할 수 있는 단서를 코드 작성 시점에 미리 깔아두라는 입장이다.

public Product findProductById(Long productId) {
    Product product = productRepository.findById(productId);
    if (product == null) {
        throw new ProductNotFoundException(
            "요청한 ID의 제품을 찾을 수 없습니다: " + productId);
    }
    return product;
}

스프링의 트랜잭션 어노테이션이 기본적으로 런타임 예외에서만 롤백되고 체크 예외에서는 커밋된다는 부분도 짚고 넘어간다. 저자는 이것을 신입 개발자가 자주 저지르는 실수라고 명시한다. 예외를 던졌으니 당연히 롤백되었을 것이라는 착각이 데이터에 흔적을 남기는 실제 경로다. 이 한 줄을 머리에 박아두는 것만으로도 한 권 값을 한다고 느꼈다.

분산 환경에서의 로그를 다루는 부분에서는 Trace ID와 Span ID 개념이 깔끔하게 소개된다. 하나의 사용자 요청 전체를 Trace ID로 묶고, 그 안의 각 작업 단위를 Span ID로 식별한다. 주문 컨트롤러가 루트 Span이 되고 트랜잭션 서비스가 그 자식 Span이 되며, 그 안에서 결제 서비스와 재고 서비스가 각자의 Span으로 동작하는 트리 구조가 그림으로 나온다. Micrometer Observability를 잠깐이라도 만져본 사람이라면 이 그림을 보고 추상이 구체로 내려오는 순간을 경험하게 된다.

테스트는 코드가 아니라 시스템의 약속을 점검한다

테스트를 다루는 절에서 가장 좋았던 문장은 “테스트는 코드가 아니라 시스템의 약속을 점검하는 도구”였다. 저자는 요구사항을 코드 실행 전후에 항상 성립해야 하는 조건, 즉 불변식으로 정리할 수 있다고 말한다. 쇼핑몰의 주문 기능을 예로 들면 “주문 수량은 1개 이상이어야 한다”, “주문 총액은 상품 가격 곱하기 수량이다”, “결제 금액이 주문 총액보다 적을 수는 없다”가 불변식이고, 이 기준으로 테스트 케이스를 짜면 구현이 바뀌어도 약속이 유지되는지 검증할 수 있다는 시각이다.

테스트 모델로 피라미드, 다이아몬드, 허니콤을 차례로 소개하는 부분도 유행 정리에 그치지 않는다. 마이크로서비스로 전환한 조직이라면 단위 테스트만으로는 서비스 간 연동이나 설정 차이를 잡지 못하기 때문에 통합 테스트에 무게를 둘 필요가 있다는 다이아몬드 모델의 입장을 짚는다. 그러면서도 테스트의 양이 아니라 신뢰성이 중요하다는 점을 환기한다.

같은 테스트를 실전 프로젝트의 시점에서 다시 보는 흐름도 좋았다. 단위 테스트가 빠르고 독립적이고 반복 가능해야 한다는 원칙은 앞서 다뤘던 내용이지만, 실전 부분에서는 통합 테스트의 도구를 더 깊이 들고 들어간다. 스프링 부트의 통합 테스트 어노테이션으로 컨텍스트 전체를 로드하는 방식과 컨트롤러 계층이나 JPA 계층만 따로 로드하는 테스트 슬라이스의 차이가 짧지만 정확하게 정리된다. Spring Boot 3.1부터 추가된 서비스 커넥션 어노테이션이 Testcontainers와 스프링 부트의 자동 설정을 연결한다는 짧은 문장도 있는데, 통합 테스트 환경을 직접 구성해본 사람이라면 이 한 줄이 얼마나 큰 차이를 만드는지 안다.

가장 인상적이었던 일화는 검증 파트 안쪽의 짧은 컷이었다. “외부 결제 API 테스트가 그동안 실제로 돈을 결제하고 있었다네요. 테스트 더블을 안 썼다니, 이런 초보적인 실수를…” 팀장의 한마디로 회식이 날아간다. 농담처럼 들리지만 실제 현장에서 종종 일어나는 사고고, 저자는 이 사고를 통해 의존성 역전 원칙이 단순한 SOLID의 한 글자가 아니라 테스트 격리의 원칙이 된다는 결론까지 자연스럽게 끌고 간다.

API는 개발자 경험을 다루는 인터페이스

웹 API 설계 파트는 분량부터 묵직하다. 저자는 API의 핵심을 한 줄로 정리한다. “API 설계의 기본은 결국 예측 가능성과 일관성.” 일관성을 잃은 인터페이스는 사용자가 문서를 매번 들춰봐야 하고 시행착오를 거치며 사용법을 익혀야 한다고 한다. 개발에서 시행착오는 곧 버그로 이어지니, 일관성은 단순한 미감이 아니라 운영 비용에 직결된다는 입장이다.

API 분류 체계도 좋았다. 공개 대상에 따라 Private, Open, Partner로 나뉘는 비즈니스 관점의 분류와, 계층에 따라 BFF, API Gateway, Composite API, Resource API로 나뉘는 아키텍처 관점의 분류가 같이 소개된다. BFF가 SoundCloud에서 고안된 패턴이라는 짧은 메모도 좋았다. 클라이언트별로 다른 데이터 모델을 조합하는 것뿐 아니라 클라이언트의 하드웨어 사양에 따라 요청 횟수, 데이터 갱신 주기, 캐시, 통신 프로토콜까지 최적화한다는 설명이다. 단순히 프론트별로 API 만든다가 아니라 각 클라이언트 환경에 맞추는 백엔드 계층이라는 정의가 분명해진다.

리소스 모델링 4단계를 펼쳐주는 부분도 인상적이었다. 도메인 분석과 모델 정의에서 시작해 리소스 식별자 정의로, 유저 스토리 정의로, 마지막에 리소스 행위 매핑으로 이어진다. 특히 리소스 간의 관계를 합성, 집합, 연관으로 풀어내는 부분이 와닿았다. 게시글과 댓글의 관계가 합성이고, 사용자와 리뷰의 관계는 집합이며, 교사와 학생의 관계는 연관이라는 구분이 단순한 분류표가 아니라 URI 설계와 생명주기 관리의 가이드가 된다.

HATEOAS를 다루는 시각도 솔직해서 좋았다. 이론적으로는 완벽해 보이지만 프라이빗 API 환경에서는 굳이 링크를 동적으로 파싱하기보다 API 명세를 보고 하드코딩하는 게 빠르고, 응답 데이터 크기도 커진다고 한다. 이상을 쫓기보다 팀의 생산성에 도움이 되는가를 기준으로 도입을 결정하라는 정리가 저자의 톤을 잘 보여주는 한 문장이라고 느꼈다.

실전 프로젝트에서 도메인 모델링을 다시 꺼내드는 흐름도 짝을 이룬다. “코드는 금방 짤 수 있지만, 먼저 도메인을 이해해야 해요”라는 팀장의 한마디로 이 대목이 열린다. 기획자와 데이터베이스 담당자와 마케터가 ‘설문’이라는 단어를 각각 다르게 쓴다는 예시가 등장한다. 같은 단어를 서로 다르게 쓰는 직군들 사이에서 공통 언어를 맞추는 작업이 도메인 분석이고, 그 결과가 도메인 모델이라는 정의가 단단하다. 도메인 모델과 엔터티를 분리해서 봐야 한다는 조언, 도메인 모델은 비즈니스 규칙과 행위를 표현하고 엔터티는 데이터베이스에 저장되는 구조라는 구분도 짧지만 정확하다.

데이터의 무결성, 그리고 깃허브가 외래키를 안 쓰는 이유

데이터를 다루는 파트는 분량이 많은 만큼 저자의 톤이 가장 진해지는 대목이기도 했다. 정규화를 “데이터를 정리하는 원칙이자 실수를 줄이기 위한 방어막”으로 정의하면서, 그 본질을 신뢰할 수 있는 데이터를 만드는 법이라고 짚는다. 삽입 이상, 삭제 이상, 수정 이상이라는 세 가지 이상 현상이 구체적인 SQL 예시와 함께 등장한다. user_training 테이블에서 교육 코드 없이는 사용자를 등록할 수 없는 삽입 이상이라거나, 어떤 사용자의 마지막 교육 기록을 지웠더니 사용자 정보까지 함께 사라지는 삭제 이상은 이론 설명보다 훨씬 또렷하게 정규화의 필요성을 전달한다.

역정규화도 단순히 성능 때문에 하는 것으로 다루지 않는다. 조회 전용 테이블, 특정 시점의 데이터 기록, 계산된 데이터 기록으로 나누어 각각이 왜 필요한지를 짚는다. 결제가 완료된 주문의 상품 가격은 이후 할인 정책이 바뀌어도 변경되면 안 되기 때문에 당시의 가격을 주문 상품 테이블에 별도로 저장한다는 사례는, 데이터베이스 설계가 시간이라는 변수까지 다뤄야 한다는 사실을 분명히 한다.

NoSQL 키 설계에 도메인 분리를 반영하라는 조언도 인상적이었다. user-service:user:{user-id}와 shipping-service:user:{user-id}처럼 키 네임스페이스부터 도메인을 구분해 두면 모놀리식에서 마이크로서비스로 전환할 때 유리하다는 입장이다. 문서 데이터베이스의 다섯 가지 패턴인 임베디드, 임베디드 서브셋, 확장 참조, 다형성, 스키마 버전도 단순한 패턴 카탈로그가 아니라 각 패턴이 어떤 의사 결정 지점에서 등장하는지를 함께 보여준다.

일관성 모델을 강한 일관성, 인과적 일관성, 최종적 일관성으로 나누어 설명하면서 비즈니스의 우선순위에 따라 선택해야 한다는 시각도 좋았다. 실시간 거래나 계좌 이체에는 강한 일관성이, SNS 게시글과 댓글의 순서에는 인과적 일관성이, 좋아요 수에는 최종적 일관성이 자연스럽게 맞물린다. 구글 스패너, 몽고DB, 다이나모DB가 대표 사례로 등장하면서 추상이던 이론이 제품의 선택으로 내려온다.

ACID 트랜잭션의 격리 수준을 다루면서 MySQL은 REPEATABLE READ가 기본이고 PostgreSQL과 오라클은 READ COMMITTED가 기본이라는 차이를 짚어둔 부분도 좋았다. 이 차이를 모르면 개발 환경과 운영 환경의 동작이 달라 당황하거나 데이터 정합성 문제를 겪을 수 있다는 친절한 경고가 따라온다. 그리고 가장 의외였던 부분은 “외래키 제약 조건을 실무에서는 잘 안 쓴다”는 코너였다. 쓰기 성능 저하, 운영 유연성 저하, 마이그레이션 복잡도가 이유로 등장하고 깃허브 이슈 링크까지 같이 붙여둔다. 저자가 보여준 가장 정직한 한 페이지였다.

장애를 막는 게 아니라 버텨내는 시스템

장애를 다루는 파트는 저자의 톤을 한 번 더 정리해주는 곳이다. 장애를 완전히 막을 수는 없다고 저자는 짚는다. 서버는 언젠가 멈추고 네트워크는 끊기고 코드에는 늘 버그가 숨어 있다. 그렇다면 개발자에게 중요한 것은 장애를 완벽히 피하는 것이 아니라 장애가 나도 버텨낼 수 있는 시스템을 설계하는 일이라는 입장이다. 이 한 단락이 이후 모든 패턴의 좌표축이 된다.

장애에 강한 시스템의 세 기둥으로 저자는 고가용성, 확장성, 복원력을 든다. 이중화와 Failover와 모니터링이 고가용성을, 수직 확장과 수평 확장이 확장성을, 자동 복구와 격리와 백업이 복원력을 받친다. 각각이 이론적인 분류로 그치지 않고 결제 서비스가 장애를 일으키면 이를 호출하던 주문 서비스도 응답 지연이나 예외에 시달리게 되고, 나아가 사용자 요청을 처리하던 프런트엔드 서비스까지 영향받을 수 있다는 구체적인 연쇄 시나리오로 다시 등장한다.

재시도 전략을 다루는 부분에서 저자의 결이 가장 잘 드러난다. 고정 간격 재시도, 지수 백오프, 그리고 랜덤 지수 백오프까지 차례로 소개되는데, 단순히 알고리즘을 나열하지 않고 왜 그 알고리즘이 필요한지를 짚는다. 지수 백오프는 점점 간격을 넓혀 장애 노드를 더 괴롭히지 않기 위한 전략이고, 랜덤 지수 백오프는 여러 클라이언트가 같은 시점에 한꺼번에 재시도를 시도하는 스파이크를 방지하기 위한 전략이다. 이 두 줄로 분산 시스템의 설계 사고가 한 단계 깊어진다.

멱등성을 다루는 절은 분량으로도 두께가 있지만 내용으로도 가장 인상적이었다. 멱등성을 구현하는 세 가지 방법인 고유 식별자 활용, 결과 캐싱, 불변성이 차례로 소개되고, 이어서 실전 팁들이 묶음으로 들어온다. 이벤트 소싱과 CQRS, 데이터베이스 트랜잭션과 제약조건, 공유 저장소와 분산 락, 캐시 일관성, 그리고 아웃박스 패턴. 특히 아웃박스 패턴은 분산 시스템에서 자주 일어나는 한쪽은 성공 다른 쪽은 실패 같은 일관성 문제를 트랜잭션 안에서 메시지까지 함께 저장하는 방식으로 푸는 패턴이다. 저자는 데비지움 같은 변경 데이터 캡처 도구로 DB 로그를 읽어 실시간으로 발행하는 방식을 트래픽이 많은 환경에서 선호한다는 부연도 빠뜨리지 않는다.

회로 차단기는 재시도와 멱등성의 보완책으로 등장한다. 재시도는 단기적 장애를 위한 것이고 회로 차단기는 장기적 장애를 빠르게 차단하기 위한 것이라는 분리가 명쾌하다. Closed, Open, Half-Open 세 상태의 전환 로직이 그림과 함께 정리되어 있어서 처음 접하는 사람이라도 큰 무리 없이 따라갈 수 있다.

비동기 처리를 다루는 절에서는 메시지 큐, 이벤트 기반 아키텍처, 비동기 API를 각각 분리해서 보여주고, Saga 패턴과 아웃박스 패턴의 차이를 표로 정리한다. Saga는 여러 서비스 간 트랜잭션 흐름을 보상 로직으로 조율하는 것이고, 아웃박스는 한 서비스 안에서 DB 변경과 이벤트 발행을 동시에 보장하는 것이라는 구분이다. 두 패턴을 함께 쓰는 경우가 많다는 정리는 분산 트랜잭션 설계가 단일 패턴으로 해결되지 않는다는 사실을 짚어준다.

기술의 깊이가 아니라 영향의 범위

협업 파트는 분량이 길지 않지만, 기능 조직과 목적 조직을 구분하는 시각이 전체의 흐름과 자연스럽게 이어진다. 기능 조직은 같은 기술을 다루는 사람들이 모여 전문성을 키우는 구조이고, 목적 조직은 백엔드, 프런트엔드, 디자이너, 기획자, 마케터가 하나의 제품을 중심으로 모이는 구조다. 앞서 반복적으로 등장하던 도메인 분석, 공통 언어, 비즈니스 언어가 이 대목에서 다시 호명된다.

결국 한 가지 질문으로 모인다. 이 기술이 동료에게, 시스템에게, 사용자에게 어떤 영향을 주는가. 객체지향은 다음 사람을 위해, 예외 메시지는 운영자를 위해, API는 호출하는 다른 개발자를 위해, 데이터 모델은 미래의 마이그레이션을 위해, 장애 대응은 사용자의 경험을 위해 설계된다. 이 질문은 기술의 깊이를 묻는 질문이 아니라 기술이 영향을 미치는 범위를 묻는 질문이다.

각 파트 끝에 자리한 [고민 상담소] 코너가 그 톤을 단단하게 받친다. “팀원마다 설계 기준이 다 달라요. 뭐가 맞는 거죠?”, “이 정도 변경인데 테스트 안 해도 되지 않나요?”, “재시도와 회로 차단기를 도입할 부분은 어떻게 찾나요?”, “스크럼이 잘 안 굴러가요. 그런데 제가 뭘 할 수 있을까요?”, “질문하면 무능해 보일까 봐 두려워요.” 이런 질문들은 신입의 머릿속에 실제로 도는 질문이면서 동시에 경력자가 새 조직에서 다시 마주하는 질문이기도 하다. 저자는 매번 그 질문을 정면으로 받고 짧지만 단단한 답을 돌려준다.

신입에게도 경력에게도 첫 출근 이후의 세계는 모두 처음이다. 저자는 그 세계를 기술 카탈로그가 아니라 이해관계의 지도로 그려둔다. 백엔드를 시작하는 사람이라면 한 번은, 다시 출발하는 사람이라면 한 번 더, 이 지도를 옆에 두고 자기 자리를 가늠해 보는 시간이 도움이 될 거라고 생각한다.


한빛미디어 <나는 리뷰어다> 활동을 위해서 책을 제공받아 작성된 서평입니다.