42helper 주소: https://helper.42seoul.io/

42helper 가이드 문서: https://bit.ly/3hy02ya

1. 지원 동기

Spring Boot 모집

열심히 이너서클 탈출을 위해 과제를 하던 도중 Spring Boot 프로젝트 Cadet을 모집한다는 글을 보았습니다.

Spring Boot는 혼자서 공부한 게 전부이고 백엔드 개발자 직무를 희망하고 있지만, 웹 프로젝트를 해본 적이 없어서 경험을 쌓고 싶었습니다. 특히 42서울에 계신 Cadet 분들이라면 함께 성공적으로 프로젝트를 마무리할 수 있을 것이란 기대를 품고 지원하였습니다.

2. 기술 스택

2.1 Spring Data JPA

JPA로 자동생성된 스키마의 UML Diagram

저희는 Spring Data JPA를 사용하여 웹 서비스 구축을 하였습니다.

JPA(Java Persistence API)는 ORM(Object-Relational Mapping) 기술에 대한 API 표준 명세입니다. JPA를 사용하면 객체를 관계형 데이터베이스와 맵핑을 해서 쿼리를 따로 작성할 필요 없이 객체로 테이블을 구성하고, 코드로 관리할 수 있는 장점이 있습니다.

MyBatis 와 JPA를 고민하다가 학습 및 객체 중심 개발, 빠른 개발을 위해 JPA를 선택하게 되었습니다. JPA를 선택하였기 때문에 손쉽게 CRUD, 페이징, 정렬 기능을 DBMS에 종속되지 않게 구현할 수 있었습니다.

2.2 Thymeleaf와 Bootstrap

Vue나 React를 사용하기에는 학습 곡선이 높았기 때문에, Thymeleaf 템플릿 엔진과 Bootstrap을 사용하여 기본적인 페이지 구성을 하였습니다.

개발이 점점 진행이 될수록 처음 부족하다고 느꼈던 기획이 구체화 되면서, 나중에는 백엔드보다 프론트엔드 개발에 더 오랜 시간을 투자를 하여 개발을 진행하였습니다.

메인 페이지

그렇게 해서 백엔드 개발자 3명의 노력 끝에 이렇게 멋진 메인페이지가 나오게 되었습니다.

2.3 GitHub Action 을 이용한 CI/CD

GitHub Action을 사용하여 CI/CD를 구축하였습니다.

Pull Request 요청이 올경우 자동으로 Maven을 사용해 Build 체크를 하도록 구성을 하였고, Push 이벤트가 발생할 경우 자동으로 develop 서버 환경과 production 서버 환경에 자동으로 배포하도록 구성하였습니다.

지속적으로 코드 통합과 서버 배포가 이루어지는 것을 확인할 수 있습니다.

자세한 코드는 GitHub 에서 확인할 수 있습니다.

2.4 자동 메일 시스템

새로운 유저가 팀에 참여했는지, 떠났는지 알려줘야 한다고 생각하여 이벤트에 따라 자동으로 메일이 전송되는 시스템을 만들었습니다.

직접 42helper.noreply Gmail 만들어서 메일이 전송되도록 시스템을 구현하였습니다.

받은 메일함 혹은 스팸함을 확인해보면 메일을 확인할 수 있습니다.

메일을 열어보면 멘티에 대한 정보와 팀 정보를 볼 수 있는 Team link 주소를 받을 수 있습니다.

Team link를 클릭하면 팀에 대한 상세정보를 볼 수 있는 modal 화면이 뜨도록 구현을 하였습니다.

2.5 서비스 모니터링(GA, Sentry)

접속하는 사람들에 대한 분석에서 에러 메시지에 대한 처리까지 모니터링의 전반에 대해 Google AnalyticsSentry로 구축했습니다.

Google Analytics로 접속자 현황과 상세 통계에 대해 알 수 있었습니다. 오픈 후 며칠간 통계를 지켜본 바로는 저희가 프론트를 PC웹으로 고정하고 만들었지만 모바일로 접속하는 비율이 적지 않았다는 것입니다. 아무래도 모바일 지원은 숙제로 남을것 같다는 생각이 듭니다.

예외처리시 Logback으로 로그가 쌓이는 부분에 대해서 Sentry로 보내도록 구성했습니다. 사용자가 예상치 못한 행동으로 예외처리가 발생했을때 Sentry로 로그 수집을 하고 각 팀원들에게 메일을 보내도록 구성했습니다.

2.6 Embedded h2 활용

helper는 MariaDB를 사용하고 있으며 GitHub Action 에서 Build 시 DB 설정이 요구 되었기에 때문에 배포서버에서 사용하는 MariaDB와 동일하게 Docker 이미지를 올려서 Build 할 수 있게 설정이 필요했으며, 각각의 팀원 또한 자신의 Local 환경에 배포서버와 동일하게 MariaDB를 구축해야하는 번거로운 상황이 예상되었습니다.

저희는 이런 번거로운 작업을 덜기위해 Spring Boot 에서 제공하는 Embedded h2를 적극적으로 활용했습니다. Embedded h2는 Local 에서 동작 시에만 생성되어 작동하는 h2 DB 입니다. 또한 간단한 설정으로 앱 실행 시 특정 .sql 파일을 실행하여 Table 생성과 Data 삽입이 가능하여 Local 에서 테스트 시 데이터 삽입 등이 용이하고 GitHub에서 Maven Build 테스트시 추가 작업이 필요 없기 때문에 개발 속도를 빠르게 할 수 있었습니다.

배포 시에는 deploy.sh 를 통해 다른 .properties 파일을 통해 Build 하게 하여 Local 과 배포환경에서 다른 DB 를 사용하도록 설정해서 배포 작업에 추가 행동이 필요하지 않았고, JPA 를 사용하고 있었기 때문에 DB 환경의 차이에 상관없이 작업이 가능했기 때문에 이러한 방식을 채택해 사용했습니다.

2.7 42 OAuth2 Login

helper 는 매칭 기능을 제공하고 있기 때문에 유저의 정보가 요구 되었고, 이는 회원가입 및 로그인 그리고 서비스 별 접근제한 기능이 필요했습니다. 이는 상당한 시간과 작업이 요구되는 지루한 작업입니다. 저희는 이 서비스가 42Seoul 사람들이 주 고객 이었기 때문에 Intra42 에서 지원하는 42OAuth2 와 Spring Security 를 이용해 회원가입 및 로그인, 유저권한 별 접근권한을 관리할 수 있었습니다.

2.8 민감한 정보 숨기기

helper 는 누구에게나 열려있는 오픈소스 프로젝트입니다. 이로 인해서 다른 사람들이 이 프로젝트를 실행할 수 있게 하기 위해 .properties 파일도 정보를 공개해야 했습니다. 그러나 .properties 파일에는 DB 유저 정보, OAuth2 Key 값 등 민감한 정보나 작업자에 따라 다른 값이 들어가는 경우가 존재합니다. 저희는 이러한 값들은 환경변수로 저장하고 이를 .properties 에서 가져와 사용하도록 설정하였습니다. 또한 README.md 파일에 필요한 설정값을 나열하여 다른 사람들이 프로젝트를 받아 직접 실행할 수 있게 마련했습니다.

3. 협업 방법

3.1 GitHub로 협업하기

우리의 git flow는 다음과 같습니다.

1. 깃허브 이슈 발행

매일 회의를 통해 새로운 기능, 버그 등이 생기면 이슈 발행을 하여 작업을 하였습니다.

개인별로 이슈를 할당하여 작업을 하였습니다.

2. Pull Request

개인별로 이슈가 끝나면 Pull Requestdevelop branch에 병합을 요청했습니다.

3. Code Review & Approved

Pull request는 2명의 팀원에게 Code Review 를 받고, approved 되어야 squash merge를 하도록 저희끼리 규칙을 정했습니다.

4. develop 병합

develop로 병합되는 코드는 squash and merge를 하였습니다.

develop에 병합이 되면 GitHub Action에 의해 빌드develop 서버 배포가 이루어집니다.

5. main 병합

main으로 병합되는 Create a merge commit 을 하였습니다.

main에 병합이 되면 GitHub Action에 의해 빌드와 production 서버 배포가 이루어집니다.

main 병합시 날짜 배포로 커밋 메시지를 작성하였습니다.

3.2 커넥티드 코딩하기

프로젝트가 본격적인 개발 단계에 들어서면서 ‘서로 간에 소통이 잘 안 되는 것 같다’라는 이슈 생겼습니다.

멘토님께서 팀원들끼리 서로 연결이 되어 코딩하는 방식을 제안해주셨습니다.

  1. 어제 무엇을 하였는가?
  2. 오늘 무엇을 할 것인가?
  3. 방해 되는게 있는가?

위 질문을 토대로 매일 00:00시에 온라인으로 만나서 회의를 진행하였고, 매일 production 서버에 배포하였습니다.

이 방식을 통해 코로나라 자주 만나지 못함에도 불구하고, 이전보다 더 적극적으로 이슈를 발행하고, 긴밀하게 이슈 해결할 수 있었으며 짧은 배포 간격을 가질 수 있게 되었습니다.

4. 많은 문서화 작업

  • GitHub: 우리 팀이 아닌 다른 사람들이 설정하더라도 똑같은 환경에서 실행 할 수 있도록 Readme에 문서화를 하였습니다
  • GitHub Wiki: 프로젝트를 진행하며 멘토님과 같이 진행하였던 회의 내역들을 볼 수 있습니다.
  • 인스턴스 셋업 방법: 아무것도 없는 인스턴스 환경에서 저희와 같은 환경을 구축할 수 있도록 인스턴스 셋업 방법을 문서화 하였습니다.
  • 가이드 문서: 우리 서비스를 이용하는 사람들을 위해 정성 가득한 가이드 문서를 작성하였습니다.
  • 42 API 발급 가이드: 42 API 발급 방법 가이드 문서를 작성하였습니다.
  • 컨트리뷰터 가이드: 저희 프로젝트는 오픈소스로 운영이 됩니다. 컨트리뷰트 하고 싶은 분들을 위해 가이드 문서를 작성하였습니다.

5. 느낀점

ychoi

  • 기획부터 개발, 배포, 운영까지 모두 다 경험할 수 있었던 프로젝트 였습니다. 혼자서는 Spring, Java 공부를 해왔으나, 이렇다할 Spring 프로젝트를 해본 경험은 없었습니다. 이번에 프로젝트를 진행하며 직접 필요에 의해 자료를 찾고, 팀원들의 코드를 보면서 코드를 작성하니, 혼자 했을 때 보다 더 효율적으로 학습할 수 있었습니다.
  • 소통의 중요성을 알게 되었습니다. 3명 모두 다른 경험을 가지고 있기 때문에 자신의 의견을 잘 말하고, 잘 들으며, 끊임없이 소통하는게 중요하다고 느꼈습니다. 다들 긍정적으로 의견을 받아드리시면서 의견을 제시해주셔서 큰 문제 없이 소통할 수 있었고, 이는 곧바로 새로운 이슈로 발급되어, 당일에 수월하게 개발이 진행되었습니다.
  • 팀원분들이 기업에서 오래 일해본 경험이 있으셔서 프로젝트 외에도 간접적으로 백엔드 외의 다른 개발 분야에 대해서도 경험할 수 있었습니다. 또한 프로젝트 개발을 진행하며 Infra, Shell, Code, DB 등 다방면으로 배울 수 있었습니다.
  • 어설픈 질문과 의견에도 긍정적으로 수용해준 좋은 팀원분들, 그리고 매번 회의때 많은 지식을 공유해주시고 응원해주신 멋진 멘토님과 함께하여 즐거웠습니다.

hwon

  • 몇몇 토이 프로젝트를 진행해봤지만 실제 웹페이지를 완성하고 배포, 운영하는 것은 이번이 처음이었습니다. 서비스 전날에 팀원 들과 병합을 진행하면서 큰 문제가 없겠지 하고 있었지만 생각하지도 못한 버그와 제안들이 날라 왔습니다. 이를 보고 왜 회사에서 배포와 서비스 경험을 물어보는 지 이해가 되었습니다. 이를 GitHub issue 로 알려주면 모든 분들께 감사하며, 정말 어디서도 경험해보지 못한 값진 경험이였다고 생각합니다.
  • 저는 당시 BE쪽 으로 직무를 희망하고 있었고, FE에 대해 쉽다고 생각하였고 내가 지원하는 직무쪽과 관계가 없다고 생각하여 잘 건들지도 않았습니다. 하지만 이번 프로젝트에서 두 작업을 동시에 진행해보면서 “왜 REST Api를 이런식으로 설계하고, FE에 이런 오픈소스들이 있어서 이렇게 요청을 하겠구나” 하는 것을 느꼈습니다. 왜 BE 개발자에게도 FE에 대한 경험을 요구하는지 알 수 있었고 좀 더 FE에 가까워지는 계기가 된 것 같습니다.
  • 여러 팀원 들과 협업을 해왔지만 이렇게 GitHub 를 체계적으로 사용한 적은 이번이 처음 이였습니다. GitHub의 Issues 로 해야할 일들을 남기고 이를 PR 과 연결하여 관리 함으로서 프로젝트를 진행하였고, 해당 방식으로 진행하니 팀원 들이 지금 어떤 작업을 하고 있고, 현재 어떤 작업들이 필요한지 바로 바로 알 수 있어서 코로나로 인해 자주 만나지 못해도 이전에 진행했던 프로젝트 보다 수월하게 프로젝트를 진행했습니다.
  • 팀원 들을 정말 잘 만났다고 생각합니다. 저는 스케줄 종종 까먹는 경우가 많고, 오타가 상당히 잦은 편입니다. 또한 CI/CD 는 건들지도 못했고, 리눅스의 명령어는 거의 까막눈 수준이었습니다. 그런데 우연의 일치인지 저희 팀원 3명 다 각자 다른 분야에 특출 했기 때문에 서로의 지식과 단점을 보완해주면서 프로젝트를 진행하였고, 이로 인해 편하고 수월하게 여기까지 온 것 같습니다.

minkang

  • 그동안 자바나 스프링을 공부한다고 했지만 파편화된 지식들이 대부분이였습니다. 이번 기회에 이런 지식들을 모아 실제 서비스로 구현해볼 수 있었던 프로젝트였습니다. 특히 아이디어 선택 부터 피드백 반영까지 개발의 한 사이클을 경험해 볼 수 있어서 좋은 경험이였다고 생각합니다.
  • GitHub을 평소에 많이 사용하지만 배포를 위한 git flow 정책이나 GitHub Actions을 통한 CI/CD 구축 과정을 겪어보니 프로그래밍 외에도 협업을 위한 도구 역시 알아야할 필요가 있다는것을 느꼈습니다.
  • 개인적으로는 스프링 부트를 이용하는 것도 서툴러서 프로젝트 내내 팀원들에게 민폐가 되는것 아닌가 싶었는데 두분의 많은 이해와 배려 덕분에 중도 이탈하지 않고 끝까지 갈 수 있었다고 생각합니다. 덕분에 기술, 설계적으로 많이 배우고 전체적인 프로세스를 끝까지 경험할 수 있었습니다. 이 자리를 빌어서 두분께 감사하다는 말씀 꼭 전하고 싶었습니다.
  • 뛰어난 사람들과 함께 할 수 있는 기회는 인생에 몇 번 없다고 생각합니다. 프로젝트 내내 멘토님과 팀원들 한분한분께 배울점이 많다는 것을 느끼고 많은 도움을 받았습니다. 여러분들도 좋은 기회가 보인다면 망설이지 말고 꼭 붙잡으시기 바랍니다. 감사합니다.

여기까지 42helper 팀이었습니다. 긴 글 읽어주셔서 감사합니다 🙂

사이트 주소: https://helper.42seoul.io