쌩로그

24.01 - 24.04 입사 OJT 프로젝트 회고록 본문

Project/회고

24.01 - 24.04 입사 OJT 프로젝트 회고록

.쌩수. 2024. 7. 1. 09:51
반응형

목록

  1. 서론
  2. 본론
  3.   테스트 코드의 필요성
  4.   하지말라는 데에는 이유가 있다(JPA 양방향 연관관계)
  5.   문서화에 대하여
  6.   팀원과의 의견 충돌
  7.   해당 프로젝트에서 어려웠던 점
  8.   해당 프로젝트에서 아쉬웠던 점
  9.   해당 프로젝트를 통해서 깨달은 것들
  10. 고민 포인트 및 생각 정리

1. 서론

간략한 회사 소개

현재 입사한 회사는 SI회사이고, 국내 유명한 모니터링 회사와 해외의 업무자동화 최적 플랫폼의 회사와 파트너를 맺고 있는 회사이다.(상호는 생략한다.)
지금 현재 글을 쓰는 시점은 정규직이 된 지 1달이 막 넘은 시점이다.
나는 현 회사에 1월초에 입사를 하였고, 3개월의 수습기간을 거쳐 4월 2일에 정규직으로 전환이 되었다.
나를 포함한 4명의 동기가 있다
나는 연구개발 부서로 배정받았다.(R&D라고 한다.)
다른 팀원들은 현재 각자의 상황에 맞게 고객사 프로젝트로 나가있고, 나 또한 다른 한 분과 현재 고객사로 파견 중이다.
한 명 말고는 같은 건물에 있다.

포스팅 개요

1월 2일에 입사하여, 입사 2주차부터 OJT와 겸하여 사내에서 사용하기 위한 웹 애플리케이션 프로젝트를 진행했다.

해당 프로젝트를 현재까지 진행하면서 경험하고, 고민하며, 무엇이 부족한지, 무엇을 배웠는지에 대해 풀어보려고 한다.

2. 본론

2-1 . 프로젝트 개요

프로젝트 설명

위에서 말한 것처럼 사내에서 사용할 서비스를 개발했다.

우리 회사엔 이전부터 전통이 있었다.
업무를 위해 개발된 서비스들은 이전에 입사햇던 선배들이 OJT 기간동안 개발한 서비스란 것이다.
우리도 그 전통을 이어받아 사내에서 사용할 서비스를 OJT 기간동안 프로젝트를 도맡아서 진행했다.
나와 동기들(이하 우리)이 개발한 서비스(프로젝트)는 회사 선배들이 이미 사용 중인 서비스의 단점이 개선되고자 하는 바램으로 시작된 프로젝트이다.
쉽게 말하면 우리가 외주를 맡은 사람들이고, 회사직원이 고객사인 구조다...ㅋㅋ;;
간략한 회사 소개에서 말한 것처럼 모니터링 회사와 파트너를 맺고 있는 회사라고 했는데, 우리 회사의 모니터링 서비스를 이용하는 회사들이 있다.
고객사와 관련된 정보들을 이전의 선배들이 만들었던 서비스로 관리중이었는데,
그런 정보들을 더욱 쉽고 간편하게 보고싶은 선배님들의 바램이 있었고, 더불어 추가되었으면 좋겠다는 기능에 대한 생각도 가지고 계셨다.
그런 바램들이 다 요구사항에 반영되었다.

참로고 대외비적인 부분이 있으므로, 상세하게 설명하지 못하는 점 양해를 바란다.

사용 기술

서버와 클라이언트를 분리한 CSR 방식으로 개발을 했다.
사용 기술은 다음과 같다.

  • 백엔드
    • 스프링부트 3.2
    • 자바 21
    • JPA
      • 스프링 데이터 JPA
      • QueryDSL
    • 스프링 시큐리티(구글 OAuth 로그인)
    • MySQL(RDB)
    • Redis(JWT 관리를 위해 사용)
  • 프론트 엔드
    • JS ES6
    • 리액트 18
    • 노드 20(노드는 큰 의미가 없다.)
    • 타이니MC 에디터

뭐 딱히 특별한 것은 없다.
그냥 평볌하다.
Tool까지 굳이 언급하자면,
슬랙, vsCode, 노션, 인텔리제이
(나는 프론트엔드에서 vsCode말고 젯브레인의 툴 웹스톰을 사용했고, MySQL 워크벤치를 사용하던 동기들과 달리 젯브레인의 DataGrip을 사용했다.)
그리고 깃랩.

2-2. 새로 적용한 기술적인 내용

1. Oauth 2.0 로그인의 redirect-url

여기에 글을 따로 작성했다.

구글 캘린더 API 사용

추후 작성 예정
그 외에 스케줄링 적용이 있다.
스케줄링 적용은 검색만 해도 많은 내용들이 나오기 떄문에 알아서 알아보면 좋을 것 같다.

3. 고민 포인트 및 생각 정리

테스트 코드의 필요성

해당 프로젝트를 할 당시 박우빈님의 테스트 강의를 보고 있었다.
그래서 헷갈리는 개념이 있을 때 테스트 패키지를 열고, 헷갈리는 개념에 대해서 테스트했다.

예를 들어, JPA에서 Entity를 생성하고, 조회할 때 생성한 Entity와 조회한 Entity가 동등성과 동일성이 보장 되는건데,, 보장되는지를 확인하기 위해서 작성했다.

그러다가 팀원들의 코드가 합쳐지고 하다보니 어느샌가 작성했던 테스트들을 다 주석처리하기 시작했다.
그리고 서버를 실행시켜 POSTMAN 혹은 리액트의 npm을 동시에 실행시켜 브라우저에서 확인했다.

매번 DTO나 Entity에 필드가 추가될 때마다 작성했던 테스트 코드들의 DTO, Entity도 수정해줘야 했고, 메서드 이름들도 조금 더 직관적인 메서드 이름들로 바꾸고 싶은 경우가 많아서 메서드 이름을 바꾸면 테스트 코드의 메서드호출 코드도 수정해줘야 했다.
(코드 컨벤션이 있으면 좋지만, 이 얘기는 뒤에서 하겠다.)
그래서 메서드 이름도 바뀌면 테스트 코드의 메서드들도 다 바꿔주어야 했다.

초반에는 서버를 재실행하고 하는게 어느정도 괘찮았다.
하지만, 프로젝트가 길어지면 길어질수록 그만큼 테스트 해야 하는 기능들이 많아지다보니 정상적으로 수행되는지 테스트 해야 되는 경우도 많았다.

그 뿐만이 아니었다.
팀원(입사 동기)이 "성수님! 이거 안 돼는데요?!" 하면 하던 거 멈추고, 그거부터 고쳐주고, 다시 하던 걸 하는 경우가 많았다...
고쳐줄 때조차 테스트가 필요했다.
고쳐지면 "이제 해봐요~ 될 거에요 pull 땅기시고요!" 라고 말했다.

그래서 다음부터는 테스트 코드를 좀 짜면서 프로젝트를 진행해야겠다고 생각했다.

TDD..??

얼마 전엔가 TDD에 대해 논쟁을 펼치는 내용을 링크드인에서 봤다.
또한 패스트캠퍼스에서 The Red(?) 로 TDD 강의를 찍은 이규원 님의 글이 있었는데. 조금 인상깊었다.
TDD 를 하면 코드의 양이 프로덕트 코드보다 월등히 많아질 수 밖에 없다.
본인은 회의에 대한 얘기를 하시면서, 15분의 회의를 위해서 회의를 통해 진행할 내용을 정리 및 작성하는데, 75분이 걸린다고 하셨다.
즉, 시간상 5배차이다.
그 15분을 원활하고 순조롭게 진행하기 위해서 75분을 사용한다는 것이었다.
이와 같이 TDD도 마찬가지다.
테스트 코드의 양이 많아지더라도, 좋은 제품을 생산하기 위해서 TDD를 한다고 하셨다.
(참고로 워딩이나 표현이 기억에 의존해서 쓰는 거라, 정확하지 않을 수 있는 점 양해바람...!! 당시 글을 일고 이해한대로 쓰는 것이다...)
회사 선배는 TDD가 좋긴 하지만, 현실에서는 프로덕트 코드 짜는 것도 바빠서 현식적으로는 어렵다고 한다.
그래도 테스트 코드는 정말 필요로 하는 것 같다.
나는 나중에 이전에 했던 프로젝트를 TDD로 해볼 생각이다...!!
(나름 버킷 토이리스트 중 하나다.ㅋㅋㅋ)

참고로 다들 아실테지만, 테스트 코드 작성이 TDD를 얘기하는 것은 아니다.
둘은 별개다.

하지말라는 데에는 이유가 있다(JPA 양방향 연관관계)

해당 프로젝트를 진행하는데 있어서 기술이나, 툴은 우리의 자유였다.
팀원들도 JPA로 프로젝트를 해보고 싶다고 했고, 나는... 당시 JPA 로드맵을 듣는 중이었기 때문에, JPA 뿜뿌에 차오르고 있었다.

(현재는 그 거품이 빠졌다. MVC도 제대로 모르는 게 너무 많고, 하다보니 RDB 지식의 한계를 느꼈다...기초가 ㄹㅇ 중요한 게 뼈저리게 느낀다...물론 거기에만 머물고 있진 않아야 한다고도 생각한다.)

영한님이 강의에서 하셨던 얘기는 다음과 같았다.
"먼저는 단방향으로 하다가 필요할 때 양방향으로 하라"고 했다.
배우는 입장에서 그냥 그런가보다 하고 넘어갔다.

일단 해당 프로젝트의 연관관계는 모두 양방향인 관계에서 시작했다.
당시에 연관관계 매핑 맺는 것도 재밌었고, 애너테이션 쓰면서 기분 좋았다.
기분 좋게만 하면 안 되긴한데...여튼,, 그랬다...

그런데 하다보니깐 양방향 관계를 맺으면 오히려 복잡해진다는 것을 알았다.
예를 들어 제일 많이 나오는 예시인데,
팀과 멤버가 있다고 하자.
그리고 덧붙여서 팬이 있다고 하자.
팬은 팀의 팬이 될 수도 있고, 팀의 멤버의 팬이 될 수도 있다.
팀 -> A, 멤버 -> B, 팬 -> C 라고 가정할 때,
A 안에 B가 있고, A안에 C가 있을 수도 있고, B안에 C가 있을 수도 있다는 것이다.
대충 ERD를 나타내보면 이렇다.

A가 지워지면, B와 C가 같이 지워져야 한다.
B가 지워지면 C가 지워져야 한다.
그런데 요구사항 중엔 실제 물리적인 삭제를 하면 안 되고, 삭제 처리가 되어야 한다.
그리고 추후에 삭제된 데이터는 복구도 되어야 한다고 했다.
그냥 물리적인 삭제가 가능하다고 하면 정말 쉬운 내용이다.
그냥 삭제처리도 쉽다.
A를 삭제하면 B를 삭제하고, C도 삭제하게 하면 된다.
B를 삭제하면 C도 같이 삭제하게 하면 된다.
그리고 물리적인 삭제를 하지 않더라도, JPA에서 delete를 쳤을 때 update 쿼리가 나가서 삭제 처리를 할 수 있도록 지원하는 애너테이션도 있다.
삭제는 쉽다.
그런데 복원까지 생각해보면, 정말 복잡해진다.
A를 복원하는 순간 A와 관련된 B도 복원해야되고, 그와 관련된 B도 복원해야 한다.

처음에는 양방향 관계로 설정해서 흔히 연관관계 메서드를 통해서 연관관계에 놓인 객체들의 연관관계를 하나의 메서드 안에서 처리해주면 된다.

그리고, 삭제를 할 때는 연관관계 삭제 메서드를 두었었다.
그래서 하나의 메서드 안에서 서로 연관된 객체의 관계를 서로 끊어주었었다.

그런데 복원을 생각하면 이게 정말 복잡해진다.
연관관계를 끊었던 객체들을 다시 찾아서 연관관계를 맺어줘야 했는데,,,
A를 복원하고,
B를 복원할 때는 A와 관련된 B를 찾아서 복원해주고,
C를 복원할 때 A와 관련되고, B와 관련된 데이터를 찾아 복원해줘야 한다.
지금 이렇게 A,B,C가 있지만, A,B,C는 타입이고, 각각의 타입에 따른 인스턴스들은 또 얼마나 많을것인가..
따라서 서로 연관관계를 끊는 것이 좋은 선택이 아니었다.
맺었던 연관관계는 놔두고 가되 삭제 처리를 나타내는 컬럼(DB에서는 컬럼, Entity에서는 필드)을 두고, 삭제 처리되었는지 아닌지에 따라 사용자에게 나타내는 것이 좋은 거 같았다.
그리고 양방향 연관관계가 능사는 아니었다.
그냥 외래키를 두는 테이블과 매핑되는 Entity 클래스에 단방향 연관관계를 두고,
A를 복원처리했다면, A를 참조하는 B만 찾아서 복원시켜주고,
복원한 A, B를 참조하는 C를 복원처리만 해주니 양방향 연관관계를 맺고 연관관계를 생각하면서 코드를 작성할 때마다 더욱 더 깔끔하게 처리했다.

하지말란 데에는 다 이유가 있었다는 것...
처음엔 단방향으로 가져가되 정말 필요로 할 때 양방향 연관관계를 맺어라고 한 이유를 이번 프로젝트를 통해서 더욱 더 잘 알게 되었다.

※ 참고로 취준용 프로젝트에서는 삭제를 했다만,
실무에서는 데이터를 물리적으로 삭제하는 경우는 거의 없다고 한다.

문서화에 대하여

문서는 정말 중요하다는 것을 프로젝트를 하면서 많이 느꼈다.
백엔드보단 프론트에서 해당 내용을 많이 느꼈는데,
(프론트를 다들 리액트로 한 적이 없고, 프론트엔드의 입장에서 문서를 안 써서 그런 걸 수도 있다..)

예를 들면, 버튼을 왼쪽으로 조금 옮긴다던가, 오른쪽으로 조금 옮기는 내용들이 날마다 사람의 기분따라 바껴지는 느낌이었다.
(이 내용은 화면 정의서가 있으면 단번에 해결될 문제이긴 하다.)
버튼에 대한 내용은 예를 든 것일 뿐, 어쨋든 나도 팀원에게 어제는 A같이 말해놓고, 다믕날에 다르게 말했다. ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ
이건 내가 분명히 잘 못했다.

예전에는 (한 5~6년 젊을 때는) 기억에 의존할 수 있을만큼 기억력이 좋았다만,
이제는 그럴 수 있는 시기가 아닌 거 알면서도 기억에 의존했던 수많은 시간에 익숙해져서 그런가 뭔가 기록하는 데에 익숙치가 않다.
이런 일이 반복되다보니... 뭔가 요구사항이 발생했고 의견이 있을 때는 문서로 남겨놓는 것이 정말 중요하겠구나 라는 생각이 들게 되었다.

팀원과의 의견 충돌

ERD 설계

해당 프로젝트를 하면서 ERD를 설계를 해놓고도 많이 흔들렸다.
참조관계를 어떻게 가져갈 것인가에 대한 내용이었다.
그러면서 내가 DB에 대한 지식이 조금 많이 부족함을 느꼈다.
ERD 설계를 할 때 DB상으론 팀원의 의견이 맞긴했는데, 코드를 작성하기에는 그게 아니었다.
JPA의 강점은 DB에 의존적인 개발이 아니라, 자바와 스프링이 지향하는 객체지향적인 설계와 객체지향적인 애플리케이션을 만들 수 있게 해준다는게 굉장히 큰 강점이라고 본다.
나는 객체를 생각해서 ERD를 작성했지만, 팀원은 DB를 생각해서 ERD를 바라보았던 거 같다.
이것 떄문에 얘기를 많이 했다.
DB에 대한 지식이 그 팀원이 조금 더 있었던 거 같지만,
해당 설계대로 개발을 하자니...수용하고 싶었지만, 수용하면 개발이 힘들 것 같았다.
그래서 의견 충돌이 많이 발생했다.
결국엔 백엔드 코드를 더욱 더 많이 만지는 나의 의견 쪽으로 기울어지긴 했는데,
상대방을 설득하기에 많이 부족했다.
팀원도 머지않아 내 의견을 따라주는 것 같아서 미안하기도 했다.
그래도 덕분에 후에 후회하지 않을 수 있는 결과가 뒤따른 것 같아서 정말 다행이었다.

PathVariable vs RequestBody

이 외에도 PutMapping시에 Body에 id를 담을 것인가, 아니면 PathVariable에 id를 담을 것인가에 대한 의견도 충돌하긴 했는데,
PutMapping시에 body에 id를 담는 경우도 있고, PathVariable에 id를 담는 경우도 있고,
제각각이었다.
물론 두 방식 다 구현이 가능하긴하다.
나는 PathVariable에 id를 담는 방식을 선호한다.
왜냐하면 PUT 매핑은 POST의 기능도 하지만, POST와는 다르게 자원의 경로를 알고있기 때문이다.
따라서 HTTP 메서드의 방식에 따르면 자원이 표현되는 PathVariable에 id를 담는 것이 좀 더 맞지않을까? 하는 생각에서였다.
이 건은 프로젝트 완성이 임박함에 따라 전적으로 백엔드를 내가 다 하게 되었고,
팀원들은 프론트에 다 붙게 되어서 결국엔 내가 지향하는 대로 되었다.

해당 프로젝트에서 어려웠던 점

진짜 어려웠던 점은 거의 없었다. 오히려 재밌었다.
왜냐하면 1월부터 3월까지 진행했던 프로젝트였는데,
해당 기간동안 영한님의 JPA 로드맵을 다 수강하면서 해당 프로젝트를 진행했다.
어려웠다기 보다는 영한님이 실무에서 "이렇게하면 클납니다~" 하는 그 얘기가 이번 프로젝트를 통해서 굉장히 와닿았다. 그래서 재밌었따.
예를 들어어 벌크성 update 쿼리 같은 경우 배울 때는 "아~ 그렇구나" 했었고,
해당 프로젝트에서 벌크성 update 쿼리를 사용했었다만,
그 뒤로 쿼리가 더 나가야 되는데 안 나간다....??

이유는 @Modifying애너테이션에서 clear 속성에 true를 줬기 떄문이다.

영속성 컨텍스트가 비워지니깐 그 뒤로 쿼리가 나가야되는 상황임에도 불구하고, 안 나가길레,
"아~ 이게 이렇게 되는 거구나..."하면서 다시 Entity를 조회해서 update 쿼리가 나가도록 했었다.
그리고 대부분의 어떤 트러블 슈팅은 영한님의 JPA 로드맵 (JPA 기본, 실전 1,2, Spring Data JPA, QueryDSL) 5개를 들으면 웬만한 트러블 슈팅은 다 해결할 수 있는 정도로 나와서 그리 어려운 것은 없었다.
아직 내게 있어서 두려운 건 해보지 않은 것을 해보려 할 때가 긴장을 많이 하는 것 같다...
요구사항이 명확하지가 않아서 적용을 했음에도 쓰이진 않지만, 스프링에서도 스케줄링을 지원한다.
"아침 몇시에 어디 고객사에 지원가야 합니다~" 라는 메시지가 이메일로 발송되도록 해야했었는데, 스프링에서 스케줄링을 지원하는 것을 보고 깜짝 놀랐다.
그리고 위에 작성했던 구글 캘린더 API는 문서를 진짜 많이 봤다. 영업일 기준 5일은 사용했다.
팀원 한명이랑 머리 싸메고 문서보고 오만때만 난리 부르스를 치다가 결국은 해냈는데,
문서 읽는 것도 쉽지 않은 것이었다.

그래도 한 가지 깨달은 점은...
"그냥 해보면 된다. 이미 누군가 했고, 누군가 했기 때문에 나에게 친숙한 것.. 굳이 긴장하고 두려울 필요가 없다"는 것이다.

앞으로 새로운 기술, 매커니즘을 적용할 때는 도전적인 마인드로 해야겠다..
어차피 되기 때문이다..

해당 프로젝트에서 아쉬웠던 점

위에서 언급했지만, 문서화가 많이 아쉽다.
말이 계속 바뀌는 부분들이 있었는데, 이를 문서화를 해놓았으면 뒷말이 나오지 않고 깔끔하게 프로젝트가 진행됬을 것이다.
내가 그런 부분도 있고, 다른 팀원이 그렇게 한 부분들이 있지만, 내가 제일 많이 뭔가 제안하다가 바꾼 거 같다...
이 부분은 팀원들에게 미안하다.
그리고 메서드 이름을 좀 더 직관적으로 하기 위해서 좀 바꼈다고 했는데,
코딩 컨벤션에 대해서 그리 중요하게 생각 안 했었는데, 이번에 왜 중요한지를 한 번 생각해보게 되었다.

규칙을 정해놓고 가는 것과 무규칙인 상태에서 규칙이 만들어지는 것은 차원이 다른 거 같다....!!

해당 프로젝트를 통해서 깨달은 것들

  1. 문서화는 중요하다.
  2. 테스트 코드의 중요성
  3. 나의 DB 지식 부족
  4. 구현 불가능한 것은 없다.
  5. 나는 글읽기를 그리 좋아하진 않는다.
  6. 소프트 스킬이 부족하다.
  7. DB가 부족하다.
  8. MVC도 아직 미숙하다.

4번까지는 위의 글들로 충분히 설명되리라고 생각한다.

5번은 구글 캘린더 API를 사용하면서 많이 느꼈다.
일단 글이 많으면 힘들어진다...
(당시엔 그랬는데, 요즘에 책을 조금이라도 더 접하고 있어서 그런지 긴 글에도 낯설진 않다.)

그런데 구현을 해야만 하는 것이 있었다보니 구글 캘린더 문서를 겁나게 뒤져봤다.
그리 좋아하진 않지만, 해야될 땐 보는 나를 보고 살짝 의외였다.
6번 소프트 스킬이 많이 부족하다.
개발 시굴과 능력말고도, 커뮤니케이션, 문서화 등 아직 부족한 부분이 많다.
링크드인, 커리어리 등 많은 인사이트들이 있다.
그런 것들을 보고 좀 배워야겠다.
7번은 팀원과의 의견 충돌에서 드러났다만, 조만간에 DB에 대한 공부를 철저히 해볼 생각이다.
MVC도 아직 미숙하다.
예외 처리, Bean Validation 등... 적용은 했지만, 아직 미숙하다.
돌아보면 뜯어서 고쳐볼 것들이 많다.
이 내용은 지금 영한님 MVC 2편 듣고 있는데, 해당 강의로 다 채워질 것 같다.
객체의 책임과 역할 부여에 대한 생각도 풀어보고 싶긴한데...
이건 다음에 다른 개인 토이 프로젝트를 통해 적용해보고, 이야기를 풀어보겠다..

7월 1일 : 해야 될 것

구글 캘린더 API 글 쓰기
해당 단란은 포스팅 완료시 지움..

728x90

'Project > 회고' 카테고리의 다른 글

미안하다. -To. 나에게 -  (2) 2023.05.04
Comments