
단순한 CRUD를 넘어, 그날 먹고 싶은 마음에 가까워지는 방향으로
참고용 github: https://github.com/js-kim-arc/hidden-gem
내일배움캠프 초반 미션 중 하나로 맛집 리스트 서비스를 구현해보는 과제가 있었다.
처음에는 맛집 정보를 등록하고, 조회하고, 수정하고, 삭제하는 비교적 단순한 기능이라고 생각했다.
하지만 막상 시작해보니 프론트엔드 구조를 이해하고, 상태를 다루고, 데이터 흐름을 설계하고, 사용자 경험까지 함께 고민해야 했다.
생각보다 훨씬 많은 요소가 들어 있는 미션이었다.
이번 글에서는 이 미션을 진행하면서 겪었던 초기 어려움과,
단순한 리스트 기능에서 한 걸음 더 나아가 ‘그날 먹고 싶은 것을 떠올리게 돕는 서비스’ 로 확장해보고 싶었던 기획 방향까지 함께 정리해보려고 한다.
초기 미션의 핵심은 비교적 명확했다.
기본적으로는 맛집 정보를 등록하고, 조회하고, 수정하고, 삭제하는 CRUD 로직을 구현하는 것이었다.
여기에 더해 단순히 데이터만 다루는 것이 아니라,
직접 화면을 만지고 바꾸어 보면서 프론트엔드가 데이터를 어떻게 보여주고, 어떤 흐름으로 조작하는지 경험해보는 것도 중요한 목표였다.
특히 이번 미션에서는 실제 서버를 바로 붙이기보다는,
Mock API 서버를 기반으로 임시 데이터를 다루는 방식으로 진행했다.
즉, 완성된 백엔드가 없는 상황에서도 프론트엔드에서 요청을 보내고 응답을 받아보며,
하나의 작은 서비스가 어떻게 움직이는지를 먼저 체감하는 과정에 가까웠다.
이 방식은 개인적으로 꽤 의미 있었다.
나는 백엔드 개발을 중심으로 공부해왔지만, 실제 서비스는 결국
화면에서 입력하고, 상태가 바뀌고, 다시 사용자에게 보이는 흐름 전체로 작동한다.
그렇기 때문에 초기 단계에서라도 프론트엔드를 직접 다뤄보는 경험은
단순한 “화면 구현” 이상의 의미가 있었다.

이번 미션에서 가장 먼저 부딪힌 어려움은 기능 자체보다도
React.js와 JavaScript 생태계에 대한 익숙하지 않음이었다.
기존에는 Java와 Spring 중심으로 사고하는 시간이 많았기 때문에,
프론트엔드에서 흔히 사용하는 구조들이 처음에는 꽤 낯설게 느껴졌다.
초반에 특히 어렵게 다가왔던 부분은 다음과 같았다.
처음에는 기능을 빨리 만들고 싶은 마음이 앞섰다.
하지만 그럴수록 구조를 제대로 이해하지 못한 채 억지로 붙이게 될 것 같았다.
그래서 먼저 React 컴포넌트 구조, JSX 문법, Node 기반 패키지 관리 방식과 관련된 문서들을 읽으면서
전체 흐름을 이해하려고 했다.
이 과정에서 느낀 점은 분명했다.
프론트엔드는 단순히 “화면을 예쁘게 만드는 영역”이 아니었다.
오히려 상태를 나누고, 책임을 분리하고, 사용자의 행동에 따라 즉각적으로 반응하는 흐름을 설계하는 영역에 더 가까웠다.
그리고 이 부분은 백엔드에서 도메인과 책임을 나누는 감각과도 생각보다 닮아 있었다.
그래서 비교적 빠르게 이해해나갈 수 있었던 것 같다.

이번 미션에서 사용한 Mock API는
실제 백엔드를 붙이기 전에, API처럼 데이터를 주고받는 흐름을 먼저 만들어볼 수 있는 도구다.
백엔드 개발자 관점에서 보면, 프론트엔드가 서버 없이도
조회, 생성, 수정, 삭제 같은 기본 요청 흐름을 미리 맞춰볼 수 있게 해주는 임시 인터페이스라고 볼 수 있다.
쉽게 말하면 아직 Spring 서버나 DB를 본격적으로 구성하지 않았더라도,
프론트엔드는 GET, POST, PUT, DELETE 같은 요청을 보내고
그에 맞는 응답을 받아보면서 화면과 데이터 흐름을 먼저 검증할 수 있다.
즉, “나중에 실제 서버가 들어올 자리”를 임시로 흉내 내주는 역할에 가깝다.
Mock API의 장점은 분명하다.
가장 큰 장점은 빠르게 붙여볼 수 있다는 점이다.
초기 기획 단계나 화면 개발 단계에서 백엔드가 완성되기를 기다리지 않고도
리스트를 불러오고, 데이터를 추가하고, 수정하고, 삭제하는 기본 동작을 바로 실험할 수 있다.
특히 프론트엔드와 협업할 때는 API 명세의 큰 틀을 먼저 맞춰보고,
데이터 구조나 요청/응답 형태를 가볍게 검증해보기에 좋다.
다만 한계도 분명하다.
Mock API는 어디까지나 실제 비즈니스 로직이 들어간 서버는 아니다.
복잡한 유효성 검증, 인증과 인가, 트랜잭션 처리, 예외 상황 제어,
연관관계가 있는 데이터 관리, 실제 DB 설계 같은 부분은 결국 실제 백엔드에서 다시 다뤄야 한다.
그래서 Mock API는 운영용 서버라기보다는,
초기 개발에서 흐름을 맞추고 인터페이스를 확인하기 위한 가벼운 실험 도구에 더 가깝다.
정리하면 Mock API는 백엔드가 완성되기 전 단계에서
API의 형태를 먼저 흉내 내고, 화면과 데이터 흐름을 빠르게 검증할 수 있게 해주는 임시 서버 도구다.
실제 서버를 대체하는 것은 아니지만,
서비스를 처음 만들 때 프론트엔드와 백엔드 사이의 연결 감각을 익히기에는 꽤 유용한 출발점이라고 느꼈다.
이번 미션을 진행하면서 자연스럽게 들었던 생각 중 하나는
“이걸 그냥 순수 HTML, CSS, JavaScript로 만들 수도 있었을 텐데 왜 React를 쓰는 걸까?” 였다.
작은 기능만 놓고 보면 순수 JavaScript로도 충분히 구현할 수 있다.
실제로 버튼을 누르면 데이터를 불러오고, 목록을 그리고, 수정하고, 삭제하는 기본 흐름 자체는
굳이 React가 아니어도 만들 수 있다.
하지만 화면이 조금만 복잡해지기 시작하면 차이가 점점 드러난다.
순수 HTML, CSS, JavaScript 방식의 장점은 분명하다.
가장 큰 장점은 구조가 단순하고 직관적이라는 점이다.
브라우저가 어떻게 동작하는지, DOM이 어떻게 바뀌는지, 이벤트가 어떻게 연결되는지를
비교적 직접적으로 볼 수 있다.
즉, 화면을 직접 선택하고(querySelector),
필요한 부분의 내용을 바꾸고(innerHTML, appendChild),
이벤트를 붙이는 흐름이 눈에 바로 보인다.
이 방식은 작은 프로젝트나 간단한 페이지에서는 오히려 빠르고 가볍다.
불필요한 설정이 적고, 번들링이나 컴포넌트 구조를 크게 고민하지 않아도 되기 때문이다.
다만 단점도 분명하다.
기능이 늘어나고 화면이 복잡해질수록
어느 DOM을 언제 바꿔야 하는지 직접 관리해야 하는 부담이 커진다.
예를 들어 리스트 하나를 수정할 때도
단순히 데이터만 바꾸는 것이 아니라,
그 변경이 화면 어디에 반영되어야 하는지 직접 찾아서 다시 그려야 한다.
즉, 상태와 화면이 커질수록
코드가 점점 DOM 조작 중심으로 흘러가기 쉽고,
이벤트와 렌더링 로직이 뒤섞이면서 유지보수가 어려워질 수 있다.
React의 큰 장점 중 하나는
DOM을 직접 하나하나 조작하는 부담을 줄여준다는 점이다.
React에서는 개발자가 화면의 최종 상태를 중심으로 생각한다.
즉, “데이터가 이 상태면 화면은 이렇게 보여야 한다”를 선언적으로 작성하면,
실제 DOM 반영은 React가 처리해준다.
이때 자주 이야기되는 것이 가상 DOM(Virtual DOM) 이다.
React는 상태가 바뀌었을 때
실제 DOM을 무작정 전부 다시 건드리는 것이 아니라,
가상 DOM을 통해 이전 상태와 새로운 상태를 비교하고
바뀐 부분만 효율적으로 반영하려고 한다.
그래서 개발자는 순수 JavaScript처럼
“이 요소를 찾고, 지우고, 다시 넣고, 이벤트를 다시 걸고…”
이런 식으로 매번 직접 DOM을 관리하지 않아도 된다.
특히 리스트, 폼, 조건부 렌더링, 재사용되는 UI 조각이 많아질수록
React의 장점은 더 커진다.
다만 React가 항상 정답인 것은 아니다.
React도 결국 학습 비용이 있다.
처음 접하면 다음과 같은 개념들이 꽤 낯설다.
즉, 순수 JavaScript보다
처음에는 더 많은 개념을 이해해야 하고,
프로젝트 설정이나 구조도 조금 더 무겁게 느껴질 수 있다.
또한 아주 단순한 정적 페이지나 작은 기능만 구현한다면
React의 구조가 오히려 과하게 느껴질 수도 있다.
이럴 때는 순수 JavaScript가 더 빠르고 단순할 수 있다.
정리하면 순수 JavaScript와 React는
누가 절대적으로 더 좋다기보다 어떤 상황에 더 적합한가의 차이에 가깝다.
내가 느낀 가장 큰 차이는 이것이었다.
순수 JavaScript는
“DOM을 직접 움직이며 화면을 만든다” 는 느낌에 가깝고,
React는
“상태를 관리하면 화면은 React가 맞춰준다” 는 느낌에 가까웠다.
즉, 순수 JavaScript는 제어권이 직접 손에 있는 대신
규모가 커질수록 관리 비용이 커지고,
React는 처음 배울 것은 더 많지만
복잡한 화면에서는 그 관리 부담을 꽤 줄여준다.
특히 이번처럼 리스트를 보여주고, 수정하고, 삭제하고, 다시 반영하는 흐름에서는
React가 왜 많이 쓰이는지 조금 이해할 수 있었다.
결국 핵심은 성능 하나만이 아니라,
상태와 화면을 연결하는 복잡성을 줄여주는 구조적 장점이 크다고 느꼈다.
순수 JavaScript는 작고 단순한 화면에 강하고,
React는 상태 변화가 많은 복잡한 화면을 구조적으로 관리하는 데 강하다.
그래서 둘의 차이는 단순히 “무엇이 더 빠른가”보다
무엇을 더 쉽게 만들고, 더 오래 유지할 수 있는가의 트레이드오프로 보는 것이 더 적절하다고 생각한다.
기본 미션을 수행하면서 점점 이런 생각이 들었다.
사람들은 항상 “오늘 정확히 무엇을 먹고 싶은지”를 명확하게 알고 있지는 않다.
오히려 대부분은 메뉴 이름보다 먼저 느낌을 떠올린다.
예를 들면 이런 식이다.
즉, 사용자는 음식 이름을 먼저 떠올리기보다
날씨, 계절, 컨디션, 분위기 같은 감각적인 단서를 먼저 느끼는 경우가 많다.
그래서 단순히 “맛집을 저장하는 리스트”를 넘어서,
계절감과 날씨감을 기준으로 그날의 음식점을 떠올리게 돕는 방향으로 확장해보면 재밌겠다고 생각했다.
여기서 중요한 점은 “정답 같은 추천”이 아니었다.
무조건 많은 사람에게 통하는 표준화된 추천보다,
내가 평소에 저장해둔 맛집들 중에서 오늘의 분위기에 맞는 곳을 다시 꺼내주는 흐름이 더 매력적으로 느껴졌다.
이 관점에서 보면 서비스의 역할은 크게 달라진다.
단순 맛집 저장 서비스는 정보를 쌓아두는 역할에 가깝다.
반면, 날씨나 계절을 기준으로 다시 보여주는 구조는
사용자의 기억 속에서 애매하게 떠다니는 취향을 그날의 맥락 안에서 다시 호출하는 역할을 하게 된다.
나는 이 차이가 UX적으로 꽤 중요하다고 느꼈다.
사용자는 늘 새로운 정보를 원한다기보다,
사실은 이미 알고 있는 것 중에서 오늘 나에게 맞는 것을 빨리 찾고 싶어하는 경우가 많기 때문이다.
이 미션을 하면서 점점 더 선명해진 것은
맛집 서비스의 본질이 단순히 “등록한다”에 있지 않다는 점이었다.
오히려 중요한 것은 언제, 어떤 맥락에서 다시 꺼내 보여주느냐였다.
UX 관점에서 보면 사용자는 리스트를 길게 쌓아두는 순간부터 피로해진다.
저장할 때는 만족스럽지만, 나중에 다시 보려고 하면 항목이 많아져서 오히려 고르기 어려워진다.
결국 저장은 했지만 활용은 잘 안 되는 상태가 된다.
그래서 이후에는 이런 방향을 생각하게 되었다.
비 오는 날, 쌀쌀할 때, 봄 저녁, 혼밥, 기분 전환 같은 태그를 붙이기이때 핵심은 거창한 AI 추천 시스템이 아니다.
오히려 초반에는 훨씬 단순해도 된다.
중요한 것은 완벽한 추천 정확도가 아니라,
사용자가 “맞아, 오늘은 이런 게 먹고 싶었어” 라고 느끼게 만드는 작은 계기를 제공하는 것이다.
이런 점에서 이 서비스는 단순한 맛집 보관함보다
취향의 회상 장치에 더 가깝게 설계할 수 있다고 느꼈다.
초기 단계에서는 데이터 저장과 API 흐름을 빠르게 실험해보기 위해
Mock API 기반으로 임시 운용하는 방식이 적절했다.
실제 DB를 설계하고 서버를 정교하게 구성하기 전에,
우선은 화면과 데이터 흐름이 자연스럽게 이어지는지 빠르게 확인할 수 있기 때문이다.
하지만 이 구조는 어디까지나 시작점이다.
이후에는 자연스럽게 Spring 백엔드로 연결해볼 계획을 가지고 있다.
백엔드 관점에서 보면 다음 단계에서 다뤄볼 수 있는 요소들도 꽤 분명하다.
특히 흥미로운 부분은 단순한 맛집 CRUD가
나중에는 상황 기반 추천 시스템의 아주 작은 출발점이 될 수 있다는 점이다.
예를 들어 지금은 단순히
“오늘 비가 오면 국물류 태그가 붙은 음식점을 먼저 보여준다”
정도의 규칙 기반 로직으로 시작할 수 있다.
하지만 이후에는 사용자의 선택 이력을 바탕으로
“비 오는 날에도 이 사용자는 전보다 매운 음식을 더 자주 선택한다”
같은 식으로 점점 개인화된 흐름으로 발전시킬 수도 있다.
즉, 지금 단계의 임시 구조는 단순한 미완성이 아니라
빠르게 가설을 검증하기 위한 실험용 토대라고 볼 수 있다.
이번 맛집 리스트 미션은 겉으로 보면 작은 CRUD 프로젝트처럼 보일 수 있다.
하지만 나에게는 그보다 훨씬 더 큰 의미가 있었다.
익숙하지 않은 프론트엔드 환경 안에서도
문서를 읽고 구조를 이해하면서 문제를 하나씩 풀어가는 경험을 했다.
기능을 구현하는 것을 넘어서
“사용자가 왜 이 기능을 쓰고 싶어할까?” 를 생각해보게 되었다.
백엔드 입장에서도 처음부터 무거운 구조를 올리기보다
가볍게 Mock 환경으로 시작해서 흐름을 검증하고,
이후 Spring 기반 구조로 확장하는 접근이 꽤 현실적이라는 점을 다시 느꼈다.
무엇보다도 가장 인상 깊었던 것은,
작은 미션 하나도 단순히 주어진 기능만 구현하는 데서 끝나지 않고
사용자의 애매한 욕구를 어떻게 더 잘 다룰 수 있을지 상상하는 순간
훨씬 더 살아 있는 서비스 기획으로 바뀐다는 점이었다.
이번 미션은 맛집을 등록하고 관리하는 간단한 기능에서 출발했다.
하지만 그 안에서 나는 단순한 리스트보다 더 중요한 것은
그날의 맥락 속에서 사용자가 원하는 선택지를 다시 떠올리게 만드는 경험이라는 생각을 하게 되었다.
아직은 Mock API 기반의 작은 시작점에 가깝고,
실제로는 기본적인 맛집 리스트 기능을 먼저 안정적으로 만드는 것이 우선이다.
하지만 그 다음 단계에서는 날씨, 계절, 분위기 같은 요소를 붙여
조금 더 개인의 감각에 가까운 방식으로 확장해보고 싶다.
결국 서비스는 데이터를 저장하는 것에서 끝나지 않는다.
사용자가 필요할 때, 필요한 형태로 다시 꺼내 쓸 수 있어야 한다.
이번 미션은 그 아주 작은 시작을 경험해본 과정이었다.