프로젝트 관련 질문 답변
SA질문
1.
API 설명 중 - "특정회원에대해 신고하는 경우 /api/v1/users/{userId}/report라고 작성해주는것보다 회원신고라는 Entity가 새로 생성된다는점에서 /api/v1/report/{userId} 이런식으로 url을 변경하였는데 url을 이렇게 바꾸는게 맞는건지 잘 모르겠습니다. / 또한 특정 상품에대한 좋아요같은경우 /api/v1/product/{productId}/likes 이런식으로 뒤에 likes를 붙였는데 위에서 한것과같이 /api/v1/likes/{productId} 라고 생각하니 엄청 어색하다고느껴져서 어떤식이 좀 더 맞는건지 궁금합니다." 이 내용도 위와 동일하게 어떻게 결론 내셨는지 진행상황을 설명 해주세요.
: 계층구조에 집중하기보다는 특정 리소스에 대한 동작에 집중하여 가독성을 높이는 쪽으로 url을 디자인했습니다. 신고라는 Report Entity가 리소스이면서, Restful API를 나타내기 위해서 /api/v1/reports를 기본으로 정했고, Controller RequestMapping주소를 활용하면서 생성 시 /api/v1/reports + RequestBody형태로 수정, 삭제 시 /api/v1/reports/{reportId}형태로 결정했습니다.
또한 계층형으로/api/v1/reviews/{reivewsId}/comments 쓰게 되면 리뷰에만 사용해야되어 비슷한 구조의 메서드들이 많이 생길수 있고 딱 리뷰에만 사용해야 하게때문에 새로운 계층이나 관계를 추가하기 어렵습니다. 하지만 비계층형 /api/v1/comments 으로 하면 다른곳에서도 쓸수있기 때문에 유연성이 높아서 데이터 구조에 새로운 항목이나 관계를 쉽게 추가할 수 있습니다.
2.
API Context Path 설계 중 중간에 /v1을 다 삽입 하셨는데 나중에 어떤 활용을 염두해 두셨을까요? 간략하게 시나리오 예제를 만들어봐 주세요.
: v1을 삽입한 이유는 API버전을 url에 포함시키는 것이 후에 버전 업데이트에 대비해서 클라이언트와 서버간의 호환성 유지에 적합하다고 판단했고, 버전을 명시적으로 표시하는 것이, 서버 배포 후에 API가 업데이트될 시 이전 버전과 새로운 버전간의 관계를 효과적으로 나타낼 수 있다고 생각했습니다.
•
시나리오 예제
◦
버전 1.0 출시 : "/api/v1/image”를 사용한 기본적인 기능 제공
◦
기존 기능에대한 피드백 및 업데이트 : 이미지파일 생성기능에 이미지파일 리사이징 기능을 도입
◦
버전 2.0 출시 : v1에서 제공하는 기능에 추가적인 기능을 추가하여 "/api/v2/image"로 업데이트
3.
ERD 중에 - "현재 저희의 설계단계에서는 식별관계처럼 쓰이지않는다고 생각해서 비식별관계로 통일" 라는 코멘트가 남겨져 있는데 좀 더 부연설명을 해주셨으면 합니다. 맞냐 틀리냐를 떠나서 팀에서 어떻게 의사결정을 해서 이런 결과를 도출했는지 설명해주세요.
: 설계단계에서 비식별관계로 통일함으로써 부모entity의 키 변경이 자식entity에 영향을 미치지 않고, 변경사항이 생기면 더 유연하게 모델을 구축할 수 있다고 판단했습니다.
4.
리뷰 테이블에 이미지 컬럼이 있는데 타입 재확인 부탁드립니다.
: S3 콘솔에서 새로운 버킷을 만들고,MultipartFile 타입 을 이용해서 이미지를 받은후 해당 버킷에 업로드 한후, 이미지의 S3 버킷 URL을 얻어내어저장하고 있습니다.
5.
채팅메세지 테이블에 user_id column이 1개만 있는데 수신자 id를 저장하나요 아니면 발신자 id를 저장하나요? 유효한 컬럼인지도 검토 부탁드립니다.
: 채팅메시지 테이블의 id컬럼은 Chat Entity에 대한 개인키 컬럼이고, 기존에 있던 user_id 컬럼은 수신자와 발신자가 1:1로 채팅을 하기 때문에, 서로 발신자id에 대한 컬럼만 존재하면 되기때문에 sender_id로 컬럼을 수정하였습니다.
기술질문
1.
OpenAPI를 사용해 책 가격을 가져올 때 어떤 플랫폼을 이용하셨고 왜 그런 선택을 했나요?
:
•
국립중앙도서관API
장점: 국립중앙도서관API는 국가의 중앙 도서관이라는 신뢰성을 가지고 책에 대한 정보의 정확성 또한 높을 것이라 생각했고, 국내 도서에 특화된 정보 제공이 가능합니다.
단점: 중고 책 관련 사이트가 중점이기때문에 국내 도서에 집중하는 것보다는 해외 도서에 대한 정보 또한 필요하다고 생각했고, 그런점에서 국립중앙도서관의 데이터베이스는 다소 한정적이고 다양성이 부족하다고 생각했습니다.
•
KAKAO OPEN API
장점: 마찬가지로 국내 기반이지만 해외도서 정보 또한 풍부하게 제공이 가능하고, 개발 문서, 예제와 같은 정보 또한 개발자를 위해 제공합니다. 또한 다른 Kakao 서비스와 연동이 가능합니다.
단점: 일일 호출 제한 수를 초과하면 유료API비용이 발생 가능
•
KAKAO OPEN API를 사용하기로 결정
국립중앙도서관api보다 해외도서, 신규 출판물 등을 포함해 제공하는 도서가 더 풍부하고, api접근성 또한 kakao open api가 더 용이하다고 생각했습니다. 책 검색 일일 쿼터는 3만건으로 프로젝트를 진행함에 부담이 없다고 판단했습니다.
2.
로그인 방식으로 어떤 방식을 채택했고 왜 선택했나요?
:
로그인 방식을 선택하는데 있어서 크게 두가지 고려사항이 있었습니다.
첫번째로 로그인 로직을 authentification filter를 작성하여 구현하는 방법과 userService에서 직접 구현하는 방법 중 무엇을 선택할까였습니다.
필터방식의 선택시 비즈니스 로직에서 인증 문제를 분리하여 모듈화로 유지관리가 쉽다는 점이 있겠고 직접 구현하는 방법은 인증로직을 작성하는데 있어서 더 유연하게 작성할 수 있다는 점이 장점이었습니다.
실제적으로 다른 api에서 요구되는 인가 상태는 authoriaztion filter를 통해 분리되어있는 상태였고
저희가 기존 구상했던 소셜로그인이나 차단된, 혹은 삭제된(soft deleted) 유저에 로그인 제한 등 인증 매커니즘 자체가 유연해야 겠다고 판단되어 인증의 경우 userService에서 작성하는 것을 선택하였습니다.
두번째는 세션방식과 토큰 방식 중 무엇을 선택할지였습니다.
세션 방식의 장점으로는 사용자의 모든 정보를 서버에서 관리하기 때문에, 로그인 상태를 유지하고 관리하기에 용이하다는 점, Http Only Cookies를 사용하여 CSS(Cross Site Scripting)취약점 즉, Javascript를 통한 쿠키 탈취 문제를 예방할 수 있다는 점, Secure Cookies를 사용하여 HTTPS가 아닌 통신에서는 쿠키를 전송할 수 없게하여 보안성에서 우수하다는 점이 있습니다.
하지만 단점으로 서버 측에서 사용자의 정보를 관리하고 상태를 유지하기 때문에, 서버 부담이 크다는 점이 있고, 로그인 상태 유지와 공유가 힘들다는 점, 서버 확장성이 떨어진다는 점이 있습니다.
Jwt토큰 방식의 장점으로는 사용자의 로그인 상태정보를 클라이언트에 저장하기 때문에 서버의 부담이 적고, 서버 간 토큰을 공유하거나 검증할 필요가 없기 때문에 확장성 측면에서 유리하다는 점, Header, Payload를 기반으로 한 알고리즘으로 Signature를 생성하는 구조를 가지기 때문에, 데이터 위변조를 막을 수 있다는 점이 있습니다.
하지만 사용자의 정보를 클라이언트 측에서 관리하기 때문에, 보안적인 측면에서 많이 위험하다는 단점이 있습니다.
결론적으로 트래픽관리, 확장성, 보안성 등의 장단점을 고려했을 때, 트래픽 처리를 보완하고, 추후 확장성 측면에서 세션 방식보다는 Jwt토큰 방식이 저희 프로젝트와는 더 적합하다고 생각했고, 보안성 측면에서는 서비스에서 주고받는 정보의 보안상 중요도가 다소 낮은편이며, 토큰 탈취같은 보안적인 문제는 별도의 Refresh토큰을 도입하여 예방이 가능하다고 판단했습니다.
3.
테스트 소스코드가 많이 작성 되어있는 편인데 개발 시 TDD를 진행한건지? 그리고 본인들이 생각하는 테스트 커버리지가 얼마나 되나요?
: 개발을 TDD방식으로 진행하지는 않았고, CI/CD방식으로 프로젝트를 진행하면서 1차 배포시기에 갖춰진 기능들의 기본적인 CRUD에 한해서 테스트코드를 작성하고 배포를 했습니다. 1차 배포 이후에 추가로 작성된 기능들은 아직 테스트코드를 작성하지 못했고 기존 테스트코드를 수정해야만 테스트가 정상적으로 되기때문에, 기존에 작성해둔 테스트코드는 주석처리하여 보류하고 후에 부하테스트를 하기 전 테스트코드를 리팩토링하고 기능테스트를 추가 할 예정입니다. 테스트 커버리지 또한 구현된 모든 기능에 대한 테스트코드가 작성되지 않았기때문에 측정할 수는 없었습니다.
4.
ERD 테이블명이 TB_로 시작하는데 명명규칙을 이렇게 정한 이유가 있나요?
: 기능 개발 시작 전 code convention을 진행하면서 테이블명은 tb_도메인명으로 하기로 정했고, 1차 배포를 하면서 대문자 소문자에 대한 일관성을 유지하기 위해 모든 테이블명을 TB_DOMAIN으로 수정한 뒤 배포를 했습니다.
5.
일부 중요한 프로퍼티가 github에서 조회되는데 어떻게 개선할 수 있을까
:
•
.gitignore을 사용하여 key를 담고 있는 파일이나 디렉토리를 버전관리에서 제외시키는 방법으로 github에서 중요 프로퍼티가 노출되는 것을 방지할 수 있습니다.
•
admin _token같은 정보가 서비스단에 하드코딩되어 있는데, 환경변수를 이용해서 서비스코드가 gihub에 공개되어도 실제 정보는 노출되지 않도록 할 수 있습니다.