[TIL] 2022.11.29

rara_kim·2022년 11월 29일
0

TIL

목록 보기
20/25

어제부터 오늘까지

이번주 목요일까지 제출해야하는 개인과제를 드디어 끝마쳤다!
사실 후다닥 과제를 끝내놓고 좀 여유있게 언어스터디 예복습도 하고 외부 강의도 들을 생각이었는데, 생각보다 과제가 오래 걸렸다.

어제 저녁8시 부터 시작해서 코드를 몇번 갈아 엎고 테스트에 실패하고 머리를 쥐어 뜯다가 완성했다😂
요구사항도 그렇게 많지 않았지만 REST API나 ResponseDto 사용이나 구현외에도 공부할 게 정말 많았다.

이번에 수강한 CRUD 강의와 전에 진행했던 프로젝트의 코드를 참고하며 코드를 작성했고 어플리케이션 실행까지는 문제없었는데 Postman을 이용한 테스트에서 첫번째 에러가 발생했다.
Request를 날리는 URL도 틀리지 않았고 넣어주어야 할 Body도 JSON 형식으로 입력했음에도 왜인지 계속해서 404: Not Found가 리턴되었다.
일단 코드를 전체적으로 훑어보았지만 Request도 Response도 문제가 없어 더 패닉에 빠졌다.
이래저래 고민하다가 조금 무식한 방법이지만, Entity 클래스부터 코드를 첫줄부터 천천히 읽어보기로 했다.
그렇게 찬찬히 읽어보는데 역시나 내 코드에 문제가 있었다. Controller 클래스에 @RestController가 아니라 @Controller를 붙여줬었던 것이다...
바로 RestController 어노테이션을 붙여주니 Postman에서 Request도 문제없이 보내졌고 에러없이 Response도 리턴되었다.

그런데!! 이번엔 Response가 문제였다.
JSON 형식으로 반환은 잘 되고 있으나 아래의 Timestamped 클래스를 상속받았으니 당연하게도 들어가야 하는 필드값이 null로 반환되고 있었다.

@Getter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public class Timestamped {

	@CreatedDate
	private LocalDateTime createdAt;

	@LastModifiedDate
	private LocalDateTime modifiedAt;
}

그렇게 또 뭐가 문제인지 알아보기 시작했는데, 이번에는 그래도 비교적 빨리 원인을 찾아냈다.
@EntityListeners(AuditingEntityListener.class) 이 어노테이션을 보고 혹시? 싶어서 Application 클래스를 보니 아니나 다를까 @EnableJpaAuditing 어노테이션을 추가해주지 않은 채였다.

이렇게 문제인 부분들을 고치고 나니 드디어! 원인찾기 약1시간만에 문제없이 작동하기 시작했다.
Postman으로 Request를 날렸을 때, 문제없이 제대로 된 값이 반환되었을 때의 그 기쁨이란...🥹

그렇게 과제를 해결하고 어노테이션, REST Api에 대해 찾아보고 개념들을 정리해보았다.
프로젝트를 진행하며 시행착오를 겪고 그 이후에 개념을 정리하니 그냥 공부하는 것 보다도 훨씬 이해가 잘 되는 느낌!

💡기억해두기!

@Controller와 @RestController의 차이점

@Controller

  • API와 view를 동시에 사용하는 경우에 사용한다.
  • 대신 API 서비스로 사용하는 경우는 @ResponseBody를 사용하여 객체를 반환한다.
  • view return이 주목적이다.

@RestController

  • view가 필요없는 API만 지원하는 서비스에서 사용한다.
  • @RequestMapping 메서드가 기본적으로 @ResponseBody 의미를 가정한다.
  • data return이 주목적이다.

즉, @RestController   =   @Controller +   @ResponseBody


@EnableJpaAuditing

Spring Data JPA에서 시간에 대해서 자동으로 값을 넣어주는 기능이다.
Entity를 영속성 컨텍스트에 저장하거나 조회를 수행한 후에 update를 하는 경우 매번 시간 데이터를 입력하여 주어야 하는데, audit을 이용하면 자동으로 시간을 매핑하여 데이터베이스의 테이블에 넣어준다.

Entity 클래스가 Timestamped 클래스를 상속하면 JPA가 생성일자, 수정일자 컬럼을 인식하게 된다.

@Getter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public class Timestamped {

	@CreatedDate
	private LocalDateTime createdAt;

	@LastModifiedDate
	private LocalDateTime modifiedAt;
}

💡SpringBoot의 실행 클래스에 @EnableJpaAuditing 어노테이션을 적용해주어야 JpaAuditing 기능이 활성화 된다.


Path Variable vs Query Parameter

Path Variable

  • Path Variable 는 이름에서도 알 수 있듯이 경로를 변수로서 사용한다.
  • 게시물이 존재하며 각각의 게시물을 볼 수 있는 경우를 생각해보면, 각각의 게시물을 보기 위해서는 게시물의 id를 서버에 넘겨줘야 한다.
/api/posts/6  

Query Parameter

  • Query Parameter 은 경로 뒤에 입력 데이터를 함께 제공하는 식으로 사용한다.
  • 이 때 ? 이후의 부분을 query string이라고 하며 뒤는 key, value의 쌍으로 이루어진다.
api/posts?id=6&key=value1

어느 상황에 어떤 방식을 써야할까?

서버에서는 어느 방식으로 넘어오던지 간에 받아온 resource의 id로 쿼리를 날리게 된다.
그런데 만약 존재하지 않은 resource의 id가 들어올 경우 각각 어떻게 동작할까?
우선 Path Variable은 저 경로의 존재하는 페이지가 없으므로 404 에러가 발생한다.

그에 비해 Query Parameter는 서버로 데이터가 넘어가고 쿼리를 날리며 해당하는 데이터가 없을 경우 따로 에러 핸들링을 해줘야한다.
즉, resource를 식별해야하는 상황에서는 Path Variable 가 더 적합하다.

posts/1
posts?category=java

id가 1인 관련 글이 없을 경우 Path Variable은 404에러를 발생하고, Query Parameter는 category가 jav인 리스트를 가져와야하는데 없는 경우에는 빈 리스트를 반환할 것이다.

필터링을 하다가 404에러가 발생하는 것은 부적절하므로, 정렬이나 필터링을 해야하는 상황에서는 Query Parameter가 더 적합하다.

profile
느리더라도 꾸준하게

0개의 댓글