본문 바로가기
⚒️ Projects

[프로젝트 후기] 프로젝트 공유 사이트, Gallery:port

by vodkassi 2021. 8. 10.
728x90

 

Intro


프로젝트를 시작할 때 좋은 아이디어를 떠올리기란 여간 힘든 일이 아니다.

아이디어를 참고하기 위해 개발자들이 많이 쓰는 github 과 같은 오픈 소스 플랫폼을 사용하는데,
코드만 적혀있어서 읽기 싫었던 적이 한두번이 아니었다.

우리 팀은 여기서 아이디어를 얻었고
시각적으로 바로바로 프로젝트를 볼 수 있는 공간을 만들었다.

 

당신의 프로젝트를 공유하고,
여러 작품과 소통할 수 있는 공간,
Gallery:port


Landing Page

 

 

첫 웹개발 프로젝트, 2주간의 모험


이론 강의 수강을 마치고 드디어 고대하던 (?) 프로젝트를 하게 되었다. 당연한 얘기겠지만, 자습이나 과제 실습만으로는 채워지지 않는 부분들이 굉장히 많다. 무수히 많은 오류를 만날 기회도 상대적으로 적고, 가이드 없이 백지에서 시작해 아름다운 그림(코드 아키텍쳐)를 그려나갈 수도 없다. 이러한 점들을 비롯하여 부족했던 부분들이 프로젝트를 하며 많이 채워졌다. 한 마디로, 프로젝트는 단순 '공부' 이상의 '경험'을 얻을 수 있는 시간이었다.

원하던 백엔드 포지션으로 드디어 프로젝트를 하게 되다니, 첫날부터 두려움과 설렘에 휩싸였다. 워낙 도전해보고 싶었던 것들도, 제대로 공부해보고 싶었던 것들도 많았는데, '이번 기회에 다 해봐야지!' 하는 뚜렷한 의지도 있었다.

2주간의 첫 프로젝트가 끝난 지금, 한 줄로 후기를 정리하자면 마치 김병만 없이 정글을 탐험하는 것과 같은 경험이었다. 백과사전으로 정글을 간접 체험하기만 했던 내가 직접 정글에 투입되어 서바이벌을 하는 꼴이었다. 자유도가 큰 만큼 어려움과 괴로움으로 가득하기도 했지만, 무엇보다 모든 것을 뛰어넘는 즐거움을 만끽할 수 있었다.



Project Page

 

 

순조로웠던 첫 시작


프로젝트에서 제일 중요한 요소 하나를 꼽으라면 나는 스택도 주제도 아닌 "함께하는 팀원" 이라고 답할 것이다. 함께 일하는 사람이 누구냐에 따라 팀의 역량이 커지기도, 축소되기도 한다고 믿기 떄문이다.

나는 본격 팀 배정 이전에 함께 하자는 연락을 받았던 터라, 며칠 일찍부터 미리 팀원들을 알아갔다. 이 기간동안 많은 것을 하지는 않았지만 한 두번의 화상 모임을 통해 각자 소개를 하고, 가볍게라도 친해지는 시간을 가지게 되었다. 프로젝트 기간에 본격 들어간 뒤에는 필수 항목이었던 프로젝트 주제, 팀원 포지션, 사용 스택 등을 함께 정해갔다.

이 시기는 마치 정글을 함꼐 모험할 단원들끼리 구체적인 탐험지를 선정하고 각자 역할에 따라 준비물을 챙기는 과정과 비슷하다. 다행히 우리 팀은 각자 잘하는 것이 명확해서 서로의 포지션을 욕심내지 않고 잘하는 분야에 집중할 수 있었다. 서로의 역할에 대한 계획과 기대하는 바를 공유하며, 모두가 프로젝트를 통해 최대한 많은 것을 얻어갈 수 있도록 조율했다.



Sign Up Page

 

 

백엔드로서의 책임감


왜 프론트엔드는 지망하지 않았는가? 묻는다면 나는 확신에 찬 목소리로 "CSS 때문에요" 라고 말할 수 있다. 사실 프론트엔드에서 로직을 짜는 일도, SPA 가 효율적으로 작동하록 설계하는 일도 매우 재밌지만, 결국 나는 근본적으로 UI 나 그래픽 (그리고 CSS)와는 거리가 먼 사람이었다. 무엇보다 백엔드에서 캐싱, 세션, DB, 네트워크를 배울 때의 즐거움이 훨씬 컸기 때문에 마치 본능처럼 백엔드에 이끌렸다.

기획 단계에서는 항상 촉을 세워두고 '백엔드 파트에서 놓치는 부분'이 없는지 생각했다. 팀원들과 세부 기능을 논의할 때는 특히 신중하지만 정확하게 판단을 내려 우리의 서비스에 알맞는 기능을 구상할 수 있도록 지원했다.

가령 로그인 로그아웃 기능을 논할 떄는 사용자 인증을 어떻게 할 것이며 로그인 상태를 어떻게 유지할 것인지 계속 떠올리며 회의에 참여하여, 프론트 측과의 협업이 필요한 부분이 있다면 짚고 넘어갔다. 또한 단순히 기능 구현만을 생각하기보다는 데이터 플로우의 감을 잡기 위해 '이 기능을 구현하려면 어떤 쿼리를 날려야 하나?' 생각하며 진행했다. 이러한 고민을 기반으로 사용하게 될 DB 패러다임과 데이터 스키마를 미리 머릿속에 그려놓을 수 있었다.

첫 프로젝트였기 때문에 백엔드 지식에 대한 자신감도 많이 없었고, 실제로 모르는 것이 더 많았다. 그럴 때마다 메모를 남기거나 같은 백엔드 포지션 팀원과 회의에 회의를 거쳐 기능을 논리적으로 풀어나갔다.

코드의 90%는 손글씨와 머리로 짜고 나머지 10%만 컴퓨터로 짜는 것이라고 한다. 그만큼 코딩하기 전 코드의 구조와 설계가 중요하다는 것인데, 프로젝트에서도 역시 설계가 제일 중요하다고 생각했다.

(실제로 설계가 제대로 되어있는 부분은 코드 치고 디버깅하는 시간이 훨씬 적었고, 설계가 엉성하고 엉망진창이었던 부분은 실제로 기능을 구현할 때 꽤나 고생했다.)

이 지점에서 백엔드 개발자로서 간과했던 부분과 잘했던 것이 대표적으로 한 개씩 있다. 우선 간과했던 부분은 각 HTTP 요청마다 db에서 어떤 데이터를 조회하고 어떻게 활용할지 더 구체적으로 생각해보지 않았다는 점이다. 하나의 GET 또는 POST 요청이 들어와도 구현하고자 하는 기능에 따라 단순 findOne 또는 create 보다 훨씬 더 많은 쿼리 작업을 하게 되는데 , 이 내용이 설계가 잘 안 되어있다보니 불필요한 이중 삼중 쿼리를 날려 성능을 낭비하기도 했다.

다행히 미들웨어로 도입했던 부분 (jwt token, multer) 에 있어서는 설계가 구체적이었던 덕에 기능의 완성도를 다소 높일 수 있었다. 설계에 오랜 시간이 걸리긴 했어도 코드 작업과 기능 구현은 거의 하루 안에 완성했다. 물론 나중에 생기는 에러들은 디버깅해야 했지만, 최초 예상 소요 시간이 사흘 정도였는데 하루 안에 끝낸 것 자체가 탄탄했던 설계 덕이라고밖에 할 수 없었다.

사람들에게 프로젝트에 대한 강한 첫인상을 주는 것이 프론트엔드의 역할이라면, 그 인상이 나빠지지 않도록 뒤에서 최선을 다하는 것이 백엔드의 역할이라고 생각한다. 프론트엔드 팀원들이 낸 좋은 결과물을 허술한 백엔드로 망치고 싶지는 않았다. 좋은 서비스를 만들고, 나 개인으로서도 백엔드 포지션을 잘 해내고 싶었기 때문에 가끔은 오버하는 것 아닌가 정도로 성능과 보안, 데이터와 설계에 대해 많이 고민했다.

 

multer module 활용 설계도

 

 

그래서 설계가 왜 중요하다고?


설계는 프론트 백엔드가 기능에 대해 동일한 이해를 가지고 있는지 어떤 식으로 데이터를 주고받을지 정하는 과정이다. 이 작업을 잘 해놓으면 이후 작업할 때 원활한 분업이 이루어져 서로를 괴롭히지 않을 수 있다. 반대로 말하면, 이 작업이 재대로 안 되어 있으면 서로에게 물어봤떤 내용을 재차 물어보는 등 사소한 회의가 많아져 작업 속도가 저하될 수 있는 문제가 생긴다.

백엔드로서 설계가 중요한 이유는 이 때야말로 온전히 '성능' 을 깊이 고민할 수 있는 시간이기 때문이다. 기능 구현에 돌입하는 즉시 내가 접해보지 않았던 수많은 에러에 부딪히기 때문에 이 때 더 나은 성능을 고민하며 코드를 짜기란 (저연차 개발자로선) 불가능하다. 설계 단계에서 될 수 있는 한 모든 경우의 수를 따져보며 어떤 구조로 응답을 보낼지, 어떻게 쿼리를 짜야 속도가 빠를지 고민해 놓아야 나중에 이중 삼중으로 고생하지 않는다.


 

기능은 1%의 코드와 99%의 에러 핸들링으로 완성된다
- 나


설계를 마친 이후에는 기본적인 서버와 DB 세팅을 하고 로그인, 로그아웃을 비롯한 여러 주요 기능을 코드로 구현하게 된다. 이 시기에 나는 아마 Section 1, 2, 3 을 통틀어 만났던 에러 메세지보다 더 많은 에러 코드를 본 것 같다.

DB 연결할 때 버전 호환이 안 돼서 에러 터지고, 모델 스키마와 시드 데이터 자료형이 안 맞아서 에러 터지고, RDS 연결 끊어져서 에러 터지고, 환경변수 오타나서 에러 터지고, fs 모듈 작동 안해서 에러 터지고, 쿠키 삭제 안 돼서 에러 터지고, params 와 유저아이디 비교가 안 돼서 에러 터지고 ...

에러가 터진다는 것은 "내가 작성한 코드 어딘가" 에 문제가 있다는 걸 알려준다. 이미 잘 설계된 과제를 할 때는 이 "내가 작성한 코드"의 범위가 매우 좁았기 때문에 금방 디버깅을 할 수 있었지만, 사방을 둘러봐도 다 내 코드일 뿐인 프로젝트에서는 요령이 먹히지 않았다. 운이 좋으면 에러 메세지에 문제가 되는 위치를 알려주기도 했지만, 그러지 않은 경우도 많았다. (특히 로컬에서 작업할 때가 아닌 배포 서버에서 나는 에러는 더 잡기 힘들었다)

내 로컬에서 발생하는 에러를 다 잡았도 끝이 아니었다. 프론트엔드 개발자들이 구현한 클라이언트 코드와 연결할 때도 많은 에러를 만나게 되었고, 배포 서버에 올려 테스트를 돌릴 때도 무수히 많은 에러를 만났다. 그러다보니 기능의 기본 역할은 진작에 구현되었어도 (혹은 그렇다고 생각했어도) 내가 미리 예상하지 못했던 예외 케이스나 배포 환경 문제에 계속 시달렸다.

하지만 나는 예전부터 다른 부분은 약해도 끈기와 집념 하나만큼은 자신할 수 있는 사람이었기에 에러의 원인이 되는 코드를 끝까지 파고들었고 대부분의 경우 디버깅을 잘 해냈다. 에러와 하루종일 싸우는 동안 정말 포기하고 싶은 마음도 많이 들었지만, 결국 싸우길 잘했다는 생각이 들었다. What doesn't kill me makes me stronger (나를 죽이지 않는 것은 나를 더 강하게 만든다) 고 하던가. 힘들었던 만큼 지식의 깊이가 깊어졌고, 에러의 유형에 맞춰 확인해야 하는 부분을 파악하는 노련함이 생겼고, 무엇보다 "에러를 최소화 할 수 있는 코드 (더 많은 경우의 수를 고민한 코드)"를 설계하는 노하우를 얻었다.

에러는 있어도 불안하지만 없어도 불안한 존재이다. 에러가 발생하면 이 에러가 언제 어떻게 해결될지 몰라 불안하지만, npm start 를 실행해서 서버를 작동시켰는데 아무 에러가 터지지 않아도 '어..? 내 코드가 완벽할리 없는데..?' 하는 마음이 들며 불안하다. 그리고 후자의 경우 대체로 언젠가 더 큰 오류가 터져 돌아오기 때문에, 차라리 초반에 에러를 많이 잡아놓는 편이 좋을 지경에 이른다. 때문에 코딩과 에러는 떼어놓을 수 없는 불가분의 존재임을 받아들이고, 더 좋은 에러 싸움꾼이 되기 위해 성장하는 수밖에 없다.



Profile Update Page

 

 

기본기와 응용의 중요성


개발자가 되어야겠다는 다짐을 한 이후 정말 많이 들었던 얘기가 "기본기를 탄탄하게 잡아야 한다"는 말이었다. 이 때는 왜 그런가 싶었는데, 확실히 프로젝트를 하다 보니 기본기가 없으면 꽤나 고생했겠다는 생각이 드는 순간이 많았다.

이번에 깨달은 기본기가 중요한 이유는, 응용력의 발판이기 때문이다. 함수의 원리를 모른다면 함수를 응용해서 사용할 수 있는 순간임에도 반복문 100줄을 짜게 될 수 있다. 마찬가지로 기본 웹, CS 지식이 탄탄하지 않다면 문제를 직면했을 때 지식을 응용해서 해결하기 어렵다.

가령, 백엔드 단에서 프론트엔드에게 이미지가 저장된 url 을 전달해야 하는 케이스가 있었다. 구글링을 통해 얻은 자료의 대부분은 S3 버킷에 이미지를 올린 뒤 해당 이미지의 url 을 반환하는 방식을 택하고 있었으나, 서버의 local storage 에 이미지를 저장해 작업하고자 했던 우리의 방식과 맞지 않았다. 아키텍처를 엎고 제공된 자료의 방식에 맞춰 이미지 저장소를 S3 로 바꿀 수도 있었으나, 서버의 기본 특성을 응용해 우리 서버에 올라온 이미지의 위치를 찾아주는 get 요청을 처리하는 url 을 만들면 될 것이라는 생각이 들었다. 따라서 클라이언트에서 이미지명을 path 에 입력해 지정된 url 로 get 요청을 날리면, 서버에서는 res.sendFile 로 이미지를 반환하여 클라이언트 측에서 이미지 소스를 바로 받아올 수 있게끔 했다.

매우 간단하고도 기본적인 해결 방법이었지만, 구글링을 통해 얻은 자료를 가져다 사용하기만 하는 것이 아니라 우리 서비스에 적합한 방법을 고안해낸 좋은 경험이 되었다. 프로젝트를 하다 보면 구글에 있는 코드를 그대로 가져다 기능을 구현하고 싶을 때가 생기는데, 무지성 복제를 한다면 결국 문제가 발생했을 때 이를 해결할 실마리가 되는 '코드에 대한 이해'가 부족하여 결국 새로 뜯어고치게 된다. 기본적인 지식을 쌓는 것도, 활용하는 것도, 내가 작성하는 코드의 원리를 잘 파악하고 있는 것도 전부 좋은 코드의 근원이라는 사실을 체감했다.



Project Upload Page

 

 

2주 프로젝트 한 줄 평:
몸은 죽어나지만 정신은 행복하다


2주 내내 2시 이후에 잠들고 아침 8시반에 일어나 9시부터 작업하는 일정이 반복되었다. 그러다 보니 몸은 정말 힘들었지만 정신적으로는 말로 표현할 수 없을 정도로 즐거웠다. 자칭타칭 "팀플학과"로 불리는 과에서도 대외 활동을 통해서도 팀플을 정말 많이 해봤지만, 이번 프로젝트는 여태 했던 모든 팀플 중 제일 재밌었다고 자부할 수 있다. 그만큼 백엔드에 대한 애정이 커졌고, '개발' 자체에 대한 매력에 완전히 빠져버렸다.

팀원에 대한 감사함도 굉장히 크다. 모든 과정이 온라인으로 이루어졌음에도 불구하고 갈등 한 번 없이 원활히 소통했으며, 누군가 이해가 안 되는 부분이 생기거나 도움이 필요한 내용이 생기면 팀원들 모두가 적극적으로 문제 해결에 참여했다. 분업을 통해 맡은 부분도 개인 선에서 최대한 완성도를 높여 팀원들로부터 건설적인 피드백을 받을 수 있도록 했다. 무엇보다 모두가 다 열정적인 자세로 임해주었기 때문에 끝까지 힘 빠지지 않고 완주할 수 있었다.

자주 쓰이는 비유지만 프론트엔드는 집을 지을 때 벽돌을 쌓고 변기를 설치하고 페인트칠을 하는 사람이라면, 백엔드는 도어락을 설치하고 전선과 배관을 연결하고 티비가 나오도록 안테나도 달아주는 사람이다. 하나의 역할 없이 다른 하나가 완성될 수 없으며, 그렇기에 협업과 소통은 매우 중요하다.

아쉬운 점은, 백엔드는 잘 드러나지 않는 부분이라 사람들의 호응을 유도하거나 즉각적인 피드백을 받기는 다소 어렵다는 사실이다. 그리고 확실히 백엔드는 제대로 알고 제대로 적용하기 쉽지 않은 부분이 많은지라 단기간에 시도해보지 못한 것이 많은 것도 아쉽지만, 그렇기 때문에 지금보다 더 많이, 그리고 잘 공부해야겠다는 투지를 다졌다.



SignOut (Remove Cookies)

 

 

다시 처음으로 돌아간다면?


이 프로젝트를 처음부터 다시 시작하거나, 새 프로젝트를 시작하게 된다면 이렇게 할 것이다! 싶은 내용들을 마지막으로 정리하며 마무리해본다.

 

- 서버 & 클라이언트 모두 전체 뼈대를 잡아주는 폴더와 파일을 먼저 만든다. 서버의 경우 routers, controllers 등의 폴더 (& 파일) 이 있고, 클라이언트의 경우 Components, Pages 등의 폴더 (& 파일) 이 있다.

- 클라이언트-서버 간 구체적인 기능을 구현하기에 앞서 각 기능별 간단한 request-response 를 주고받음으로써 CORS 에는 이상이 없는지, 쿠키 또는 헤더 정보는 잘 전달되는지 테스트한다.

- 로컬 환경과 배포 환경의 차이를 잘 숙지하고, 로컬 환경이 잡아주는 소소한 에러를 간과하지 않는다. 배포 환경과 같은 개발환경을 쓰는 팀원이 있다면 해당 팀원과 미리 클라이언트 & 서버 연결 테스트를 시도한다.

- 기획에 시간을 더 들이더라도 세세한 내용까지 미리 논의한다. 가령 어떤 버튼을 클릭하면 어떤 요청이 날라오고 어떤 응답에 따라 alert 창이 뜨는지까지 서로 파악하고 있는다.

 

 

놀러오세요, Gallery:port 에

'⚒️ Projects' 카테고리의 다른 글

[프로젝트 후기] IT 트렌드 매거진, DEVzine  (0) 2021.09.12

댓글