Skip to content
Open
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
bc460cb
feat: ErrorCode 구현
kih1015 Jun 2, 2024
6523f0f
feat: ArticleErrorCode 구현
kih1015 Jun 2, 2024
8f46c93
feat: BoardErrorCode 구현
kih1015 Jun 2, 2024
0f8680a
feat: MemberErrorCode 구현
kih1015 Jun 2, 2024
3672b07
feat: CommonErrorCode 구현
kih1015 Jun 2, 2024
30ec81a
refactor: exception.error 패키지로 이동
kih1015 Jun 2, 2024
14da25c
feat: RestApiException 구현
kih1015 Jun 2, 2024
7bdf905
feat: ErrorResponse 구현
kih1015 Jun 2, 2024
167fd5c
feat: GlobalExceptionHandler 구현
kih1015 Jun 2, 2024
4e57ccf
refactor: handleCustomException 메서드 분리
kih1015 Jun 2, 2024
100b4df
feat: handleEmptyResultException 구현
kih1015 Jun 2, 2024
4e257c0
feat: from 메서드 구현
kih1015 Jun 2, 2024
8b32f21
feat: getArticles 메서드 구현
kih1015 Jun 2, 2024
b050442
feat: 조회 예외처리 controller 구현
kih1015 Jun 2, 2024
ef348a1
feat: 사용자 수정 예외처리 구현
kih1015 Jun 2, 2024
43e903e
feat: 게시물 수정 예외처리 구현
kih1015 Jun 2, 2024
78042a1
feat: 공통 생성 예외처리 구현
kih1015 Jun 2, 2024
bfaca10
feat: 게시물 생성 예외처리 구현
kih1015 Jun 2, 2024
9169d55
feat: 사용자 삭제 예외처리 구현
kih1015 Jun 2, 2024
dfe6627
feat: 게시판 삭제 예외처리 구현
kih1015 Jun 2, 2024
0dbe606
style: import 최적회
kih1015 Jun 2, 2024
b60661c
style: 들여쓰기 정리
kih1015 Jun 6, 2024
aaec70e
refactor: 공통 mapping 추가
kih1015 Jun 6, 2024
efc13e2
style: 논리식 조건문 삽입
kih1015 Jun 6, 2024
47d00c7
fix: 오류 수정
kih1015 Jun 21, 2024
e74feed
feat: JPA 의존성 추가
kih1015 Jun 25, 2024
7f76725
refactor: refactor Article to Entity
kih1015 Jun 25, 2024
a7b41c3
refactor: refactor Board to Entity
kih1015 Jun 25, 2024
bbf44c6
refactor: refactor member to Entity
kih1015 Jun 25, 2024
28ff372
refactor: refactor ArticleRepository impl
kih1015 Jun 25, 2024
fe2be17
refactor: refactor BoardRepository impl
kih1015 Jun 25, 2024
4b2ad7f
refactor: refactor MemberRepository impl
kih1015 Jun 25, 2024
2384531
refactor: refactor update methods
kih1015 Jun 25, 2024
807ac1a
refactor: alter ArticleRepository to Spring Data JPA
kih1015 Jul 2, 2024
b468327
refactor: alter BoardRepository to Spring Data JPA
kih1015 Jul 2, 2024
93acc08
refactor: alter MemberRepository to Spring Data JPA
kih1015 Jul 2, 2024
b5abb8a
refactor: refactor ArticleService
kih1015 Jul 2, 2024
a145eab
refactor: refactor BoardService
kih1015 Jul 2, 2024
9e5b1cf
refactor: refactor MemberService
kih1015 Jul 2, 2024
c7aa9de
refactor: makes Article have many-to-one mapping
kih1015 Jul 2, 2024
966fbac
refactor: makes Board have one-to-many mapping
kih1015 Jul 2, 2024
0d35924
refactor: makes member have one-to-many mapping
kih1015 Jul 2, 2024
f3405c6
refactor: alter to lazy fetch
kih1015 Jul 2, 2024
c2ba88a
refactor: modify create, update logic in ArticleService
kih1015 Jul 2, 2024
93c1057
feat: add articles getter
kih1015 Jul 2, 2024
9b5c19e
feat: 양방향 연관관계 적용하도록 변경
kih1015 Jul 2, 2024
7600bd2
style: 필드간 개행
kih1015 Jul 6, 2024
5c65b1c
feat: add dependencies
kih1015 Jul 9, 2024
adbb0c0
feat: add POST /members/login and /members/join
kih1015 Jul 9, 2024
21f7c37
feat: add AuthenticationConfig
kih1015 Jul 9, 2024
98c649a
feat: add dependency
kih1015 Jul 9, 2024
f0228e9
feat: add JwtUtil
kih1015 Jul 9, 2024
7ab68c1
feat: add login method
kih1015 Jul 9, 2024
e33138e
feat: add dependency
kih1015 Jul 9, 2024
164a7c7
feat: add JwtFilter class
kih1015 Jul 9, 2024
f16ec8c
feat: 회원가입 시 이메일 중복 방지 기능 추가
kih1015 Jul 9, 2024
4c30465
feat: 이메일로 검색 기능 추가
kih1015 Jul 9, 2024
756e6eb
feat: EncoderConfig 추가
kih1015 Jul 9, 2024
82c04a8
feat: 이메일 존재하지 않음, 패스워드 불일치 에러 추가
kih1015 Jul 9, 2024
9efdca4
feat: 로그인 dto 추가
kih1015 Jul 9, 2024
384823e
feat: login 메서드 추가
kih1015 Jul 9, 2024
2947fbc
feat: get 요청을 허용하도록 변경
kih1015 Jul 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 47 additions & 21 deletions src/main/java/com/example/demo/controller/ArticleController.java
Original file line number Diff line number Diff line change
@@ -1,68 +1,94 @@
package com.example.demo.controller;

import java.net.URI;
import java.util.List;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.example.demo.controller.dto.request.ArticleCreateRequest;
import com.example.demo.controller.dto.response.ArticleResponse;
import com.example.demo.controller.dto.request.ArticleUpdateRequest;
import com.example.demo.controller.dto.response.ArticleResponse;
import com.example.demo.exception.RestApiException;
import com.example.demo.exception.error.ArticleErrorCode;
import com.example.demo.exception.error.CommonErrorCode;
import com.example.demo.service.ArticleService;
import com.example.demo.service.BoardService;
import com.example.demo.service.MemberService;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.net.URI;
import java.util.List;

@RestController

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

지금 공통적으로 "/articles"가 있는데 @RequestMapping("/articles") 를 해놓으면 해당하는 클래스에 공통적으로 적용돼서 뺄수 있습니다!

public class ArticleController {

private final ArticleService articleService;
private final MemberService memberService;
private final BoardService boardService;

public ArticleController(ArticleService articleService) {
public ArticleController(ArticleService articleService, MemberService memberService, BoardService boardService) {
this.articleService = articleService;
this.memberService = memberService;
this.boardService = boardService;
}

@GetMapping("/articles")
public ResponseEntity<List<ArticleResponse>> getArticles(
@RequestParam Long boardId
@RequestParam Long boardId

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tab이 한번 더 된것 같아요
ctrl + alt + L 하면 라인정리 깔끔하게 해주니까 참고하세용
맥이면 command + option + L입니다

) {
List<ArticleResponse> response = articleService.getByBoardId(boardId);
return ResponseEntity.ok(response);
}

@GetMapping("/articles/{id}")
public ResponseEntity<ArticleResponse> getArticle(
@PathVariable Long id
@PathVariable Long id
) {
if (articleService.getArticles()
.stream()
.noneMatch(res -> res.id().equals(id))) {
throw new RestApiException(CommonErrorCode.RESOURCE_NOT_FOUND);
}
ArticleResponse response = articleService.getById(id);
return ResponseEntity.ok(response);
}

@PostMapping("/articles")
public ResponseEntity<ArticleResponse> crateArticle(
@RequestBody ArticleCreateRequest request
@RequestBody ArticleCreateRequest request
) {
boolean isNullExistence = request.boardId() == null
|| request.authorId() == null
|| request.title() == null
|| request.description() == null;
if (isNullExistence) {
throw new RestApiException(CommonErrorCode.NULL_PARAMETER);
}
if (boardService.getBoards()
.stream()
.noneMatch(res -> res.id().equals(request.boardId()))
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이렇게 메소드 체이닝으로 길어진 구문은 보통 한줄로 적는지, 메서드 마다 들여쓰기를 하는지 궁금합니다!

|| memberService.getAll()
.stream()
.noneMatch(res -> res.id().equals(request.authorId()))) {
throw new RestApiException(ArticleErrorCode.REFERENCE_ERROR);
}
ArticleResponse response = articleService.create(request);
return ResponseEntity.created(URI.create("/articles/" + response.id())).body(response);
}

@PutMapping("/articles/{id}")
public ResponseEntity<ArticleResponse> updateArticle(
@PathVariable Long id,
@RequestBody ArticleUpdateRequest request
@PathVariable Long id,
@RequestBody ArticleUpdateRequest request
) {
if (boardService.getBoards()
.stream()
.noneMatch(res -> res.id().equals(request.boardId()))) {
throw new RestApiException(ArticleErrorCode.REFERENCE_ERROR);
}
ArticleResponse response = articleService.update(id, request);
return ResponseEntity.ok(response);
}

@DeleteMapping("/articles/{id}")
public ResponseEntity<Void> updateArticle(
@PathVariable Long id
@PathVariable Long id
) {
articleService.delete(id);
return ResponseEntity.noContent().build();
Expand Down
34 changes: 22 additions & 12 deletions src/main/java/com/example/demo/controller/BoardController.java
Original file line number Diff line number Diff line change
@@ -1,28 +1,27 @@
package com.example.demo.controller;

import java.util.List;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import com.example.demo.controller.dto.request.BoardCreateRequest;
import com.example.demo.controller.dto.request.BoardUpdateRequest;
import com.example.demo.controller.dto.response.BoardResponse;
import com.example.demo.exception.RestApiException;
import com.example.demo.exception.error.BoardErrorCode;
import com.example.demo.exception.error.CommonErrorCode;
import com.example.demo.service.ArticleService;
import com.example.demo.service.BoardService;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
public class BoardController {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기도 @RequestMapping 적용해보세요!


private final BoardService boardService;
private final ArticleService articleService;

public BoardController(BoardService boardService) {
public BoardController(BoardService boardService, ArticleService articleService) {
this.boardService = boardService;
this.articleService = articleService;
}

@GetMapping("/boards")
Expand All @@ -34,13 +33,19 @@ public List<BoardResponse> getBoards() {
public BoardResponse getBoard(
@PathVariable Long id
) {
if (boardService.getBoards().stream().noneMatch(res -> res.id().equals(id))) {
throw new RestApiException(CommonErrorCode.RESOURCE_NOT_FOUND);
}
return boardService.getBoardById(id);
}

@PostMapping("/boards")
public BoardResponse createBoard(
@RequestBody BoardCreateRequest request
) {
if (request.name() == null) {
throw new RestApiException(CommonErrorCode.NULL_PARAMETER);
}
return boardService.createBoard(request);
}

Expand All @@ -56,6 +61,11 @@ public BoardResponse updateBoard(
public ResponseEntity<Void> deleteBoard(
@PathVariable Long id
) {
if (articleService.getArticles()
.stream()
.anyMatch(res -> res.boardId().equals(id))) {
throw new RestApiException(BoardErrorCode.ARTICLE_EXISTENCE);
}
boardService.deleteBoard(id);
return ResponseEntity.noContent().build();
}
Expand Down
53 changes: 36 additions & 17 deletions src/main/java/com/example/demo/controller/MemberController.java
Original file line number Diff line number Diff line change
@@ -1,28 +1,27 @@
package com.example.demo.controller;

import java.util.List;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import com.example.demo.controller.dto.request.MemberCreateRequest;
import com.example.demo.controller.dto.request.MemberUpdateRequest;
import com.example.demo.controller.dto.response.MemberResponse;
import com.example.demo.exception.RestApiException;
import com.example.demo.exception.error.CommonErrorCode;
import com.example.demo.exception.error.MemberErrorCode;
import com.example.demo.service.ArticleService;
import com.example.demo.service.MemberService;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
public class MemberController {

private final MemberService memberService;
private final ArticleService articleService;

public MemberController(MemberService memberService) {
public MemberController(MemberService memberService, ArticleService articleService) {
this.memberService = memberService;
this.articleService = articleService;
}

@GetMapping("/members")
Expand All @@ -33,33 +32,53 @@ public ResponseEntity<List<MemberResponse>> getMembers() {

@GetMapping("/members/{id}")
public ResponseEntity<MemberResponse> getMember(
@PathVariable Long id
@PathVariable Long id
) {
if (memberService.getAll().stream().noneMatch(res -> res.id().equals(id))) {
throw new RestApiException(CommonErrorCode.RESOURCE_NOT_FOUND);
}
MemberResponse response = memberService.getById(id);
return ResponseEntity.ok(response);
}

@PostMapping("/members")
public ResponseEntity<MemberResponse> create(
@RequestBody MemberCreateRequest request
@RequestBody MemberCreateRequest request
) {
boolean isNullExistence = request.name() == null
|| request.email() == null
|| request.password() == null;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이걸 바로 조건문 안에 넣어도 괜찮을 것 같아요

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

그동안 일정이 바빴어서 지금 확인했습니다 ㅠ

피드백 주신 사항 전부 커밋해봤습니다!

if (isNullExistence) {
throw new RestApiException(CommonErrorCode.NULL_PARAMETER);
}
MemberResponse response = memberService.create(request);
return ResponseEntity.ok(response);
}

@PutMapping("/members/{id}")
public ResponseEntity<MemberResponse> updateMember(
@PathVariable Long id,
@RequestBody MemberUpdateRequest request
@PathVariable Long id,
@RequestBody MemberUpdateRequest request
) {
if (memberService.getAll()
.stream()
.filter(res -> !res.id().equals(id))
.anyMatch(res -> res.email().equals(request.email()))) {
throw new RestApiException(MemberErrorCode.EMAIL_CONFLICT);
}
MemberResponse response = memberService.update(id, request);
return ResponseEntity.ok(response);
}

@DeleteMapping("/members/{id}")
public ResponseEntity<Void> deleteMember(
@PathVariable Long id
@PathVariable Long id
) {
if (articleService.getArticles()
.stream()
.anyMatch(res -> res.authorId().equals(id))) {
throw new RestApiException(MemberErrorCode.ARTICLE_EXISTENCE);
}
memberService.delete(id);
return ResponseEntity.noContent().build();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package com.example.demo.controller.dto.response;

import java.time.LocalDateTime;

import com.example.demo.domain.Article;
import com.example.demo.domain.Board;
import com.example.demo.domain.Member;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.PropertyNamingStrategies.SnakeCaseStrategy;
import com.fasterxml.jackson.databind.annotation.JsonNaming;

import java.time.LocalDateTime;

@JsonNaming(SnakeCaseStrategy.class)
public record ArticleResponse(
Long id,
Expand All @@ -35,4 +35,16 @@ public static ArticleResponse of(Article article, Member member, Board board) {
article.getModifiedAt()
);
}

public static ArticleResponse from(Article article) {
return new ArticleResponse(
article.getId(),
article.getAuthorId(),
article.getBoardId(),
article.getTitle(),
article.getContent(),
article.getCreatedAt(),
article.getModifiedAt()
);
}
}
4 changes: 4 additions & 0 deletions src/main/java/com/example/demo/exception/ErrorResponse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.example.demo.exception;

public record ErrorResponse(String status, String message) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.example.demo.exception;

import com.example.demo.exception.error.ErrorCode;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

@RestControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {

@ExceptionHandler(RestApiException.class)
public ResponseEntity<ErrorResponse> handleCustomException(RestApiException e) {
ErrorCode errorCode = e.getErrorCode();
return handleExceptionInternal(errorCode);
}

private ErrorResponse makeErrorResponse(ErrorCode errorCode) {
return new ErrorResponse(errorCode.getHttpStatus().toString(), errorCode.getMessage());
}

private ResponseEntity<ErrorResponse> handleExceptionInternal(ErrorCode errorCode) {
ErrorResponse rsp = makeErrorResponse(errorCode);
return ResponseEntity.status(errorCode.getHttpStatus()).body(rsp);
}

}
17 changes: 17 additions & 0 deletions src/main/java/com/example/demo/exception/RestApiException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.example.demo.exception;

import com.example.demo.exception.error.ErrorCode;

public class RestApiException extends RuntimeException{

private final ErrorCode errorCode;

public RestApiException(ErrorCode errorCode) {
this.errorCode = errorCode;
}

public ErrorCode getErrorCode() {
return errorCode;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.example.demo.exception.error;

import org.springframework.http.HttpStatus;

public enum ArticleErrorCode implements ErrorCode{

REFERENCE_ERROR(HttpStatus.BAD_REQUEST, "존재하지 않는 사용자 또는 게시판입니다.");

private final HttpStatus httpStatus;
private final String message;

ArticleErrorCode(HttpStatus httpStatus, String message) {
this.httpStatus = httpStatus;
this.message = message;
}

@Override
public HttpStatus getHttpStatus() {
return httpStatus;
}

@Override
public String getMessage() {
return message;
}

}
Loading