인턴 회고

Y·2023년 1월 9일
1

회고

목록 보기
1/1

2022.09.01 - 2022.12.30, 4개월간의 현장 실습 인턴 기간이 종료됐다. 인턴 기간동안 배운 점에 대해서 회고 글을 정리해보자 한다. 각 일자별로 TIL을 작성하기는 했었는데, 기간이 길었기 때문에 모든 일자의 회고를 올리기 보다는 간략하게만 정리하려고 한다.

담당 업무

내가 현장 실습 인턴으로 일한 곳은, 이제 막 서비스 기획을 마친 단계에서 서비스 개발을 시작하는 극초기 스타트업이었다. 나는 인턴이자 사내의 유일한 개발자로 서비스할 앱의 백엔드 개발 및 인프라 업무를 담당했다.

기술 스택

기술 스택 선정은 자율에 맡기셨는데, 사측에서 안정성 있는 개발과 추후 구인이 수월한 스택을 원하여서 spring boot를 선택하였다. DB의 경우 사측에서 권유하기도 했고, 스타트업 특성상 기획 변동이 심하며, 빠른 개발이 필요하며 Atlas를 이용하면 관리가 용이하기 때문에 MongoDB를 선택했다. 인프라의 경우에는 관리를 용이하게 하기 위하여 AWS를 선택했다.

업무 회고

내가 입사했을 때, 회사에서 진행되고 있거나 완료된 업무는 앱의 전체적인 (대략적) 기획, UI 디자인이었다. 그래서 기획서를 기반으로 하여 전반적인 앱의 기획에 대한 설명을 듣고, 개발적 관점에서 검토하는 과정을 거쳤다. 기획 파트에서 빠져있는 부분이나, 추가 기획이 필요한 부분에 대해서 지속적으로 소통을 하면서 기획 수정을 진행했다. (여러 차례 기획 수정을 함께 진행하고, 검토를 했는데도 나중에 개발 하다보니까 빠진 부분이 있어서 계속 추가 기획을 부탁드렸던 것 같다...) 이후에 API, DB 설계를 했다.

API 및 DB 설계

먼저 API의 경우 이전에는 소규모 프로젝트였던데다가 클라이언트단과 협업을 바로 같이 했었기 때문에 문서에 크게 신경을 쓰지 않았는데, 이번에는 외주 개발자 분과 같이 일했기 때문에 제대로 명세서를 작성할 필요가 있었다. API 명세서를 어떻게 작성해야할지에 대해 고민하다가 인터넷에 올라와있는 여러 샘플들과, 네이버 API 명세, 쿠팡 API 명세, 카카오 API 명세 등의 양식을 참고해서 작성했다.

또한 설계 과정의 경우 일단 기획서를 바탕으로 필요한 기능들을 추출해내고, 그 기능들에 필요한 API를 목록으로 작성한 다음 각 API 목록에 대한 명세서를 작성하면서 대략적인 설계를 하는 방식으로 진행했다. API 명세를 작성하면서 전체적인 틀을 잡을 수 있었고, 이 과정을 통해서 전반적인 백엔드 개발의 설계도 할 수 있었던 것 같다.

기획과 그를 기반으로 한 API 설계를 기준으로 DB 테이블(몽고DB 기준으로는 Document가 맞겠지만 편의상 테이블로 서술하겠다!)을 나누고, 각 테이블의 스키마를 설계했다. (RDB가 아닌지라 정규화 과정 등 까지는 거치지 않았다.) 실제로 개발을 진행하면서도 기획 변경 때문에 DB 변경이 잦았어서, mongoDB로 선택하기를 잘 했다고 생각했다. 그리고 빠진 부분들도 발견이 돼서 처음 DB 설계를 할 때 좀 더 꼼꼼히 설계를 했어야 했다는 반성도 했다. 사실 혼자 개발을 하다보니까 여러 번 확인한다곤 해도 설계 과정에서 놓친 부분들이 어쩔 수 없이 꽤 발생하는 것 같은데, 이래서 협업이 정말 필요하구나 다시 한 번 느꼈다.

백엔드 개발

클라이언트는 외주를 맡기기로 했는데, 외주사 선정이 생각보다 시간이 오래걸려서 우선적으로 백엔드 개발을 먼저 시작했다. spring boot 공부를 하긴 했지만 제대로 된 프로젝트를 진행한 건 처음이었고, 그래서 아주 익숙하지는 않았어서... 그리고 java 자체도 오랜만에 쓴지라 처음에는 좀 헤맸는데 계속 하다보니까 금방 익숙해졌다.

다른 API 기능 개발보다는 아무래도 회원가입, 로그인, 로그아웃과 관련된 부분이 가장 오래 걸렸던 것 같다. 그냥 spring security를 통해 세션 기반으로 할 수도 있었겠지만, 서버 관리를 고려했을 때는 JWT를 사용하는 것이(물론 JWT의 보안성에 대해서도 논의가 있고, 완벽하지 않다는 것은 알고있지만) 좋을 것이라고 생각해서 spring security+JWT의 구조로 진행했다. 실제 사용자들에게 서비스된다고 생각하니 보안 부분을 고려하지 않을 수가 없었는데, 로그인과 회원가입까지는 구현을 했는데 로그아웃이 생각보다 좀 복병이었다. 관련 자료도 많지 않았고... 찾아보면 대부분은 redis를 이용해서 black list/white list를 사용하는 방식이었다. 그런데 이제 막 서비스를 시작하려는 입장에서 redis를 붙이는 것이 과연 과도한 스택이 아닌지에 대한 고민이 생겼다. 그때 당시는 개발 일정이 매우 촉박했기 때문에 아직 써보지 않은 스택인 redis를 빠르게 제대로 붙일 수 있을지에 대한 확신도 없었다. 그래서 결론적으로는 redis만큼은 아니지만 mongoDB도 어느정도 속도가 빠른 편이니, 별도 document를 만들어서 로그인/로그아웃 상태를 관리하도록 했다. (사실 일정 때문에 임시방편으로 이렇게 해두고 실서비스 오픈할 때쯤에는 redis를 붙이려고 했는데 서비스 오픈 자체가 퇴사 이후로 아예 밀려버리는 바람에... 그대로 두게 됐다.) 비슷하게 검색/조회에서도 자동완성 기능을 원하셨어서, elastic search와 같은 기술이 필요할지에 대해 고민했는데 이것도 과도하다고 생각이 들어서 적용하지 않았다.

기본적인 CRUD를 기반으로 하는 기능들이 대부분이어서 대체로 각 API 개발의 난이도가 어렵지는 않았다. 다만 Firebase, 소셜 로그인, 아임포트(결제), sendbird와 같이 외부 서비스를 사용하는 경우에 해당 서비스들을 이해하고, API 문서들을 읽어서 서버에 연동해야해서 공부하는 시간이 좀 있었다. 그리고 앱 개발이다보니 기능 자체를 붙이는 건 클라이언트 단이고, 서버에서는 대개 검증작업만 하는데 클라이언트단을 외주로 맡겼다보니 테스트를 하는 과정이 좀 힘들었다.

가장 신경을 많이 썼던 기능은 예약 기능이었다. 전문가 별로 예약 가능 일자를 받고, 해당 일자를 바탕으로 하여 예약을 진행하고, 결제를 진행하는 것까지 개발을 했다. 예약 -> 구매요청(제품 번호 생성) -> 결제(클라이언트단) -> 결제검증 -> 구매확정 순으로 이루어지고, 이후에 환불 기능도 별도로 개발했다. 예약 가능 일자에만 예약이 가능해야하기 때문에 DB 설계부터 고민을 많이 했는데, 예약 가능한 시간대와 예약 불가능한 시간대 중에 예약 가능한 시간대가 더 적을 것으로 예상 되었으므로 예약 가능한 시간대를 저장하는 방식으로 했다. 그리고 중복 예약을 하지 못하도록 여러 제약 조건을 걸었다. 로직 자체는 복잡하지 않은데, 제약 조건을 걸기 위해 시간 계산을 하는 부분에서 date형을 많이 다뤄보지 못해서 헤맸고, 그 외에는 예약 상품 중에 패키지 상품이 있어서 이 부분에서 어려움이 있었다. 각 상품은 별개인데 결제는 묶어서 한 번에 하고, 환불이나 변경의 경우에는 또 묶어서 처리되기 때문에 DB 설계를 하는데에 애를 좀 먹었다. (그래도 무사히 잘 끝낸 것 같다.)

그리고 기능 개발 외에도, 이전에는 에러 반환 형식에 대해서는 크게 고민을 해본적이 없었는데 이번 프로젝트를 진행하면서 custom error exception 개념에 대해서 알게되어서 이 부분을 적용했다. request/response 형식은 개인 프로젝트를 하면서는 놓치기 쉬운 부분이어서, 이에 대해서 고민해보고 적용해볼 수 있었던 것이 큰 경험이었던 것 같다.

GitHub

인턴 기간 내내 나는 혼자서 개발을 했지만, 언젠가는 새로 개발자 분들이 들어올 것이고 또 협업을 하게 될 수도 있을 것이기 때문에... 사실 이런 이유 때문만이 아니라도 혼자 개발을 할때도 브랜치 관리를 하고 git convention을 지켜서 개발을 하는 편이 옳을 것이라고 판단해서, convention이나 양식을 설정해서 이를 지켜서 개발을 했다. git flow를 이용해서 브랜치 관리를 하고, 혼자서 개발하지만 각 기능 전에 issue를 발행하고, merge를 할땐 항상 PR을 통해서 했다. 혼자서 개발했기 때문에 코드 리뷰는 적용을 못했어서 이 점은 조금 아쉬웠다. 어쨌든 이렇게 개발을 하니, 아무렇게나 커밋 메세지를 써서 개발을 할 때보다 훨씬 각 커밋에서의 개발 내용을 명료하게 확인할 수 있고, 어떤 기능을 어떤 순서로 개발했는지도 확인할 수 있어서 매우 좋았다. 이후에 프로젝트를 할 때도 이런 부분은 꼭 적용해서 하고자 한다.

인프라

백엔드 서버는 통합으로 딱 하나 있었고, 백엔드 개발자도 나 혼자였다. 그래서 현재 시점에서 굳이 docker는 적용할 필요는 없다고 판단했다. (그리고 이전에 docker를 사용했을 때(이때는 공부 목적이 컸었다.) EC2 프리티어 서버를 사용하니 용량 때문인지 너무 서버가 자주 죽었어서 힘들었던 이유도 있다.) 그냥 jar파일을 이용해서 배포하는 방식을 선택했다.

다만 배포를 쉽게 하기 위해 배포 자동화 과정을 적용하기로 했다. 여기에도 여러 툴이 있었지만 회사에서 GitHub를 사용하고 있으니 GitHub Actions를 사용했다. 관련해서는 설명글이 많아서 읽고 공부해서 쉽게 적용할 수 있었는데, 어려움을 겪은 것은 DB 계정 정보등의 민감한 정보에 대한 문제였다. 보통 이런 정보는 따로 파일을 만들어서 정보를 저장하고, 해당 파일은 .gitignore에 포함해서 GitHub에 올리지 않기 때문에 이렇게 작업을 했는데 자동으로 배포하는 과정에서 해당 과정 파일은 어떻게 해야되는가? 에 대한 고민이었다. 여러 글을 찾아다니다가 github SECRETS를 이용하는 방법이 있다고 해서 이렇게 적용을 했다. 이 방법을 이용해서 정상적으로 배포하고, 동작까지 잘 이루어졌다!

사실 인프라와 관련해서는, 실제 베타테스트를 12월에 진행하기로 했다가 갑작스럽게 엎어진 바람에... 계획을 해놓고 못한 부분이 더 많았다. 예컨대 테스트서버/실서버 분리나 스트레스/부하테스트 등... 적용을 하려고 준비를 하던 중에 베타테스트 일정 지연 통보를 받아서 결국 진행을 못하게 됐어서 이 부분이 아쉽다. 그래서 다음 개인 프로젝트를 할 때 한 번 해보려고 한다!

테스트 코드 및 로그

TDD의 개념에 대해서는 알고 있었지만, 이전까지는 사실 테스트 코드를 딱히 작성하지 않았었다. 하지만 회사에서는 실제 서비스를 개발하니, 혹시 모를 오류 상황에 대비해서 테스트 코드를 당연히 짜야했다. TDD까지는 아니었고, 코드를 다 짠 후에 테스트 코드를 짜면서 확인을 하는 방식이었다. 처음 테스트 코드를 작성하면서 꽤 많이 헤맸는데 계속 작성하다보니까 익숙해졌다.

그리고 로그! 로그의 중요성에 대해서도 익히 들어 알고 있었으나 실제로 서비스를 하는 것이 아니기 때문에 딱히 작성할 일이 없었다. 그런데 이번에 실제 서비스를 개발하고, 또 클라이언트 단과 협업을 하다보니 로그 파일을 열어봐야할 일이 많았다. spring boot에서 기본적으로 로그가 나와서 해당 파일이 저장되기는 했지만 이걸로는 정보가 부족할 때가 많았다. 특히 QA를 하면서 더 그랬다. 3-4명 정도였지만 이것도 한꺼번에 여러명이 시도하니 로그 파일을 제대로 확인하기가 어려웠다. 그래서 QA를 하면서 로그의 중요성을 뼈저리게 느꼈던 것 같다. 그래서 로깅 관련한 코드를 열심히 적용했다. DataDog을 적용해서 로그 수집을 하기도 했다.

다만 로깅을 하는 과정에서 어떤 메시지를 어느 레벨로 작성해야하는지.. 언제 어떤 로그 메시지를 작성해야하는지.. 이런 부분에 대해서는 끝까지 감이 잘 잡히지는 않았다. 이런 사소하다면 사소할 수 있는 부분들이 혼자서 해결하기 정말 어려웠던 부분이었던 것 같다.

기타 업무

개발을 주로 했고, 사실 개발만 하기에도 일정이 촉박하긴 했지만... 앱 추가/보충 기획이나, 베타테스트 진행 일정 계획 등 다른 파트의 업무에도 조금씩 참여를 하기는 했었다. 특히 베타테스트 진행을 위해 마케팅 파트 직원분과 같이 체크리스트를 만들고, 필요한 문서 목록을 정리하고, 일정을 세우고 하면서 열심히 준비를 했었는데 결과적으론 연기됐어서... 이 부분이 조금 아쉽기는 했다. 그래도 이런 개략적인 준비 과정에서도 다른 파트에서는 어떤 것들을 준비하고, 이런 준비 과정에서 내가 도움을 줄 수 있는 부분은 어떤 것인지 등을 알게 돼서 시야를 넓힐 수 있었고, 그래서 좋은 경험이었다고 생각한다.

느낀 점

많은 점을 배웠고, 또 동시에 어떤 부분이 부족한지를 뼈저리게 느낄 수 있는 경험이었다. 단순한 API 개발뿐만 아니라 전반적인 시스템 설계, DB 설계 등 설계의 중요성 을 정말 다시 한 번 체감했다. 그리고 테스트 코드, 로그, 인프라 측면에서는 스트레스/부하 테스트 등 다양한 테스트와 모니터링의 적용 등... 안정적으로 서비스를 제공하기 위해서 필요한 노력이 정말 많다는 것을 실감했다. 또 문서화의 중요성! 이것 역시 정말 뼈저리게 느꼈다. 협업도 협업인데, 클라이언트를 외주로 진행하면서 개발자분과 주로 서면으로 소통하다보니 정말 정말 문서가 중요하구나 느꼈다. 이외에도 초기 스타트업이다보니 기획, 마케팅 등의 다른 파트와 소통하거나 협업해서 참여할 일들이 많았는데, 아무래도 개발자로서 바라보는 측면과 기획, 마케팅 측면에서 바라보는 측면은 달라서 시야를 넓힐 수 있는 좋은 기회였다.

혼자서 개발을 도맡아 한다는 점이 어렵기도 했고, 책임감 때문에 힘들기도 했다. 그만큼 여러 부분을 공부하고 접할 수 있었고, 개발자로서의 스스로를 되돌아볼 수 있었다. 그래서 성장할 수 있는 발돋음이 된, 좋은 기회였다고 생각한다.

+) 이번 인턴을 하면서 회사에서는 이런 걸 어떻게 하지? 라는 질문들 때문에 각 기업들의 기술 블로그 글을 정말 많이 읽었는데, 기술 블로그 글을 읽으면서 배운 점이 정말 많았다. 앞으로도 꾸준히 챙겨보면서 공부할 예정이다.

profile
개발자, 학생

0개의 댓글