Writing

[주간회고] 우아한테크코스 레벨2 5주차 - 강제가 없었다면 하지 않았을 공부

Less is more. 2026. 6. 2. 00:37

굳이 프론트엔드 개발자가 서버를 공부해야 할 이유가 무엇일지 생각해 보는 시간을 가졌습니다.

 

이번 주 미션은 BE가 되어 서버를 개발해 보는 미션이었습니다. 단 한 번도 만들어본 적 없습니다. 솔직히 말하면, 강제가 없었다면 따로 시간을 내며 하지는 않았을 것 같습니다. 장바구니 step-1 미션은 Node.js와 Express로 서버를 직접 만들어야 했습니다. GET과 POST도 다시 공부하게 되었고, 자연스럽게 PUT과 PATCH의 차이도 공부하며, 그러다 보니 RESTful이 무엇을 의미하는지까지 공부하게 되었습니다.

 

이번엔 AI를 전혀 쓰지 않기로 했습니다. 정보를 알아가는 과정부터 배포 과정까지 블로그와 공식 문서에만 의존했습니다. AI의 조금의 도움이라도 받게 된다면 학습의 목적이 흐려지고, 결국 좋은 코드를 받아내는 것에만 집중하게 될 것 같았습니다. 초심자의 학습 목적에서는 블로그도 충분합니다.

 

이번 미션 최우선 목표는 서버와 Express, Supertest 문법 자체에 익숙해지는 것이었고, 익숙해지려면 직접 부딪혀야 한다고 생각했습니다. 일단 페어인 벤지와 함께 코드를 치기 전에 먼저 화이트보드에 설계를 그렸습니다. /products와 /cart로 도메인을 나누고, 엔드포인트별로 request body 형태, 예상 status code, response body 구조를 표로 정리했습니다. 싱크를 맞추기 위해 아예 처음부터 백지 화이트보드에서 전체를 기억에만 의존한 채로 페어에게 우리의 endpoint 설계와 구현할 res/req body에 대해 발표했습니다. 말로만 이야기하면 서로 다른 구조를 머릿속에 그리고 있을 수 있으니까요. 그렇게 싱크를 맞추고 나서야 구현에 들어갔습니다.

 

"레스형 그냥 가요~~ 일단 치면서 생각해봐요 완전 Agile하게~~"

 

우선 서버 구현 경험이 있는 자와 없는 자가 어떤 식으로 현명하게 페어프로그래밍을 진행하는 게 좋을지 고민했습니다. 구현 단계에서 드라이브는 합의하에 제가 거의 90% 이상 전부 진행했습니다. 서버 구현 경험이 있는 벤지보다 제가 직접 치는 게 학습에 도움이 될 것 같았고, 벤지도 그렇게 생각했습니다. 벤지는 막힐 때마다 옆에서 아이디어를 주었고, 가끔은 혼자 생각해내야 한다며 답을 주지도 않았고, 반대론 저는 설계 확장 가능성, 새로운 테스트 케이스 추가 건의를 하면서 진행했습니다. 벤지는 진짜 애자일하게, 일단 치면서 생각하는 스타일이었습니다. 심지어는 치면서도 설계 방향이 변경되기도 했습니다. 반면 평소의 저는 하나의 메서드를 구현하기 전에 머릿속으로 30초에서 1분은 플로우를 정리하는 편이었는데, 그 방식과는 꽤 달랐습니다. 그런데 그렇게 하니까 쉽지는 않았으나 완전 재미있었습니다. 벤지 최고.

 

이번에 구현하면서 products 엔드포인트를 전부 구현하고 cart로 넘어갈 때에 복붙이면 될 코드조차 굳이 처음부터 다시 쳤던 기억이 납니다. 옆에 띄워두지도 않고, 기억에만 의존해서 한 땀 한 땀 다시 전부 쳤습니다. 제가 완전히 이해하고 있는지 스스로 테스트하고 싶었습니다. 벤지도 오히려 좋아했습니다. 시간이 오래 걸려서 미안하기도 했지만, 그게 꽤 마음에 듭니다. 그걸 전부 다시 치다니... 저도 조금은 독한 사람인가 봅니다.

 

결과는 완전히 flat한 구조였습니다. 데이터를 다루는 코드와 응답을 만드는 코드가 한 곳에 응집되어 있었습니다. 그리고 그 후 코치 시지프가 공통 피드백으로 가져온 AS-IS 예시 코드가 저희 코드와 거의 일치했습니다. 처음엔 너무 웃었습니다. 실제로 저는 저희 코드를 가져온 줄 알았습니다.

 

그런데 잠깐 생각해 보니 꼭 웃기기만 한 건 아니었습니다. AI에게 맡겼다면 처음부터 TO-BE가 나왔을 것입니다. 관심사가 분리되고, 레이어가 나뉜 깔끔한 구조로 나왔겠죠. 코드 자체는 훨씬 그럴싸해 보였겠지만, 왜 그렇게 나눠야 하는지는 적당히 이해한 채 넘어갔을 것입니다. AS-IS를 직접 겪어봐야 TO-BE가 왜 그런 모습인지가 납득이 된다고 생각합니다. 납득이 되어야 다음엔 스스로 그 판단을 할 수 있습니다.

 

수업이 끝나고 같이 짝을 했던 윤돌과 금요일, 토요일 총 4시간 동안 시지프의 라이브 코딩을 그대로 재현하면서 어떤 생각으로 리팩토링 순서를 그렇게 가져갔는지를 추가 페어프로그래밍을 통해 복기했습니다. 자주 보여주시면 좋겠습니다. A가 B에 의존한다는 명제와 A가 B를 사용한다는 명제, 그리고 A가 B 인터페이스를 구현한다는 명제를 각각 실선 화살표와 점선 화살표로 나누어 도식화하면서 조금은 알게 되었습니다. 역시 토요일에는 반드시 나와야 합니다.

 

리뷰 과정에서도 비슷한 경험을 했습니다. PUT과 PATCH 중 어느 쪽을 쓸지 페어와 꽤 오래 고민했고, 저희는 처음에 PUT을 선택했습니다. 간단하게 요약한다면, 프론트가 이미 전체 객체를 들고 있으니 수량만 바꿔서 그대로 던지면 된다는 논리였습니다. 그런데 리뷰어 데구리가 짚어준 지점이 있었습니다. 프론트가 화면에 필요해서 들고 있는 데이터와, 서버에 다시 보낼 리소스 표현을 책임지는 것은 다른 문제라는 것이었습니다. 수량 하나를 바꾸기 위해 name, price, imageUrl 같은 상품 정보 전체를 클라이언트가 계속 들고 다니며 되돌려 보내야 한다면, 그 책임이 자연스럽지 않다는 뜻이었습니다. 그 피드백을 받고 나서야 PATCH /cart/:id에 quantity만 보내는 쪽으로 바꿨고, 그제야 이 API가 무엇을 하는 엔드포인트인지가 훨씬 명확해졌습니다.

 

직접 서버를 짜보고 나서야 이런 판단이 가능해졌다고 생각합니다. 그리고 이건 단순히 서버 문법을 익혔기 때문이 아닌 것 같습니다. 시지프가 슬랙에서 이런 말을 했습니다. React 코드를 잘 짜기 위해 React만 판다고 되는 게 아니라는 것. setState를 props로 넘기지 말라는 React 안티패턴은, 객체지향의 캡슐화나 Tell Don't Ask 같은 원칙을 알고 있으면 자연스럽게 도출되는 문장인 것. React의 좋은 코드 원칙도 결국 소프트웨어 일반 원칙에서 기인한다는 메시지였습니다.

 

서버 공부도 마찬가지인 것 같습니다. 서버를 조금 배웠기 때문에 API 설계를 잘하게 된 것이 아닙니다. 서버를 배우는 과정에서 책임을 어디서 나눌 것인지, 어떤 단위로 리소스를 표현할 것인지, 클라이언트와 서버가 어디까지 서로의 사정을 알아야 하는지를 생각하게 됩니다. 그 생각의 근거가 소프트웨어 일반 원칙이고, 그 원칙은 React를 짤 때도 똑같이 작동합니다. 프론트엔드가 서버를 배워야 하는 이유가 풀스택이 되기 위해서만이 아닌 것처럼, 근본을 키우기 위한 공부는 특정 기술 안에 머물지 않습니다.

 

그러면서 하나의 질문이 생겼습니다. API는 결국 프론트엔드가 사용하는 인터페이스입니다. 어떤 데이터를 어떤 형태로 필요로 하는지 가장 구체적으로 알고 있는 쪽도 프론트엔드가 아닐까요. 백엔드는 데이터를 어떤 형태로 내려줘도 내부 로직에는 큰 차이가 없는 경우가 많겠지만, 프론트는 그 데이터를 직접 화면에 그려야 하기 때문에 유저 관점에서 필요한 형태가 훨씬 구체적으로 정해져 있습니다. 그렇다면 API 설계를 프론트엔드가 더 적극적으로 주도하는 방향이 오히려 자연스럽지 않을까요. 개인적으로는 그런 시대가 오지 않을까 생각합니다. 그리고 그 질문 자체가, 서버를 직접 짜보기 전까지는 떠오르지 않았을 질문이라는 게 중요한 것 같습니다.

 

결국 AI 시대에 프론트엔드로 성장한다는 것은, 더 많은 도구를 쓸 줄 아는 것이 아닌 것 같습니다. 도구가 내놓은 답의 맥락을 읽을 수 있는 사람이 되는 일이라고 생각합니다. 그리고 그러려면 한 번쯤은 직접 틀려봐야 합니다. flat 한 구조를 직접 만들어봐야 왜 레이어를 나누는지가 보이고, PUT을 직접 골랐다 피드백을 받아봐야 PATCH가 왜 더 자연스러운지가 납득이 된다고 생각합니다. 그리고 그 납득이 쌓이면, 이번에는 내가 먼저 질문을 던질 수 있는 사람이 됩니다.

 

강제가 없었다면 하지 않았을 공부가 지금 생각하면 가장 필요한 공부였습니다.

 

아.. 우테코는 이 얼마나 좋은 수련 공간인가요.