Create API Operation(2) - Search by condition

GEONNY·2024년 7월 29일
0

Building-API

목록 보기
8/28
post-thumbnail

MemberController 에 memberId 를 parameter 로 받아 특정 Member만 조회 하는 operation 을 추가 해보겠습니다.

📌service interface 에 메서드 추가

public interface MemberService {
    MemberSearchResponse getMemberById(String memberId); // 추가!
    
    List<MemberSearchResponse> getMembers();

    MemberCreateResponse createMember(MemberCreateRequest parameter);

    MemberModifyResponse modifyMember(MemberModifyRequest parameter);

    Long deleteMember(MemberDeleteRequest parameter);
}

interface 에 getMemberById 메서드를 추가합니다. 이전 구현체에 getMeberById method 가 없기 때문에 오류가 발생합니다. Implement methods 를 통해 getMemberById method 를 Override 하고 조회한 데이터를 리턴하도록 구현합니다.

    @Override
    public MemberSearchResponse getMemberById(String memberId) {
        Member member = memberRepository.findById(memberId)
                .orElseThrow(() -> 
                new EntityNotFoundException("회원 ID 가 존재하지 않습니다. -> " + memberId));
        return new MemberSearchResponse(member.getMemberId(), member.getMemberName());
    }

JpaRepository 의 findById method 를 사용하여 특정 Member 의 정보를 조회 해 리턴합니다. findById 의 리턴 타입은 Optional 이기 때문에 orElseThrow 로 데이터가 없을 경우에는 EntityNotFoundException 을 throw 하게 합니다.

📌controller operation 추가

Controller 에도 구현한 Service 를 사용하는 operation 을 추가합니다. @PathVariable 로 memberId 를 받아 서비스로 전달합니다.

@GetMapping(value = "/members/{memberId}", produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<MemberSearchResponse> getMemberById(
    		@PathVariable("memberId") String memberId) {
        return ResponseEntity.ok()
                .body(memberService.getMemberById(memberId));
    }

RESTFul API URI 생성 규칙에서 '/' (슬래시) 는 계층 관계를 나타내는데 사용됩니다.
/members/{memberId} 는 member들 중에 memberId 가 같은 사람을 조회할꺼야 라는 약속이 되는거죠. 그리고 위와 같이 URI 에 '{', '}' 를 사용한 변수는 @PathVariable 을 통해서 전달 받을 수 있습니다.
@PathVariable 의 기본 옵션은 필수 입니다. required = false 를 통해 필수 옵션을 해제 할 수 있습니다. @PathVariable(value = "memberId", required = false)

이제 member1 을 조회 조건으로 전달 해 봅시다. 브라우저에 아래 URI 를 입력합니다.
http://localhost:13713/my-api/members/member1

{
  memberId: "member1",
  memberName: "회원 명"
}

조건에 의한 결과를 받았습니다.
그럼 존재하지 않는 ID 를 조회 조건으로 넘겼을 때는 어떻게 될까요?
http://localhost:13713/my-api/members/member2

Browser

Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.

Fri Jul 26 11:25:39 KST 2024
There was an unexpected error (type=Internal Server Error, status=500).

IDE

jakarta.persistence.EntityNotFoundException: 회원 ID 가 존재하지 않습니다. -> member2
이하 생략..

브라우저에는 오류 화면이 뜨고 IDE에는 아래와 같은 Exception log 가 출력됩니다.

API 는 Exception 발생 시 오류 페이지를 전달해서는 안됩니다. Exception 이 발생하더라도 API 를 응답 받을 곳에서 오류를 인지, 처리 할 수 있도록 오류 코드를 정의하고 공통의 응답구조체를 전달해야 합니다. Checked Exception 의 경우 이에 해당하는 오류 코드 응답 구조체를, 개발자가 예상하지 못했던 Unchecked Exception 이 발생하더라도 특정 오류 코드 응답 구조체를 전달해야 합니다. 다음에는 공통 응답 구조체를 정의하고 @RestControllerAdvice 를 사용하여 API 에서 발생하는 Exception 을 공통으로 처리하기 위한 Handler 를 구현해보도록 하겠습니다.😄

📚참고

📕Get method parameter 전달

RESTFul API 에서 조회를 할 때 사용하는 Get Method 에서 parameter 를 전달받는 방법을 알아보겠습니다.

📖@PathVariable

위의 예제에서 사용했던 @PathVariable 은 URI의 특정 경로를 추출할 때 사용합니다.
RESTFul API 에서 / 는 리소스를 식별하는데 사용되며 계층관계를 나타냅니다.

@GetMapping(value = "/members/{memberId}", produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<MemberSearchResponse> getMemberById(
    		@PathVariable("memberId") String memberId) {
        return ResponseEntity.ok()
                .body(memberService.getMemberById(memberId));
    }

📖@RequestParam

? 이후에 전달되는 Query Parameter 나 Form Data 에서 값을 추출할 때 사용합니다. Query Parameter 는 ?key=value 의 형태로 전달 되며, 복수의 값을 전달 해야 할 경우 & 로 연결하여 전달합니다.
?key1=value1&key2=value2
RESTFul API 에서는 보통 요청 하는 데이터 이외의 추가적인 정보를 전달하거나 필터, 정렬, 페이징 등의 정보 전달에 활용됩니다.
?page=1&numberOfPage=10

@GetMapping(value = "/members", produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<List<MemberSearchResponse>> getMembers(
    		@RequestParam int page, @RequestParam int numberOfPage) {
        return ResponseEntity.ok()
                .body(memberService.getMembers(page, numberOfPage));
    }
profile
Back-end developer

0개의 댓글