5.1 HTTP Method의 GET API 구현하기

김찬미·2024년 6월 7일
0
post-thumbnail

이번 글에서는 각 HTTP 메서드에 해당하는 API를 개발해보고 그 과정에서 필요한 내용들을 살펴보겠다. 아직 데이터베이스를 설치하지 않아 정확한 기능 구현은 어렵지만 외부의 요청을 받아 응답하는 기능을 구현해보자!


프로젝트 설정

먼저 5장에서 실습할 프로젝트를 생성하자. 앞에서 소개한 방법과 동일하게 생성하면 된다. 다만 이번에는 groupId는 'com.springboot'로 설정하고 name과 artifactId는 'api'로 설정하자.

GET API 만들기

GET API는 웹 애플리케이션 서버에서 값을 가져올 때 사용하는 API이다. GET API를 작성하는 방법은 다양하며, 이번 장에서는 애플리케이션으로 들어오는 여러 요청에 대한 처리 방법의 하나로서 소개해보겠다.

1) RequestMapping으로 구현하기

@RestController
@RequestMapping("/api/v1/get-api")
public class GetController {

    // 1) RequestMapping을 사용해 GET Method 구현
    // localhost:9090/apiv1/get-api/hello
    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    public String getHello() {
        return "Hello World";
    }

}

RequestMapping 어노테이션을 별다른 설정없이 선언하면 HTTP의 모든 요청을 받는다. 그러나 특정 형식의 요청만 받기 위해서는 어노테이션에 별도 설정이 필요하다. 이 코드와 같이 @RequestMapping 어노테이션의 method 요소의 값을 RequestMethod.GET으로 설정하면 요청 형식을 GET으로만 설정할 수 있다.

그러나 스프링 4.3 버전 이후로는 @RequestMapping 어노테이션은 더 이상 사용되지 않는다. 다음과 같은 어노테이션들이 새로 생겨났기 때문이다.

  • @GetMapping
  • @PostMapping
  • @PutMapping
  • @DeleteMapping

특별한 상황이 아니라면 앞으로는 이 어노테이션들을 상황에 맞게 사용할 것이다.

2) 매개변수가 없는 GET Method 구현

    // 2) 매개변수가 없는 GET Method 구현
    // localhost:9090/apiv1/get-api/name
    @GetMapping(value = "/name")
    public String getName() {
        return "Flature";
    }

매개변수가 없는 요청은 위 코드 1번 줄에 나와있는 URL을 그대로 입력하고 요청할 때 스프링 부트 애플리케이션이 정해진 응답을 반환한다.

3) PathVariavle을 활용한 GET Method 구현

실무에선 매개변수가 없는 메서드는 거의 쓰이지 않는다. 웹 통신의 기본 목적은 데이터를 주고받는 것이기에 대부분 매개변수를 받는 메서드를 작성하게 된다. 매개변수를 받을 때 자주 쓰이는 방법 중 하나는 URL 자체에 값을 담아 요청하는 것이다.

    // 3) PathVariavle을 활용한 GET Method 구현
    // localhost:9090/apiv1/get-api/variable1/{String 값}
    @GetMapping(value = "/variable1/{variable}")
    public String getVariable1(@PathVariable String variable) {
        return variable;
    }

1번 줄의 URL을 보면 이 메서드는 중괄호({})로 표시된 위치의 값을 받아 요청하는 것을 알 수 있다. (실제 요청 시 중괄호는 들어가지 않으며 값만 존재한다.) 값을 간단히 전달할 때 주로 사요하는 방법이며, GET 요청에서 많이 사용된다.

이러한 방식으로 코드를 작성할 때에는 주의사항이 있다. @GetMapping 어노테이션의 값으로 URL을 입력할 때 중괄호를 사용해 어느 위치에서 값을 받을지 지정해야 한다. 또한 메서드의 매개변수와 그 값을 연결하기 위해 3번 줄과 같이 @PathVariable을 명시하며, @GetMapping 어노테이션과 @PathVariable에 지정된 변수의 이름을 동일하게 맞춰야 한다.

4) RequestParam을 활용한 GET Method 구현

    // 4) RequestParam을 활용한 GET Method 구현
    // localhost:9090/apiv1/get-api/request1?name=value1&email=value2&organization=value3
    @GetMapping(value = "/request1")
    public String getRequestRaram1(
            @RequestParam String name,
            @RequestParam String email,
            @RequestParam String organization
    ) {
        return name + " " + email + " " + organization;
    }

URL 예시를 보면 ? 오른쪽에 쿼리스트링(query string)이 명시되어 있다. 쿼리스트링에는 키(변수의 이름)이 모두 적혀 있기 때문에 이 값을 기준으로 메서드의 매개변수에 이름을 매핑하면 값을 가져올 수 있다. 키와 @RequestParam 뒤에 적는 이름을 동일하게 설정하기 어렵다면 @PathVariable 예제처럼 value 요소로 매핑한다.

만약 쿼리스트링에 어떤 값이 들어올지 모른다면 아래와 같이 Map 객체를 사용할 수도 있다.

    // 5) RequestParam과 Map을 조합한 GET Method 구현
    // localhost:9090/apiv1/get-api/request2?key1=value1&key2=value2
    @GetMapping(value = "/request2")
    public String getRequestParam2(@RequestParam Map<String, String> param) {
        StringBuilder sb = new StringBuilder();
        
        param.entrySet().forEach(map -> {
            sb.append(map.getKey() + " : " + map.getValue() + "\n");
        });
        
        return sb.toString();
    }

이 방식으로 코드를 작성하면 값에 상관없이 요청을 받을 수 있다. 예를 들어 회원 가입 API에서 사용자는 ID같은 필수 항목이 아닌 취미 같은 선택 항목에 대해서는 값을 기입하지 않을 때도 있다. 이러한 경우에는 매개변수의 항목이 일정하지 않을 수 있어 Map 객체로 받는 것이 효율적이다.

URI와 URL의 차이

  • URL은 우리가 흔히 말하는 웹 주소를 의미하며, 리소스가 어디에 있는지 알려주기 위한 경로를 의미한다. 반면 URI는 특정 리소스를 식별할 수 있는 식별자를 의미한다.
  • 웹에서는 URL을 통해 리소스가 어느 서버에 위치해 있는지 알 수 있으며, 그 서버에 접근해서 리소스에 접근하기 위해서는 대부분 URI가 필요하다.

5) DTO 객체를 활용한 GET 메서드 구현

DTO란?

Data Transfer Object의 약자로, 다른 레이어 간의 데이터 교환에 활용된다. 간략하게 설명하자면 각 클래스 및 인터페이스를 호출하면서 전달하는 매개변수로 사용되는 데이터 객체이다. DTO는 데이터를 교환하는 용도로만 사용되는 객체이기 때문에 DTO에는 별도의 로직이 포함되지 않는다.

DTO와 VO

  • DTO와 VO(Value Object)는 역할을 서로 엄밀하게 구분하지 않고 사용할 때가 많다. 그러나 정확하게 구분하자면 역할과 사용법에서 차이가 있다.
  • VO는 데이터 그 자체로 의미가 있는 객체를 의미한다. VO는 읽기전용(Read-Only)로 설계된다. 즉, VO는 값을 변경할 수 없게 만들어 데이터의 신뢰성을 유지해야 한다.
  • DTO는 데이터 전송을 위해 사용되는 데이터 컨테이너로 볼 수 있다. 즉, 같은 애플리케이션 내부에서 사용되는 것이 아니라 다른 서버(시스템)로 전달하는 경우에 사용된다.

DTO의 예제는 다음과 같다.

@Data
public class MemberDto {
    private String name;
    private String email;
    private String organization;
    
    @Override
    public String toString() {
        return "MemberDto{" + "name: " + name + 
        ", email: " + email + ", organization: " + organization + "}";
    }
}
    // 6) DTO 객체를 이용한 GET 메서드 구현
    // localhost:9090/apiv1/get-api/request3?name=value1&email=value2&organization=value3
    @GetMapping(value = "/request3")
    public String getRequestParam3(MemberDto memberDto) {
        return memberDto.toString();
    }

위 코드는 4번(RequestParam을 활용한 GET Method 구현)과 동일한 쿼리스트링을 가지지만 4번에 비해 코드의 양을 줄일 수 있다.

profile
백엔드 개발자

0개의 댓글

관련 채용 정보