본문 바로가기
  • 개발공부 및 일상적인 내용을 작성하는 블로그 입니다.
프로젝트/협업

Pro.gg - 프로젝트 회고록(10) : 최종

by 방구석 대학생 2022. 3. 17.

 

 

회고록 마무리...

공식적으로 프로젝트가 종료된건 작년 9월 초 였지만 회고록은 이제서야 마무리 짓는다.

아무래도 https 연결 실패로 인해 구글, 페이스북 로그인이 정상적으로 동작하지 않는다는 부분 때문에 선뜻 회고록을 모두 작성하고 마무리 짓기가 영 아쉽기도 했고, 그동안 부족하다 싶은 부분을 공부하느라 지금까지 미뤄둔 감도 있는 것 같다.

(이게 다 최근에 허무하게 성공해버린 https 연결 때문이다!)

 

물론 프로젝트가 완료된 9월 초쯤에 얼른 회고록 작성을 끝내고 포트폴리오를 만들어서 각종 회사에 서류를 넣으며 취직을 해도 됐겠지만, 솔직히 말하자면 그때의 역량과 알고리즘, 스프링 기본 개념과 같이 부족한 부분에 대해서 어느정도 보완을 한 지금의 역량을 비교해 봤을때 꽤 크게 차이가 나기 때문에 조금 시간이 많이 걸렸더라도 지금처럼 공부할 걸 어느정도 다 끝마치고 https 연결도 성공해서 구글, 페이스북 로그인을 정상 동작시킨 지금이 취직을 하기에 더 적합한 시점이 아닌가 생각한다.

(BFS,DFS 같은 기본적인 알고리즘이나 객체지향 설계에 있어 다형성과 같은 중요한 개념을 활용하는 법, 스프링이 동작하는 기본적인 원리를 모른체로 개발자로서 취직을 했다고 생각하면, 회사 선임 개발자들에게 기본적인 역량조차 부족하다고 대차게 까였을 것이 자명하다.)

 

좋았던 점?

* 기술적인 부분

1. REST 의 개념을 어느정도 적용시켜 만든 웹 프로젝트 경험을 쌓았다.

REST 는 자원을 이름(자원의 표현) 으로 구분하여 해당 자원의 상태(정보) 를 주고 받는 모든 것을 의미한다.

좀 더 구체적으로 말하자면 HTTP URI 를 통해 자원(Resource) 을 명시하고, HTTP Method(post, get, put, patch, delete) 를 통해 해당 자원에 대한 CRUD 작업을 적용하는 것을 의미한다.

 

이번 프로젝트에서 REST 의 구체적인 특징인 캐싱이나 무상태 설계 같은 경우, 솔직히 캐싱은 따로 캐시 관련 처리를 하지 못했고(구체적으로 뭘 어떻게 할지 잘 모르겠다....) 무상태 설계 같은경우 클라이언트-서버 간 HTTP 통신 때 서버측에서 클라이언트의 요청 상태를 유지하지 않는 방식으로 설계하는 것을 말하는데, 이것은 뒤늦게서야 알게된 개념이라 이번 프로젝트에서 이게 적용이 됐을지는 의문이다.(코드를 작성하는데 있어 뭘 어떻게 해야 무상태 설계를 준수하는 건지 잘 모르겠다.)

 

즉, 경험과 역량이 부족해 REST 의 특징을 모두 잘 이용하지는 못했으나 HTTP Method 를 통해 클라이언트-서버간에 자원의 상태를 주고받는 방식의 기본적인 REST 웹 어플리케이션을 제작한 경험을 쌓았다는 점이 나름 의미있지 않았나 생각한다.

 

2. 다양한 외부 API 를 사용해 보았다.

SNS 로그인 기능을 구현하기 위해 네이버, 카카오, 구글, 페이스북이 제공하는 로그인 API 를 이용하여 프로젝트에 적용시키는데 성공했고(내가 직접 한건 구글, 페이스북이고 네이버, 카카오는 같이 하는 형이 작업했다.) 

프로젝트의 주제가 리그 오브 레전드 라는 게임 IP 를 중심으로 하여 자신만의 팀을 구성함과 동시에 커뮤니티 기능도 제공하는 웹 사이트를 만들어보자 였기에 라이엇(리그 오브 레전드 개발사) 측 에서 제공해주는 게임에 대한 다양한 API 를 활용하여 각종 챔피언에 대한 정보는 물론, 소환사 개인의 각종 랭크 정보, 최근 전적 정보와 같은 데이터도 크롤링 해올 수 있었다.

그 결과 자신만의 팀을 구성하는데 있어서 자신이 모집하고자 하는 팀원의 기준에 맞는 웹 사이트 회원을 검색해보는 기능부터 시작해 자신의 팀에 소속된 팀원들의 전체 평균티어는 어떻게 되는지, 그리고 메인화면에서 소환사 명을 검색했을 때 해당 소환사의 솔로 랭크, 자유 랭크 티어와 전적, 승률 등의 정보와 함께 최근 전적이 어떻게 되는지까지 모두 확인할 수 있는 기능들을 구현할 수 있었다.

 

이를 통해 그동안 외부 API 를 사용하는데 있어 막연하게 어렵지 않을까 하는 불안감을 걷어내고 외부 API 를 사용하는데 있어서 한층 더 자신감을 가지게 되었다.

 

3. 깃허브를 활용한 기본적인 협업능력을 길렀다.

깃허브는 프로젝트를 진행할 때 개발자들간의 협업이 원활하게 진행될 수 있도록 도와주는 소프트웨어 개발 플랫폼이다.

이번 프로젝트를 진행하면서 이 깃허브라는 플랫폼을 적극적으로 활용했다.

우선 각자 맡을 작업량을 프로젝트 이슈를 통해 명시하고, 만들어진 이슈를 기반으로 각자 작업할 브랜치를 만들고 해당 브랜치 위에서 작업을 수행한 다음,

할당량 작업이 완료되면 각자에게 풀 리퀘스트를 요청해서 문제가 없을경우 메인 브랜치에 합병 시키는 방식으로 개발을 진행했다.

(아쉽게도 프로젝트 막바지인 8월쯤엔 이제 거의 끝물이라 그런지 좀 느슨해져서 이슈도 안 만들고 그냥 메인 브랜치에 바로 소스 코드를 커밋하고는 했다. 이건 반성해야 할 부분이다.)

 

깃허브를 이용해 협업 프로젝트를 하면서 한 가지 배운점이 있다. 바로 풀 리퀘스트를 통해 다른 사람의 코드가 메인 브랜치에 병합 되었을 경우, 병합되기 이전의 메인 브랜치를 기반으로 만들어진 내 작업 브랜치를 어떻게 처리하느냐 하는 것이었다.

의외로 해법은 간단했다. 브랜치 리베이스를 하면 간단하게 현재 다른 사람의 코드가 병합된 메인 브랜치의 내용을 그대로 현재 내가 작업하고 있는 브랜치로 가져올 수 있었다.

이걸 깃 콘솔을 이용해 직접 명령어를 입력하는 방식으로 할 수 있었으면 좋았겠지만 아쉽게도 그러진 못했고, 프로젝트를 하고 있을 때 작업 툴로 IntelliJ IDEA 를 사용했는데, IDEA 자체가 깃허브와 관련해서 여러가지로 제공해주는 기능이 많아서 이걸 통해 브랜치 리베이스를 쉽게 해 줄수 있었다.

 

IntelliJ IDEA 가 참 좋았던게, 현재 작업이 진행중인 깃허브 Repository 에 연결되고 나면 해당 Repository 에 있는 각종 현재 Repository 에 만들어진 이슈를 기반으로 브랜치를 생성해주는 것 부터 시작해서, 다른 브랜치로의 변환이 단순히 마우스 클릭 몇번만으로 가능하게끔 기능을 지원해줄 뿐더러 앞전에 말했던 브랜치 리베이스를 버튼 원클릭으로 가능하게 해준다.

물론 브랜치 리베이스의 경우 충돌이 일어나는 파일이 발견되면, 각각 브랜치에서 해당 파일들 중 어떤 파일의 내용을 적용시켜 줄 지를 결정해주는 것도 가능하다.

이 밖에도 현재 작업하고 있는 브랜치에 대한 쉬운 커밋은 물론, 작업이 완료 되었을 경우 메인 브랜치에 풀 리퀘스트 요청을 보내는 것도 IDEA 에서 자체적으로 지원해준다.

깃허브를 적극적으로 활용하는 웹 개발자 입장에서 IntelliJ IDEA 는 정말 효자 개발툴이 아닌가 싶다.

(이클립스를 쓸 때는 이걸 깃이랑 어떻게 연동할 수 있는지에 대한 정보를 찾아봐도 IntelliJ 처럼 쉽게 쉽게 할 수 있는 방법은 찾지 못했던것 같다, 아니면 내가 그냥 이클립스 숙련도가 부족해서 그렇거나)

 

4. 전체적인 코딩 실력 향상

이건 프로젝트를 처음 경험하는 주니어 개발자 입장에서는 당연한 것이 아닐까 싶다, 아직 역량도 많이 부족한 상태인지라 프로젝트를 진행하면서 생기는 오류들 때문에 막히는 것들을 뚫어내면서 새로 공부하는 것도 많고 제대로 클라이언트-서버간의 통신을 통해 서비스를 제공하는 웹 프로젝트를 진행함에 있어 클라이언트의 요청을 서버측에서 처리할 때 각 기능별로 어떤 로직을 작성하며, 데이터베이스에는 또 어떻게 접근하고 어떤 쿼리를 전달해서 어떤 결과를 돌려 받고, 그걸 또 어떻게 처리할지에 대한 일련의 과정에 있어서 숙련도를 쌓을 수 있었다.

 

  

아쉬웠던 점?

* 기술적인 부분

1. JPA 가 아닌 Mybatis 를 활용해야 했던 점

이번 프로젝트에서 객체 - 데이터베이스 간 매핑 기술로 JPA 가 아닌 Mybatis 를 활용한것이 조금 아쉽다.

만약 JPA 를 활용했다면 Spring Data JPA 를 통해 간단한 CRUD 기능을 공통으로 처리해주는 인터페이스를 제공 받았을 것이다.

여기서 공통 인터페이스란 findByUsername, save, update 등과 같이 간단하지만 단순 반복 작업들을 Spring Data JPA 구현체인 Hibernate 가 애플리케이션 실행 시점에 동적으로 쿼리 집합을 만들어 사용자에게 제공해주는 인터페이스를 말한다.

https://wonit.tistory.com/469 

 

[배워보자 Spring Data JPA] JPA의 공통 인터페이스, JpaRepository 의 기능과 구조

해당 글은 배워보자 Spring Data JPA 시리즈 입니다. 해당 시리즈의 내용이 이어지는 형태이므로 글의 내용 중에 생략되는 말들이 있을 수 있으니, 자세한 사항은 아래 링크를 참고해주세요! Spring Dat

wonit.tistory.com

이렇게 JPA 를 활용했다면 간단한 select 쿼리나 update, insert 쿼리는 Spring Data JPA 에서 제공해주는 공통 인터페이스를 통해 처리하고, 조금 복잡한 쿼리는 Repository 상에서 JPQL 을 활용해 처리해주면 직접 테이블 중심으로 쿼리를 작성해야 하는 SQL 을 사용할 필요 없이, 객체 중심으로 쿼리를 작성하여 처리해 줄 수 있었을 것이다.

 

하지만 그렇다고 Mybatis 를 사용한 게 마냥 안 좋았던 건 아닌 것이, 프로젝트에서 구현하고자 하는 기능들 중에서 동적 쿼리를 사용해야 하는 것이 있었는데, JPA 를 통해 동적 쿼리를 작성하려면 QueryDSL 이라는 것을 공부해야 했다.

그런데 내가 JPA 를 조금 공부 해봤다고 해서 QueryDSL 까지 아는건 아니기도 하고, 그렇다고 이걸 공부하기엔 괜히 프로젝트 시간이 더 길어질 것 같았다.

그러나 Mybatis 같은 경우 직접 SQL 쿼리들을 Mapper 파일에 다 작성해줘야 하는 단점이 있지만, 동적 쿼리의 경우 동적 쿼리를 쉽게 구현할 수 있게끔 제공해주는 태그들이 있어서 이를 통해 동적 쿼리가 필요한 기능을 쉽게 구현할 수 있었다.

 

2. Ajax 를 과하게 사용한거 아닐까....?

Ajax 는 빠르게 동작하는 동적인 웹 페이지를 만들기 위한 웹 개발 기법의 하나이다.

Ajax 를 사용하면 웹 페이지 전체를 다시 로딩하지 않고도, 웹 페이지의 일부분만을 갱신할 수 있다.

즉, Ajax 를 이용하면 백 그라운드 영역에서 서버와 통신하여, 그 결과를 웹 페이지의 일부분에만 표시할 수 있다는 것이다.

 

하지만 이런 Ajax 도 정확하게 필요한 곳에만 사용해야 하지, 그렇지 않은 곳에서 사용하면 예상치 못한 결과를 얻게 될 수 있다는 것을 이번에 알게 되었다.

프로젝트를 진행하면서 프론트엔드와 백엔드간의 통신이 필요한 경우 거의 무지성으로 Ajax 를 사용 했었는데, 이 결과 웹 사이트에 로그인을 했음에도 불구하고 새로고침을 하면 다시 로그인 페이지로 이동하게 되는 오류가 발생하기도 했다.

새로고침은 서버측으로 보낸 요청들 중 가장 마지막 요청을 다시 실행 시키는 기능인데, 만약 단순히 웹 페이지를 이동하기만 하는 기능인데도 Ajax 를 이용했다면, 로그인 완료 이후에 새로고침을 했을 때 웹 브라우저에서 서버측으로 가장 마지막으로 보낸 요청이 로그인에 대한 요청이 아니라 로그인 페이지에 대한 이동으로 인식해서, 로그인을 했음에도 불구하고 로그인 페이지로 다시 돌아가는 불상사가 발생할 수 있다.

그 일이 바로 이번에 프로젝트를 진행하면서 발생했다.

 

결국 이런 문제가 발견된 곳은 최대한 location.href 나 location.replace 로 아예 마지막 요청을 덧 씌우는 방식으로 해결했지만, 개발을 할 때 항상 오류라는 것은 생각지도 못한 곳에서 터지듯이 아직도 어딘가에서 Ajax 의 과도한 사용으로 인해 프로세스의 진행 흐름상 잘못된 부분이 있을지도 모른다는 불안감이 조금 있다.

 

3. CKEditor 와 같은 외부 라이브러리에 대한 숙련도 문제

게시판 기능을 구현할 때 CKEditor 를 이용해 게시글 작성 기능을 만들었는데, 초반엔 그냥 일반적인 글 작성은 문제 없이 잘 되는것이 확인 되었으나 앞전의 회고록에서도 말했듯 이미지를 업로드하는 기능에서 장기간 해결을 못 했던 문제가 발생했었다.

보통 이런 외부 라이브러리를 사용할 때 다른 사람들이 사용한 후기를 보면 공식 문서에 설명이 잘 나와있기 때문에 그대로 따라만 하면 된다고는 하지만, 막상 공식문서를 보면 죄다 영어라서 이게 쉽게 알아보기도 힘들거니와, 그렇다고 다른 사람이 먼저 사용해보고 자신들의 블로그에 올려둔 예시 코드를 봐도, 내가 현재 작업하고 있는 프로젝트와는 환경이 다른 경우가 허다해서 그대로 적용하기도 쉽지가 않았다.

 

sns 로그인 같은 경우는 그래도 네이버랑 카카오가 국내 회사이고, 구글, 페이스북 같은 경우 죄다 영어이긴 했어도 워낙에 유명한 기능을 구현하는 것이기 때문에 사람들이 기존에 구현해놓은 예시 코드들을 보며 내 프로젝트의 환경에 맞게끔 바꿔나가면 곧 잘 동작하는 것을 확인할 수 있었는데, CKEditor 를 이용해 이미지 업로드 기능을 구현할 때는 sns 로그인 과는 달리 다른 사람들의 예시 코드를 보고 그대로 따라하고 어찌저찌 내 프로젝트 환경에 맞춰서 리팩토링을 해도 도무지 이유를 알 수가 없는 오류가 계속 발생해서 며칠동안 계속 복장이 터져나갔다.

결국 오류가 발생하는 명확한 이유는 프로젝트 내부의 static 폴더에 업로드 시킬 이미지가 미처 다 저장되기도 전에 CKEditor 측에서 해당 이미지의 경로를 참조하려고 했던것 이었고, 이게 생각보다 너무 단순한 이유였던게 사람을 진심으로 허탈하게 만들었다.

 

어쩌면 내가 영어를 잘해서 CKEditor 에 대한 공식문서를 명확하게 잘 읽어 봤다면 그런 불상사를 막을 수 있지 않았을까 하는 생각도 든다.

앞으로는 영어 잘 못한다고 공식문서 대충 넘겨버리지 말고 최대한 읽어보려고 노력해봐야 겠다.

 

4. TDD 개발 방식을 적극적으로 활용하지 못한 점

프로젝트를 진행하면서 한 가지 기능의 구현이 끝나면, 그 기능이 정상적으로 잘 동작하는지 확인하기 위해 직접 서버를 구동 시키고 기능이 제공되는 페이지로 이동해서 직접 기능을 실행 시켜봐야 했다.

어찌보면 이런식으로 테스트트를 하는게 당연하다고 볼 수 있다.

하지만 내가 테스트 코드를 좀 더 잘 작성할 줄 알았다면, 이를 통해 테스트 코드를 먼저 작성하고 테스트가 잘 통과되는지 확인한 다음 본 코드를 작성하는 방식으로 개발을 진행했다면, 즉 TDD 방식으로 개발을 진행했다면 기능이 잘 동작하는지 확인하는 것이 훨씬 더 간편했으리라는 생각이 든다.

 

* 기술적인 것 이외에 아쉬웠던 점

- 길어도 지나치게 길었던 프로젝트 진행 기간

프로젝트가 너무 오래걸렸다. 오래걸려도 진짜 지나치게 오래 걸렸다.

프로젝트 첫 기획이 2021년 5월 중순 이었는데, 공식적인 프로젝트 종료는 9월초였다.

물론 이유가 없는 것은 아니다. 프로젝트 초기에 프로젝트의 규모를 4명이서 작업 하는것을 기준으로 삼았는데, 시작부터 뜬금없이 말도 안되는 이유로 처음에 프로젝트를 제안하고 아이디어 까지 제시했던 두 명이 본인들은 더 이상 진행이 힘들것 같다면서 프로젝트에서 이탈했다.

한 명은 집이 이사를 간다고 해서 당분간 이사 돕는것 때문에 바빠질걸 핑계로 프로젝트에서 이탈했고, 한 명은 갑자기 맹장이 터졌다면서 일주일간 병원에 입원하면서도 자신은 프로젝트에 확실히 참여 할테니 먼저 작업하고 있으라고 해놓고는, 그대로 말도 없이 사라져버렸다.

 

프로젝트 시작부터 이런식으로 문제가 터져버리니 나도 그렇고 프로젝트를 끝까지 같이 진행한 형도 그렇고 멘탈이 안 깨질래야 안 깨질수가 없었다.

학원에서 프로젝트 완성 기한으로 잡은 기간은 3주 였는데 그 덕분에 3주 안에 프로젝트를 완성하기는 커녕 당장에 프로젝트가 엎어지지는 않을지를 걱정해야 했다.

안 그래도 4명이서 작업하는걸로 기획했기 때문에 프로젝트 규모가 나름대로 큰 편이었고 그렇다고 다들 숙련된 사람들도 아니라서 4명이서 빡세게 들러붙어도 3주안에 될 까말까 싶었는데 말 그대로 프로젝트를 기간안에 완성시킬 가능성이 완전히 사라져 버린것이다.

 

사태가 그렇게 되버린 이후 남아있던 나와 프로젝트를 같이 진행한 형, 둘 이서 얘기를 해본 결과는 다음과 같았다.

1. 나도 그렇고 형도 그렇고 취업하려면 자신이 진행한 프로젝트를 기반으로 만든 포트폴리오가 필요하다.

2. 말도 안되는 이유로 초반부터 프로젝트에서 이탈해버린 사람들 때문에 이 프로젝트가 엎어지게 되면 결국 가장 손해를 보는 사람은 제대로 참여해서 진행한 프로젝트가 필요한 나와 형이다. 

3. 애초에 나도 그렇고 형도 그렇고 직접 제대로 진행한 협업 프로젝트가 필요해서 국비과정에 지원한 것이다. 그렇기에 프로젝트를 포기하는 것은 그동안 국비 과정을 들어온 시간을 그냥 허공에 날려버리는 것과 같다.

4. 결론, 기간이 얼마나 오래걸리던 상관없이 어떻게든 프로젝트를 두 명이서라도 끝까지 진행해서 완성한다.

5. 프로젝트 초반에 이탈한 두 명이 괘씸해서라도 프로젝트 규모를 축소하지 않고 보란듯이 프로젝트를 끝까지 완성하자.

 

위와 같이 일단은 둘이서 프로젝트를 끝까지 완성하자는 결론을 내렸다.

하지만 그렇다고 해서 프로젝트 시작부터 멘탈에 입은 데미지가 완전히 사라진것은 아니었기에 둘 다 일말의 불안감이 있었다.

원래 4명이서 진행해야 했을 프로젝트를 둘이서 진짜 빡세게 달라붙으면 왠지 모르게 한쪽에서 그냥 관두자는 말이 나올것 같았다.

안 그래도 멘탈에 타격을 입은 상황에서 아직 커리어 시작도 못한 주니어 웹 개발자 입장에서는 규모도 꽤 큰 프로젝트를 빡세게 달라붙어서 진행하면, 지금 힘든게 다 처음에 시작부터 포기한 그 두 사람때문이라는 생각이 계속 들어서 안 받아도 될 스트레스까지 이중으로 받게되는 바람에 진짜 둘 중 한 사람이 포기하고 싶다는 생각이 들지도 몰랐다.

 

그래서 또 한 가지  결론을 내렸는데, '프로젝트 완성은 하되 천천히, 쉬엄쉬엄 하자' 이다.

아마 위의 결론이 아무리 프로젝트 참여 인원이 2명이 되버렸다고 해도 프로젝트 기간이 지나치게 오래 걸린 결정적인 이유일 것이다.

아무리 프로젝트 참여 인원이 2명이 되었고 프로젝트 규모가 두 명이서 하기에는 그리 작지 않다는걸 감안해도 3개월 하고도 보름이라는 시간은 프로젝트 기간이 지나치게 오래 걸렸다는 방증이다.

보통 국비 과정에서 4 ~ 6명 정도의 팀에서 모든 인원이 제대로 프로젝트에 참여했다고 할 경우 빠르면 2주, 늦어도 3~4주 안으로 프로젝트가 끝나는데 우리는 아무리 두 명이서 프로젝트를 진행했다고 해도 3개월이라는 말도 안되게 긴 시간이 걸리고 말았다.

천천히, 쉬엄쉬엄 하자는 느낌으로 프로젝트를 진행하게 되버린 바람에 진짜 심할 경우엔 하루에 1시간 정도만 작업을 하고 나머지는 대충 놀고 있는 스스로를 발견할 때마다 '이대로 괜찮은가....' 하는 생각이 문득 들기도 했다는것을 감안하면 확실히 프로젝트를 더 빨리 마무리 지을수 있음에도 불구하고 너무 느릿느릿하게 프로젝트를 진행했다는 것을 부정할 수가 없다.

 

사람이 참 간사한게, 막상 9월 초가 되어서 프로젝트를 완성하고 난 후에 프로젝트가 진행되었던 과정을 되돌아 보니 

그냥 처음부터 빡세게 달렸으면 7월중순 쯤 되서 프로젝트가 완성되지 않았을까 하는 생각이 들 정도였으니 말 다 했지 않은가.

결국 자기 객관화를 제대로 하고 프로젝트 기간을 살펴보면 '제대로 빡세게 달렸으면 적어도 한 달이상은 기간을 단축 시킬수 있었음에도 형이든 나든 시작부터 터진 악재에 스스로 겁을 집어먹고, 그걸 핑계로 느릿느릿 하게 놀면서 작업을 했다.' 가 될 것이고 이건 앞으로 개발자로서 경력을 쌓아 나가기에 앞서 진심으로 반성해야 할 부분이라고 생각한다.

 

어쨌든 이렇게 프로젝트도 끝났고, 프로젝트를 작성하면서 있었던 일들을 정리하는 이 회고록도 끝났다.

이제부터는 진행한 프로젝트를 기반으로 포트폴리오를 만들고 각종 회사에 서류도 넣고 면접도 다니면서

최대한 빠른 시일내에 취직해서 개발자 커리어를 시작하자.

 

지금 안 그래도 집안 경제 사정이 안 좋은데 나라도 빨리 취직을 해야한다.