본문 바로가기
프로젝트/MegabyteSchool

[Spring Boot]B2B 이커머스 플랫폼 비즈큐레이터

by 엑츄얼리 2023. 9. 12.

프로젝트 설명

기업간의 대량 구매/판매 및 맞춤 상품 제작 의뢰를 중개해주는 B2B 플랫폼

 

담당

1. 인증 (Spring Security를 통한 로그인|로그아웃, JWT 토큰)

2. 의뢰서 (CRUD)

 

Github

https://github.com/growing-every-day/ebnatural-bizcurator-backend

 

Api 설계

https://mkevin-study.notion.site/API-f7750933ed964026ab922863edad7301?pvs=4


주요 기술 스택

  • SpringBoot
  • SpringSecurity
  • SpringDataJPA
  • JWT

프로젝트 방향성

1. 현업과 유사한 프로젝트 구조

 최종 목표는 취업이기 때문에 현업에서도 도움이 될만한 프로젝트를 진행하고 싶었습니다.

 다방면으로 조사하고, 팀원들과의 소통 결과 아래와 같은 프로젝트 구조를 갖추었습니다.

역할

1. controller

     view와 service를 이어주는 징검다리 역할만을 수행

     service 실행 후 결과 값을 반환 (예외처리 X)

 

2. service

     @Transactional 을 통해 모든 예외처리는 service에서 진행

     GlobalExceptionHandler와 Optional을 적극활용하여 서버에러 최소화

 

3. domain & dto

     domain: Entity로 DB와 통신하는 객체

     dto: Request를 통해 받은 정보를 담은 객체 or

                                                                    DB탐색 결과 Entity를 변환한 객체

     Entity의 수정 작업은 직접적으로 진행하지 않고, Dto로 변환 후 실행
     => 데이터의 무결성 보존

 

 

2. 명확한 계층 간의 역할 구분

 상위의 역할 부분에 언급한 것처럼 계층 간의 역할을 명확히하여 일관된 프로젝트 구조를 갖도록 하였습니다. 

 이를 통해 코드 리뷰 시에 상호간의 코드를 더 쉽게 이해할 수 있었고, 팀원의 코드를 수정해야할 때에도 더 직관적으로 접근 및 수정이 가능했습니다.

 또한 Entity와 Dto의 역할을 명확히 했습니다.

 학습을 하다보면 Dto, Dao, Domain, Entity라는 용어들이 섞여서 사용된다는 느낌을 많이 받았고, 이를 명확히 하고자 멘토님께 여쭤봐도 혼용되는 추세라는 대답을 얻었습니다. 결과적으로 멘토님께 조언을 얻어 앞선 역할 3.과 같은 형태로 진행하기로 하였습니다. 

 

3. 기획에 대한 올바른 이해 기반 올바른 과정을 통한 결과 도출

  기획에 대한 명확한 이해 없이 코드를 작성한다면 결과는 제대로 나오지만 과정이 의도와 다른 경우가 종종 발생하게됩니다. 이 때 타인이 이를 유지보수할 경우가 생긴다면, 코드를 이해하기 힘들뿐더러 결과적으로 새로 작성해야하기 때문에 추가적인 리소스를 소요하게 됩니다. 이를 방지하기위해 기획에 대해 백엔드 입장에서 명확하지 않은 부분을 확실 시하고 팀원 모두가 기획을 이해하고 프로젝트를 진행할 수 있도록 하였습니다.

 


DB 모델링

원본링크: https://www.erdcloud.com/d/z53zr653h4LubHL8m

1. DB설계의 우선순위를 높게하여, 코드 작성 이전에 완성도를 최대한 높였습니다.

 이전에 프로젝트를 진행하면서 기획의 변경 및 새로운 방식의 제안 등 여러가지 이유로 DB의 수정은 불가피하다고 느꼈습니다. 그 과정에서 DB의 변경은 크게는 코드 전반을 수정해야할 정도로 번거롭고 과정에서 많은 오류를 야기했습니다. 이를 통해 잘 설계된 DB를 통해 프로젝트 진행 중의 수정을 최소화해야함을 배웠고 이번에 이를 실천하기위해 노력했습니다.

 

2. 테이블간의 연간관계를 명확히하고, 각각의 카테고리 테이블에 대한 자료형을 ENUM이 아닌 VARCHAR로 설정했습니다.

 식별, 비식별 관계를 명확히 하고, N:M 관계일 경우 N:1 과 1:M으로 나누는 식으로 테이블 관계를 직관적으로 맺어 개발 중에 쉽게 이해할 수 있는 설계를 하기위해 노력했습니다.

 또한 일반적으로 ENUM 타입으로 정의되는 카테고리 테이블을 서버에서 카테고리를 ENUM으로 관리했습니다. 이를 통해 카테고리 추가/수정/삭제 시, 서버에서만 조치되도록하여 번거로움을 줄임과 동시에, 앞서 언급한 것처럼 DB의 수정을 최소화하였습니다.

 

3. 상태를 나타내는 Column 들에 대해서 미리 상태를 서버에서 Enum으로 정의했습니다.

 협업을 하다보면 같은 상태에 대해서 서로 표기 방식이 달라 차질이 발생할 수 있다고 생각해서 이와 같이 진행했습니다. Enum을 활용했기 때문에, 추가/수정/삭제가 필요한 경우에도 리소스를 최소화 할 수 있다고 생각했습니다.


API 설계 및 구현

로그인 회원가입 관련 API (링크)

구현에도 많은 시간을 할애했지만, 원리를 이해하는데 더 많은 시간이 걸렸습니다. 결과적으로 끼워맞추듯이 적용했다보니, 조금 더 직관적이고 유지보수가 쉽게 작성할 수 있는 방법을 고민할 시간이 부족했던 점이 아쉽습니다.

 

1. SpringSecurity 적용

 처음에는 SpringSecurity라는 프레임워크가 필요한 요소들을 implements 하여 구현하면, 자체적으로 비밀번호를 체크해준다는 점을 받아들이지 못했습니다. 결과적으로 UserDetailsService를 implements한 클래스의 loadUserByUsername 메서드의 반환 객체를 통해 스프링 자체적으로 입력된 비밀번호와 반환 객체의 비밀번호가 일치하는지 확인한다는 점을 이해했습니다.

 

2. JWT 적용

 아직 완전하게 이해했다고 말하기는 힘들지만, JWT 적용하는 과정을 통해 Spring의 여러 Filter와 각각의 기능들을 익힐 수 있었습니다. 그 외에도 JWT 의 취약점과 이를 보완하기 위해 refresh token 방식을 적용했습니다. 결과적으로 보안과 관련된 부분들은 취약점을 명확히 알고 이에대한 대비책을 마련해야한다는 점을 배웠습니다.

 

3. 인증 메일 기능 적용

 외부 api와 guide를 활용하여 관리자 이메일을 통해 서버에 아이디 비밀번호를 입력하면 api를 통해 인증 메일을 송신하는 기능을 적용했습니다. guide가 잘되어있어서 api의 적용은 어렵지 않았으나 서버 내부에 아이디 비밀번호가 저장되어있다는 점과 외부 api에도 이들이 보내진다는 점이 보안적 측면에서 찝찝함이 남아있었습니다. 관련해서 보안과 관련된 더 개선된 방식을 찾았으나 실패했습니다. 이런 생각을 하다보니 여러모로 보안의 중요성을 재고할 수 있었습니다.

 

 

구매, 제작, 입점의뢰 관련 API (링크)

 jpa와 Optional 이해

 jpa를 활용한 DB와의 통신과 그 결과를 Optional을 통해 반환하여 NullPointException을 방지하고 Optional에서 이를 확인하여 예외를 처리하는 방식을 익힐 수 있었습니다. @Entity 객체에 대해서는 JPA가 DB와 자동으로 동기화하기 때문에 직접적으로 save하지 않아도 된다는 점도 배웠습니다. 아직 JPA에 대한 이해가 깊지 않지만 Spring에 충분히 익숙해지고나면 JPA도 깊게 이해하고 싶다는 갈망이 생겼습니다.

 


아쉬운점 or 개선요소

1. 다형성과 상속을 활용하여 여러 DTO와 Entity를 일관되게 관리했으면 좋았을 것 같습니다.

 데이터의 무결성과 DTO의 역할을 명확히 하기 위해 하나의 Entity에 대해서도 여러 개의 DTO를 생성해서 사용했습니다.

 (ex. Member Entity와 관련 DTO는 MemberDto, MemberRequestDto, MemberResponseDto)

 이들 간에 상속 관계를 형성하고 다형성을 활용해서 코드를 작성했다면 더 객체지향적이고 이해하기 쉬운 코드를 작성했을거라는 아쉬움이 남습니다.

 

2. JWT를 조금 더 안정적으로 구현하거나 OAuth를 적용하고 싶습니다.

 JWT 적용을 위해 공부하다보니 이 기술이 완벽하고 안정적이지 않다는 점에 놀랐습니다. 지금에서야 말도안되는 생각이지만, 당시에는 현재 많은 기업들이 사용하는 방식이라 보안 취약점이 거의 존재하지 않을 거라 생각했습니다. 결과적으로 모든 기술에는 trade-off가 있다는 점을 배웠습니다. 

 OAuth 또한 JWT 처럼 보안 취약성이 있을테고, 프로젝트 아키텍처에 따라 JWT 보다 취약한 방식이 될 수도 있을 것으로 사료됩니다. 다만 더 나은 기술이라고 얘기되는 만큼 이를 적용해보면서 OAuth의 장점과 단점을 명확히 인지하여 기술의 trade-off를 판단할 수 있는 능력치를 기르고 싶습니다.

 

3. 프레임 워크를 적용할 때, 공식 문서를 활용하는 습관을 들이려합니다.

이번에 Spring Security와 Jwt를 적용할 때, 인터넷 강의와 구글링에 의존을 많이했습니다. 그렇다보니 버전의 차이 때문에 발생하는 오류들에 대해서는 대처하기가 많이 어려웠습니다. 당시에는 마음이 급해서 생각하지 못했지만 뒤돌아보니 공식 문서를 이해하기위해서 노력했다면 시간도 더 절약되고 중요한 능력을 기를 기회를 날려버린 것 같다는 아쉬움이 남습니다.

 

'프로젝트 > MegabyteSchool' 카테고리의 다른 글

[Java] ToyProject - SmartStore  (0) 2022.11.26

댓글