Skip to content

Latest commit

 

History

History
137 lines (105 loc) · 11.2 KB

File metadata and controls

137 lines (105 loc) · 11.2 KB

Spring을 통한 게시판 CRUD 만들어 보기

1. 기능 정의

1.회원 가입

  • username은 최소 4자 이상, 10자 이하이며 알파벳 소문자(a ~ z), 숫자(0 ~ 9)로 구성되어야 한다.
  • password는 최소 8자 이상, 15자 이하이며 알파벳 대소문자(a ~ z, A ~ Z), 숫자(0 ~ 9)로 구성되어야 한다
  • DB에 중복된 username이 없다면 회원을 저장하고 Client 로 성공했다는 메시지, 상태코드 반환하기

2.로그인

  • username, password를 Client에서 전달받기
  • DB에서 username을 사용하여 저장된 회원의 유무를 확인하고 있다면 password 비교하기
  • 로그인 성공 시, 로그인에 성공한 유저의 정보와 JWT를 활용하여 토큰을 발급하고, 발급한 토큰을 Header에 추가하고 성공했다는 메시지, 상태코드 와 함께 Client에 반환하기

3.전체 게시글 목록 조회

  • 제목, 작성자명(username), 작성 내용, 작성 날짜를 조회하기
  • 작성 날짜 기준 내림차순으로 정렬하기

4.게시글 작성

  • 토큰을 검사하여, 유효한 토큰일 경우에만 게시글 작성 가능
  • 제목, 작성자명(username), 작성 내용을 저장
  • 저장된 게시글을 Client 로 반환하기

5.선택한 게시글 조회

  • 선택한 게시글의 제목, 작성자명(username), 작성 날짜, 작성 내용을 조회하기 (검색 기능이 아닙니다. 간단한 게시글 조회만 구현해주세요.)

6.선택한 게시글 수정

  • 토큰을 검사한 후, 유효한 토큰이면서 해당 사용자가 작성한 게시글만 수정 가능
  • 제목, 작성 내용을 수정하고 수정된 게시글을 Client 로 반환하기

7.선택한 게시글 삭제

  • 토큰을 검사한 후, 유효한 토큰이면서 해당 사용자가 작성한 게시글만 삭제 가능
  • 선택한 게시글을 삭제하고 Client 로 성공했다는 메시지, 상태코드 반환하기

2. Use Case Diagram

UseCase

3. ERD

Board_Project_ERD

4. API명세서

1 2

5. ❓ Why : 질문과 답변

1. 수정, 삭제 API의 request를 어떤 방식으로 사용하셨나요? (param, query, body)

  • 수정 API에서는 id@PathVariable로 받으므로 param방식을 사용했고, 수정내용을 포함 하고 있는 **{title,content,username}**은 body를 사용했습니다.
  • 삭제 API에서는 id@PathVariable로 받으므로 param방식을 사용했습니다.

2. 어떤 상황에 어떤 방식의 request를 써야하나요?

  • param
    • 주소에 포함된 변수를 담는다
    • 데이터를 식별할때 적절하다.
      • ex) /api/board/1 : 1번 board를 가져온다
    • 서버에서 @PathVariable로 칭한다
  • query
    • 엔드포인트에서 물음표(?) 뒤에 key=value 형태로 변수를 담는다 ex) /api/board/?name="철수"&age=28 body
    • URL에 보이지 않는 오브젝트의 데이터들을 담는다.
    • 객체 자체를 바로 보낼때 적합하다

3. RESTful한 API를 설계했나요? 어떤 부분이 그런가요? 어떤 부분이 그렇지 않나요?

  • Resorce인 Borad를 중심으로 설계를 했고, URI만 보더라도 리소스를 추론할 수 있도록 설계했습니다.
  • 그렇지 않은 부분은 Dto를 Service에서 처리하는 로직에 있어서 Service는 데이터를 저장하는 테이블을 구성하는 역할을 하는데, 같은 클래스에서 Dto를 받아와서 생성자를 처리하는 부분까지 역할을 단일책임의 원칙에 어긋나지 않을까 하는 생각이 듭니다. 그래서 Dto를 받아서 처리하는 로직을 따로 빼서 다른 클래스로 만들었으면 어떨까 생각합니다.

4. 적절한 관심사 분리를 적용하였나요? (Controller, Repository, Service)

  • Controller
    • 클라이언트로부터의 요청을 URL에 맞게 Mapping을 통해서 Service로 전달 되도록 했습니다.
  • Service
    • Controller를 통해서 전달 받은 요청을 비즈니스 로직을 통해서 Repository에 전달 되도록 했습니다.
  • Repository
    • Service에서 전달 받은 비즈니스 로직을 통해서 DB에 접근해서 데이터를 처리하도록 했습니다.

5. API 명세서 작성 가이드라인을 검색하여 직접 작성한 API 명세서와 비교해보세요!

  • API 명세서 예시를 참고하여 {기능, Method, URL, Request, Response}로 구성을 하였습니다.

6. 처음 설계한 API 명세서에 변경사항이 있었나요? 변경 되었다면 어떤 점 때문 일까요? 첫 설계의 중요성에 대해 작성해 주세요!

  • 새로운 기능이 추가 되었거나, 기존의 기능에 변경사항이 생겨서 처음 설계한 API 명세서에 변경사항이 생겼습니다.
  • 첫 설계를 잘 해야지 협업할때 클래스명,변수명,메서드명, 타입 등등 에러를 줄일 수 있고 변경사항을 최소한으로 줄일 수 있다고 생각합니다.

7. ERD를 먼저 설계한 후 Entity를 개발했을 때 어떤 점이 도움이 되셨나요?

  • Entity간의 연관관계를 고려하면서 개발 할 수 있었던 점이 좋았습니다.

8. JWT를 사용하여 인증/인가를 구현 했을 때의 장점은 무엇일까요?

  • JWT 의 주요한 이점은 사용자 인증에 필요한 모든 정보는 토큰 자체에 포함하기 때문에 별도의 인증 저장소가 필요 없습니다
  • 쿠키를 전달하지 않아도 되므로 쿠키를 사용함으로써 발생하는 취약점이 사라집니다
  • URL 파라미터와 헤더로 사용
  • 트래픽 대한 부담이 낮음
  • REST 서비스로 제공 가능
  • 내장된 만료
  • 독립적인 JWT

9. 반대로 JWT를 사용한 인증/인가의 한계점은 무엇일까요?

  • Self-contained: 토큰 자체에 정보를 담고 있으므로 양날의 검이 될 수 있습니다.
  • 토큰 길이: 토큰의 페이로드(Payload)에 3종류의 클레임을 저장하기 때문에, 정보가 많아질수록 토큰의 길이가 늘어나 네트워크에 부하를 줄 수 있습니다.
  • Payload 인코딩: 페이로드(Payload) 자체는 암호화 된 것이 아니라, BASE64로 인코딩 된 것입니다. 중간에 Payload를 탈취하여 디코딩하면 데이터를 볼 수 있으므로, JWE로 암호화하거나 Payload에 중요 데이터를 넣지 않아야 합니다.
  • Stateless: JWT는 상태를 저장하지 않기 때문에 한번 만들어지면 제어가 불가능합니다. 즉, 토큰을 임의로 삭제하는 것이 불가능하므로 토큰 만료 시간을 꼭 넣어주어야 합니다.
  • Tore Token: 토큰은 클라이언트 측에서 관리해야 하기 때문에, 토큰을 저장해야 합니다.

10. 만약 댓글 기능이 있는 블로그에서 댓글이 달려있는 게시글을 삭제하려고 한다면 무슨 문제가 발생할까요? Database 테이블 관점에서 해결방법이 무엇일까요?

  • 댓글과 게시판이 다대일 연관관계를 가지고 있으며, 댓글이 FK의 주인이다. 게시판은 읽기 밖에 할 수 없고, 게시판을 삭제 하려고 해도 댓글 입장에서는 그 사실을 알지 못하기 때문에 삭제가 되지 않는다. 해결방법은 DB 테이블 관점에서 생각해보면 게시판과 댓글 양쪽 모두에서 삭제를 해줘야

11. IoC / DI 에 대해 간략하게 설명해 주세요!

  • DI(Dependency Injection)란 스프링이 다른 프레임워크와 차별화되어 제공하는 의존 관계 주입 기능으로, 객체를 직접 생성하는 게 아니라 외부에서 생성한 후 주입 시켜주는 방식이다. DI(의존성 주입)를 통해서 모듈 간의 결합도가 낮아지고 유연성이 높아진다.
  • IoC(Inversion of Control)란 "제어의 역전" 이라는 의미로, 말 그대로 메소드나 객체의 호출작업을 개발자가 결정하는 것이 아니라, 외부에서 결정되는 것을 의미한다. 객체의 의존성을 역전시켜 객체 간의 결합도를 줄이고 유연한 코드를 작성할 수 있게 하여 가독성 및 코드 중복, 유지 보수를 편하게 할 수 있게 한다.

12. Spring Security를 적용했을 때 어떤 점이 도움이 되셨나요?

  • service로직에서 사용자 요청이 있을 시 매번 토큰 검사 및 인증을 하지 않아도 되서 중복코드도 없어지고 편리하기도 했습니다.

13. IoC / DI 에 대해 간략하게 설명해 주세요! - 숙련주차의 답변을 Upgrade 해 주세요!

  • DI(Dependency Injection)란 스프링이 다른 프레임워크와 차별화되어 제공하는 의존 관계 주입 기능으로, 객체를 직접 생성하는 게 아니라 외부에서 생성한 후 주입 시켜주는 방식입니다. 이로써 기존의 강한 결합 상태를 좀 더 유연하게 만들 수 있고 인터페이스를 통해서 의존 관계가 많아질수록 코드의 재활용성도 높일 수 있다
  • IoC(Inversion of Control)란 "제어의 역전" 이라는 의미로, 말 그대로 메소드나 객체의 호출작업을 개발자가 결정하는 것이 아니라, 외부에서 결정되는 것을 의미한다. 객체의 의존성을 역전시켜 객체 간의 결합도를 줄이고 유연한 코드를 작성할 수 있게 하여 가독성 및 코드 중복, 유지 보수를 편하게 할 수 있게 한다.

14. JWT를 사용하여 인증/인가를 구현 했을 때의 장점은 무엇일까요? - 숙련주차의 답변을 Upgrade 해 주세요!

  • 매번 사용자의 요청이 있을때마다 서버로부터 사용자의 인증/인가를 매번 해줄 필요 없이 첫 로그인 때 발급 받은 JWT토큰을 통해서 같은 유저라는걸 알려줌으로써 반복 작업을 줄여 줄 수 있고, 정보를 주고 받기에도 편리합니다.

15. 반대로 JWT를 사용한 인증/인가의 한계점은 무엇일까요? - 숙련주차의 답변을 Upgrade 해 주세요!

  • Self-contained: 토큰 자체에 정보를 담고 있으므로 양날의 검이 될 수 있습니다.
  • 토큰 길이: 토큰의 페이로드(Payload)에 3종류의 클레임을 저장하기 때문에, 정보가 많아질수록 토큰의 길이가 늘어나 네트워크에 부하를 줄 수 있습니다.
  • Payload 인코딩: 페이로드(Payload) 자체는 암호화 된 것이 아니라, BASE64로 인코딩 된 것입니다. 중간에 Payload를 탈취하여 디코딩하면 데이터를 볼 수 있으므로, JWE로 암호화하거나 Payload에 중요 데이터를 넣지 않아야 합니다.
  • Stateless: JWT는 상태를 저장하지 않기 때문에 한번 만들어지면 제어가 불가능합니다. 즉, 토큰을 임의로 삭제하는 것이 불가능하므로 토큰 만료 시간을 꼭 넣어주어야 합니다.
  • Tore Token: 토큰은 클라이언트 측에서 관리해야 하기 때문에, 토큰을 저장해야 합니다.