Spring 입문 주차 8.12(금) ~ 8.18(목)
1. 개인 과제: 게시판 CRUD 기능을 하는 백엔드 서버 만들기, AWS 배포 2. 팀 과제: Spring 핵심 키워드 정리(필수 4개, 선택 4개) |
진행 계획
- 12일(금) Spring 핵심 키워드 정리
- 13일(토) Spring 핵심 키워드 정리
- 14일(일) 개인과제에 필요한 강의 수강 및 공부
- 15일(월) API 명세서 작성, Use Case 그리기
- 16일(화) 게시판 CRUD 기능 코드 작성
- 17일(수) 게시판 CRUD 기능 코드 작성
- 18일(목) 게시판 CRUD 기능 코드 작성 및 AWS 배포
1. 개인 과제 진행 상황
1) 게시글 수정 및 삭제 기능 구현
- PostController 수정
@RequiredArgsConstructor // final로 선언된 멤버 변수 자동 생성
@RestController // JSON으로 응답 반환
public class PostController {
private final PostRepository postRepository; // postRepository를 멤버 변수로 하고, 필수로 필요하니까 final
// 전체 게시글 목록 조회
@GetMapping("/api/posts") // /api/posts Get요청
public List<Post> getPost() { // Post에 List를 반환하는 getPost()메소드를 실행해라
return postRepository.findAll(); //postRepository에서 findAll해서 전부 찾아 반환
}
// 게시글 작성
@PostMapping("/api/posts") // /api/posts Post요청, PostMapping으로 같은 주소라도 방식이 다름을 구분
public Post createPost(@RequestBody PostRequestDto requestDto) { // RequestBody: 요청 받는 형태
Post post = new Post(requestDto); // 저장은 Dto가 아니라 Post, Dto의 정보를 post에 담아야 합니다.
return postRepository.save(post); // JPA를 이용하여 DB에 저장하고, 그 결과를 반환합니다.
}
// 게시글 조회
@GetMapping("/api/posts/{id}") // /api/posts/{id} Get요청
public Post getPost(@PathVariable Long id)
return postService.getPost(id)
// 게시글 수정
@PutMapping("/api/posts/{id}") // 이 주소로 수정 요청이 오면 updatePost메소드 실행해라, "{변수명}"은 값이 유동적일 때 사용
public Long updatePost(@PathVariable Long id, @RequestBody PostRequestDto requestDto) { // @PathVariable는 위 "{중괄호}" 유동적 값
return courseService.update(id, requestDto);
}
// 게시글 삭제
@DeleteMapping("/api/posts/{id}") //이 주소로 삭제 요청이오면 deletePost메소드 실행
public Long deletePost(@PathVariable Long id) {
postRepository.deleteById(id);
return id;
}
// 게시글 비밀번호 확인
@PostMapping("/api/posts/{id}")
public ResponseDto<?> validateAuthorByPassword(@PathVariable Long id, @RequestBody String password) {
return postService.validateAuthorByPassword(id, password);
}
}
- 응답 데이터를 전달할 Dto 생성: ResponseDto
@Getter
@AllArgsConstructor
public class ResponseDto<T> {
private boolean success;
private T data;
private Error error;
public static <T> ResponseDto<T> success(T data) {
return new ResponseDto<>(true, data, null);
}
public static <T> ResponseDto<T> fail(String code, String message) {
return new ResponseDto<>(false, null, new Error(code, message));
}
@Getter
@AllArgsConstructor
static class Error {
private String code;
private String message;
}
}
- 실제 비즈니스 로직이 실행되는 서비스 생성: PostService
@Service // 스프링에게 이 클래스는 서비스임을 명시
public class PostService {
// final: 서비스에게 꼭 필요한 녀석임을 명시(final은 한번 값이 부여되면 변경 불가)
private final CourseRepository courseRepository;
// 생성자를 통해, Service 클래스를 만들 때 꼭 Repository를 넣어주도록 스프링에게 알려줌
// 클래스에 @RequiredArgsConstructor을 쓰면 생략 가능
public CourseService(CourseRepository courseRepository) {
this.courseRepository = courseRepository;
}
@Transactional // SQL 쿼리가 일어나야 함을 스프링에게 알려줌
public Long update(Long id, Post post) {
Post post = postRepository.findById(id).orElseThrow(
() -> new IllegalArgumentException("해당 아이디가 존재하지 않습니다.")
);
post.update(post);
return post.getId();
}
// 비밀번호 확인
@Transactional(readOnly = true)
public Long validateAuthorByPassword(Long id, String password) {
Optional<Post> optionalPost = postRepository.findById(id);
if (optionalPost.isEmpty()) {
return ResponseDto.fail("NOT_FOUND", "post id is not exist");
}
Post post = optionalPost.get();
if (!post.getPassword().equals(password)) {
return ResponseDto.fail("PASSWORD_NOT_CORRECT", "password is not correct");
}
return post.getId();
}
}
2) 개인 과제 코드 관련 질문과 답변
- 수정, 삭제 API의 request를 어떤 방식으로 사용하셨나요? (param, query, body)
👉🏻 수정의 게시글 id값은 @PathVariable, 수정 할 내용은 @RequestBody를 이용해서 받음
👉🏻 삭제 할 게시글 id를 @PathVariable를 이용해서 받음
- 어떤 상황에 어떤 방식의 request를 써야하나요?
👉🏻 param: id값을 받아서 id값에 관한 기능을 구현하기 위해서 사용
👉🏻 query: 검색, 정렬을 해야 하는 경우 사용
👉🏻 body: 데이터가 많거나, 인수가 길 때, urI에 노출하면 안되는 정보일 경우 사용
- RESTful한 API를 설계했나요? 어떤 부분이 그런가요? 어떤 부분이 그렇지 않나요?
👉🏻 요청하는 URI를 보면 직관적으로 어떤 기능에 대한 로직을 처리 할 지 예상 가능하고, 같은 URI이지만 메소드(GET, POST, PUT, DELETE)에 따라 어떤 다른 기능을 함
- 적절한 관심사 분리를 적용하였나요? (Controller, Repository, Service)
👉🏻 컨트롤러에서 처리할 수 있는 로직은 바로 컨트롤러에서 처리하고, 수정이나 조회가 필요한 부분은 서비스에서 기능이 구현되도록 하였음, 데이터는 리포지토리에서 관리되도록 함, 하지만 컨트롤러는 창구 역할을 하기 때문에 서비스에 구현했어도 좋았을 것 같다.
- 작성한 코드에서 빈(Bean)을 모두 찾아보세요!
👉🏻 @Controller, @Service, @Repository 어노테이션을 달고 있는 것은 모두 @Component를 상속받기 때문에 빈으로 등록된다.
- API 명세서 작성 가이드라인을 검색하여 직접 작성한 명세서와 비교해보세요!
👉🏻 URI 설계 시 주의사항
1) 슬래시 구분자(/)는 계층 관계를 나타내는데 이용한다.
2) URI 마지막 문자 뒤에 슬래시 구분자(/)를 포함하지 않는다.
3) URI 경로에는 대문자보다 소문자를 사용하여 나타낸다.
4) 파일 확장자의 구호를 포함하지 않는다.
2. 개발 중 발생한 이슈와 해결
- ARC URL연결 문제
The requested URL can’t provide a secure connection The URL sent an invalid response.
Learn more about this problem. net::ERR_SSL_PROTOCOL_ERROR
해결방법: URL https://localhost8080/api/courses에서 http로 변경해서 연결
3. 새로 배운 것
ARC(Advanced REST Client): API를 만들고 나서 테스트 및 기능 확인하는 툴 종류 중 하나
4. 오늘 한 일 / 회고
- 개인 과제: 게시글 수정, 삭제 기능 구현, 비밀번호 조회 기능 구현
5. TO-DO LIST
- 개인 과제: 테스트 코드 구현
- AWS 배포 완료
- Spring 입문 주차 과제 제출 완료
'개발 일지' 카테고리의 다른 글
[TIL]이노베이션 캠프 19일차 (0) | 2022.08.19 |
---|---|
[TIL]이노베이션 캠프 18일차 (0) | 2022.08.18 |
[TIL]이노베이션 캠프 16일차 (0) | 2022.08.16 |
[TIL]이노베이션 캠프 15일차 (0) | 2022.08.15 |
[WIL]이노베이션 캠프 2주차 (0) | 2022.08.14 |