# 필수과제
1. 임베디드 톰캣의 쓰레드 풀 사이즈를 변경해보세요.
(성능 테스트 X)
2. 샘플 소스에서는 영화 검색 API를 사용했는데요. 응답 데이터 필드가 누락되었습니다. 데이터를 전부 가져올 수 있도록 필드를 추가해주세요.
3. 영화 되 다른 검색 서비스를 추가로 연동해보세요. 아무거나 하나만.. 자유롭게!!
4. 영화 검색 시 평점이 0인 데이터는 제외하는 기능을 개발해주세요.
5. API 디자인 지침이라는 글을 읽어주세요. 단, 전부 읽지는 마시고 "REST 소개, 리소스 중심으로 API 구성, HTTP 메서드를 기준으로 작업 정의"까지 읽어주셔도 됩니다.(사실 다 읽으면 좋음)
docs.microsoft.com/ko-kr/azure/architecture/best-practices/api-design
# 선택과제
1. 영화 평점 순 정렬에 대한 단위 테스트를 작성해주세요. 평점이 높은 순으로 정렬이 잘 되는지 검증하면 됩니다.
2.영화 검색시 평점이 0인 데이터를 제외하는 기능에 대해서 단위테스트를 작성해주세요.
(단위테스트는 @SpringBootTest 사용하지 않고 작성해보기)
참고 brunch.co.kr/@springboot/536
3.네이버 오픈 API의 인증이 실패한 경우에 대해서, 예외 처리 코드를 작성해주세요. 예외 발생시 커스텀하게 정의한 JSON 포맷으로 응답하도록 개선해주세요.
# 선택과제2(완전 선택...)
(1) RestTemplate 사용시
- 영화 검색 및 그외 다른 검색... 2개 이상의 검색 기능에 사용하는 로직에서, RestTemplate를 공통으로 사용하는 부분이 있다면, 중복코드가 없도록 리팩토링 해주세요.
- RestTemplate Bean 설정 컨피그 클래스에서 매직넘버로 설정한 셋팅 값들 전부 application.yml 파일로 속성 분리하기
(2) 그외 방법 - FeignClient를 사용하도록 변경해보기 or spring cloud openfeign을 사용해도 무방
#필수과제
1. 임베디드 톰캣의 쓰레드 풀 사이즈를 변경
숫자만 바꿔주면 된다.
4. 영화 검색 시 평점이 0인 데이터는 제외하는 기능을 개발해주세요.
public List<ResponseMovieClientDto> getListOrderRating(){
return list.stream()
.filter(b -> !((Float)b.getUserRating()).equals(0.0f)) //평점이 0인 데이터 제거
.sorted((a,b) -> a.getUserRating() > b.getUserRating() ? -1 : 1)
.collect(Collectors.toList());
}
stream()의 filter 이용
API로 영화 데이터를 모두 가져온 다음 MovieGroup.java에서 필터를 이용한 가공과정을 처리한 후 반환
5. API 디자인 지침이라는 글을 읽어주세요. 단, 전부 읽지는 마시고 "REST 소개, 리소스 중심으로 API 구성, HTTP 메서드를 기준으로 작업 정의"까지 읽어주셔도 됩니다.(사실 다 읽으면 좋음)
좋은 API의 특성
- 플랫폼 독립성
- 모든 클라이언트는 내부에서 API가 구현되는 방법에 관계없이 API를 호출할 수 있어야 합니다.
- 서비스 진화
- Web API는 클라이언트 애플리케이션과 독립적으로 기능을 진화시키고 추가할 수 있어야 합니다.
- API가 진화해도 기존 클라이언트 애플리케이션은 수정 없이 계속 작동할 수 있어야 합니다.
REST 소개
REST(Representational State Transfer)는 웹 서비스를 디자인 하는 아키텍처 접근 방식을 말합니다.
REST가 HTTP보다 우수한 주요 장점은 개방형 표준을 사용하므로 API 또는 클라이언트 애플리케이션의 구현이 특정 구현에 바인딩되지 않는다는 것입니다.
HTTP를 사용하는 RESTful API의 몇 가지 기본 디자인 원칙
- REST API는 리소스를 중심으로 디자인되며, 클라이언트에서 액세스할 수 있는 모든 종류의 개체, 데이터 또는 서비스가 리소스에 포함됩니다.
- 리소스마다 해당 리소스를 고유하게 식별하는 URI(식별자)가 있습니다. 예를 들어 특정 고객 주문의 URI는 다음과 같습니다.
https://adventure-works.com/orders/1
- 클라이언트가 리소스의 표현을 교환하여 서비스와 상호 작용합니다. 많은 Web API가 교환 방식으로 JSON을 사용합니다.
- REST API는 균일한 인터페이스를 사용하므로 클라이언트와 서비스 구현을 분리하는 데 도움이 됩니다. 가장 일반 적인 작업은 GET, POST, PUT, PATCH 및 DELETE 입니다.
리소스를 중심으로 API 구성
웹 API가 표시하는 비즈니스 엔티티에 집중해야 합니다. 예를 들어 전자 상거래 시스템에서는 기본 엔티티가 고객과 주문입니다. 가능하다면 리소스 URI는 동사(리소스에 대한 작업)이 아닌 명사(리소스)를 기반으로 해야 합니다.
https://adventure-works.com/orders // Good
https://adventure-works.com/create-order // Avoid
URI에 일관적인 명명 규칙을 적용하며, 복수 명사를 사용할 수 있습니다.
또한, URI를 계층 구조로 구성하는 것이 좋습니다. 예를 들어 /customers는 고객 컬렉션의 경로이고, /customers/5는 ID가 5인 고객의 경로입니다. 개발자는 /customers/{id}에 대한 경로를 정의할 수 있습니다.
서로다른 리소스 형식과 이러한 연결을 표시하는 방법 사이의 관계도 고려해야 합니다. 예를 들어 /customers/5/orders는 고객 5에 대한 모든 주문을 나타낼 수 있습니다. 반대 방향으로 이동하여 /orders/99/customer 같은 URI를 사용하여 주문에서 고객으로의 연결을 표시할 수 있습니다. 그러나 이러한 모델을 너무 많이 확장하면 구현이 어려울 수 있습니다.
좀더 복잡한 시스템에서는 /custorers/1/orders/99/products처럼 클라이언트가 여러 관계 수준을 탐색할 수 있는 URI를 제공하고 싶을 수 있습니다. 그러나 이 수준의 복잡성은 유지 하기 어려 울수 있으며 나중에 리소스 사이의 관계가 변하면 유연성이 떨어집니다.
이전 쿼리를 /custoers/1/orders URI로 바꿔서 고객1의 모든 주문을 찾은 후 /orders/99/products로 바꿔서 이 주문의 제품을 찾을 수 있습니다.
HTTP 메서드를 기준으로 작업 정의
HTTP 프로토콜은 요청에 의미 체계의미를 할당하는 다양한 메서드를 정의합니다. 대부분의 RESTful 웹 API에서 사용하는 일반적인 HTTP 메서드는 다음과 같습니다.
- GET은 지정된 URI에서 리소스의 표현을 검색합니다.
- POST는 지정된 URI에서 새 리소스를 만듭니다.
- PUT은 지정된 URI에 리소스를 만들거나 대체합니다.
- PATCH는 리소스의 부분 업데이트를 수행합니다.
- DELETE는 지정된 URI의 리소스를 제거합니다.
전자 상거래 예제 기반 RESTful 구현 시 많이 채택된 일반적인 규칙
POST,PUT 및 PATCH의 차이점
- POST 요청은 리소스를 만듭니다. 서버는 새 리소스에대한 URI를 할당하고 클라이언트에 해당 URI를 반환합니다. 또한, 새 리소스를 만들지 않고 기존 리소스에 처리할 데이터를 보내는데 사용할 수도 있습니다.
- PUT 요청은 리소스를 만들거나 또는 기존 리소스를 업데이트합니다. 요청 본문에는 리소스의 완전한 표현이 포함됩니다. 이 URI를 사용하는 리소스가 이미 있으면 리소스가 대체됩니다.
- PATCH 요청은 기존 리소스에 부분 업데이트를 수행합니다. 요청 본문은 리소스에 적용할 변경 내용을 지정합니다. 클라이언트가 리소스의 전체 표현이 아닌 변경 내용만 보내기 때문에 PUT을 사용하는 것보다 이 방법이 더 효율적일 수 있습니다.
PUT 요청은 idempotent(멱등)여야 합니다. 클라이언트가 동일한 PUT 요청을 여러 번 제출하는 경우 그 결과가 항상 같아야 합니다.(같은 값을 사용하는 같은 리소스가 수정되므로 POST 및 PATCH 요청이 반드시 idempotent가 된다는 보장은 없습니다.
참고
1. Mockito 를 이용한 테스트
# 선택과제1, 2
'Tech > Spring' 카테고리의 다른 글
SpringBoot에서 HttpOnly 쿠키방식을 이용한 refreshToken 발급 (0) | 2021.02.27 |
---|---|
@Controller와 @RestController의 차이점 (2) | 2021.02.12 |
[취준생을 위한 스프링부트 백엔드 프로그래밍] 3주차 과제 (0) | 2021.01.26 |
[취준생을 위한 스프링부트 백엔드 프로그래밍] 1주차 과제 (0) | 2021.01.10 |
Gradle로 빌드하고 jar파일 실행하기(터미널) (0) | 2020.11.29 |