[Spring]백엔드 넘블 챌린지 - 당근마켓

slee2·2022년 1월 21일
1

넘블챌린지

목록 보기
1/1

http://54.180.83.222:8080/

시작하기 앞서서

원래는 개발일지를 하루하루 작성하여 해당 노션을 공개하는 방식으로 생각하였지만, 넘블에서 블로그를 통해 한번에 전부 보여주는 것을 희망하는 것 같아, 제 개인 블로그에 작성하게 되었습니다.

넘블에서 모바일을 기준으로 평가한다고 하였기에
모바일 기준으로 프로젝트를 만들었습니다.


진행방식

DB 설계(ER 다이어그램)
aws 서버 구축
로컬에 mysql 생성 후 테이블 설정
DB와 Entity를 사용하지 않고 Memory 데이터로 어느정도 스프링 작성
DB와 Entity를 연결하고 스프링 작성
ec2로 데이터를 가져와 서버 구동 테스트
테스트 케이스 작성

순으로 진행하였습니다. 테스트를 먼저 작성한 뒤에 그걸 토대로 리포지토리, 서비스, 컨트롤러를 만드는 경우도 있다고 들었는데 어려워 보여 테스트를 마지막에 작성하였습니다.


ER 다이어그램

이번 챌린지는 다행(?)히도 쿠팡때보다 설계가 훨씬 수월했던 것 같습니다.

User

회원 테이블입니다. 이메일, 패스워드, 이름, 전화번호, 닉네임, 그리고 프로필 사진의 실제 경로와 저장했을때의 경로를 가지고 있습니다.

다만, 전화번호를 String으로 저장하여 이부분이 잘못되었다고 생각하지만, 고치기에는 너무 큰 산을 넘은 느낌이여서 Integer로 못바꾸기도 했으며, 전화번호에 대한 정확한 이야기가 없어 String으로 저장하였습니다.

Item

게시판입니다. 저는 판매하는 제품이라 생각하여 Item이라고 지었습니다. Item은 판매자, 카테고리, 제목(name), 내용(main), 게시한 날짜(date), 가격, 그리고 사진들중 첫번째 사진을 가지고 있습니다.

Thumbnails

사진들입니다. 상품의 사진들을 저장하는 테이블입니다.

Comment

댓글입니다.

Category

카테고리입니다. 어떤 방법으로 카테고리 테이블을 이용해야할지 고민하였고, 결과적으로 카테고리 아이디와 이름(1, '디지털기기'), ...을 통해 먼저 데이터를 넣어두고, Item에서는 카테고리 아이디를 통해 접근할 수 있도록 설정했습니다.


AWS

ec2를 통해 서버를 구축하였습니다.
여기에 대해서는 제가 자세히 아는 것이 없기 때문에 어떻게 설정했는지 자세히 설명은 어려울 것 같습니다.

https://victorydntmd.tistory.com/338
여기 글을 보고 설정을 따라하여 성공하였습니다.

아무튼 ssh로 접속 완료.

RDS

rds도 마찬가지로 위의 글을 따라 진행하여 성공하였습니다.


Repository

여기서 JpaRepository를 사용하면 자동으로 해결해주는 것을 알고 있었지만, 잘 알고 있지 않아 혹시 오류가 발생하였을때 대처를 못할 것 같아서 수동으로 작성하였습니다.

Service

그리고 서비스 부분은 솔직히 큰 역할을 했는지 의문이 좀 듭니다. 저장 폼을 유저로 바꾸는 세팅을 해준다? 정도로 했는데 어... 잘 모르겠습니다. 해야할건 많은데 한건 많이 없는 느낌입니다.

Controller

컨트롤러에서는 진행한것이 꽤 많습니다. 컨트롤러에서 어떤 처리를 했는지 설명하겠습니다.

컨트롤러는 세세하게 다 보여주기 보다는 사이에 들어간 작업을 보여드리는 방식으로 진행하겠습니다.

회원가입

회원 가입의 경우 Post로 받았을때 먼저 공백이 있는지 또는 해당 아이디가 존재하는지 검사를 합니다. 이는 @Valid에서 AddForm에 이상이 없는지 1차로 검사를 합니다. 이는

위와 같이 @NotBlank를 통해 가장 강한 검사를 처음에 해주고 비어있거나 공백일 경우에 해당 에러 메세지를 BindingResult에 담아줍니다. 하지만, 해당 아이디가 존재하는지에 대한 자세한 검사를 어노테이션으로 처리하지 못합니다.

그렇기 때문에 해당 오류를 검사해줄 Validation을 작성하였습니다.

여기서 검사에 따른 에러를 저장하게 됩니다. 또 해당 에러는

이런식으로 설정을 따로 하였습니다. 해당 설정을 적용하기 위해 application.properties 파일에 spring.messages.basename=errors를 추가하였습니다.

다시 돌아와 validate로 검사하여 중복되었는지 검사한 후에 에러를 가지고 있으면 다시 폼으로 보내고 모든 검사를 통과한다면, 저장을 해줍니다.
그리고 쿠키에 유저아이디를 저장해준 후에 유저 화면으로 넘겨줍니다.

회원가입 폼은 이와 같이 에러가 들어올 경우를 고려하여 작성하였습니다.

유저

유저 컨트롤러에서는 쿠키값을 받아 검사를 합니다. 만약 쿠키값이 없거나 쿠키값에 해당하는 유저가 없을 경우, 로그인 페이지로 이동시킵니다.

보내는 방법은 이와 같이 모델에 값을 넣어준 후에 Message.html로 보내면 messagealert()로 알린 다음 href로 이동하는 구조입니다.

이 방법은 대부분의 Get 방식에 검사를 하며 상품 수정같은 중요한 부분은 추가로 상품의 주인현재 세션의 유저인지까지 검사를 추가로 합니다.

사진 업로드

사진 업로드는 유저 프로필 수정과 상품 작성에 사용됩니다.

처음에 파일을 file로 사진만 가져오도록 작성하여 폼을 가져옵니다.

그럼 해당 파일은 MultipartFile 타입으로 받을 수 있습니다.

이때 .getOriginalFileName()을 이용하여 파일을 저장한 이름을 가져올 수 있습니다. 예를 들어 유저가 abc.png 라는 파일을 업로드 했다면, 그대로 가져옵니다. 하지만, 이렇게 저장하면 중복될 수 있는 경우가 발생하기 때문에 UUID.확장자(1234-1234-1234-1234.png)와 같이 바꿔준 후에 저장을 해줍니다.

여러장의 경우

이 작업을 반복하면 됩니다.

유저 프로필 수정의 경우 이와 같이 값을 받고 사진을 변환한 다음, 저장경로/유저가 업로드한 파일저장경로/UUID.확장자 두 경로를 저장합니다.

해당 파일은 /domain/upload에 있습니다.

관심 목록 추가

하트 버튼을 눌렀을 경우, ajax를 이용해 post로 보내면,

ResponseBody로 적용된 컨트롤러에 받아 관심목록 추가 또는 삭제 한 후에 그냥 반환해주면 버튼을 누를때마다 실시간으로 추가와 삭제를 할 수 있습니다.


application.properties

설정은 간단하게 로컬에서 사용할때의 데이터베이스와 ec2에서 사용할 데이터베이스를 나눈 뒤에 수동으로 바꾸면서 진행하였습니다.

사진 업로드 파일의 경우 클라우드를 따로 다루지 못하기 때문에 ec2에서 경로를 지정하여 파일을 저장하였습니다.


테스트

테스트의 경우 가상으로 빈에서 값을 설정하기 위한 @MockBean
모든 빈을 자동으로 등록해주는 @SpringBootTest를 같이 사용하여 테스트 코드를 작성하였습니다.

필요한 값들을 미리 설정하여 반환값이 정해져있도록 세팅하여 컨트롤러를 테스트하였습니다.

테스트 코드에 서비스는 넣지 않았습니다. 시간 관계상 작성하지 못했습니다.


프로젝트를 진행할 때 어려웠던 점

엔티티매니저

엔티티매니저와의 충돌이 많았습니다. 처음에는 엔티티에서 다대일, 일대다 관계를 양방향으로 설정하고 사용하였습니다. 양방향으로 사용하니 데이터 저장, 수정, 삭제 과정에서 엔티티매니저 오류가 많이 발생하였습니다.

그 경우에 양방향을 단방향으로 수정하니 해결된 경우가 꽤나 있었습니다.
그래서 엔티티 파일들은 단방향으로 된 것들도 있고, 양방향으로 된 것들도 있습니다.

설정과 관련된 오류

설정에 대한 예외가 발생할때도 머리가 많이 아팠습니다. 일반적인 예외가 발생한 경우 어디에서 발생했는지 정확히 위치가 나와 문제에 대한 파악이 빨라서 편했습니다.

그런데 설정과 관련된 예외는 어디서 오류가 터졌는지 찾기가 힘들었습니다. 안나오는 경우도 많아 일일이 로그로 찍어야 하는 참사가... 발생하였고 그래서 중간부터는 컨트롤러에 계속 로그를 남겨놨습니다.

Memory와 DB의 어려움

이거는 음... 제가 데이터베이스에 대해 잘 몰라서 그런 것도 있는데 원래의 계획은 Repository를 데이터베이스를 사용하지 않고 메모리로 만들어 간편하게 틀을 만든 후에 데이터베이스를 넣자라는것이 원래 목표였습니다.

그런데 사진업로드 부분부터 뭔가 잘 안될 것 같다는 생각도 들고 막연해서 메모리로 마무리를 못하고 중간부터 데이터베이스로 바꿨습니다.

뿐만 아니라 중간부터 리포지토리에 추가한 메서드들 때문에 몇몇 메모리리포지토리는 지우기도 했습니다.

Jpa Repository

아직 안배워서 사용하지 못했습니다.
구글링해서 사용하고 싶은 마음도 있었지만, 위에서 말했듯이 공부안하고 쓰면 오류터졌을때 못고칠까봐 수동으로 했습니다.

0개의 댓글