[스프링] 5. API를 작성하는 다양한 방법(GET)

PYOUNANI·2023년 10월 30일
0

Spring

목록 보기
5/31
post-thumbnail
📢 장정우님이 지음, 
[스프링부트 핵심가이드 : 스프링 부트를 활용한 애플리케이션 개발 실무] 책을 읽고 정리한 글입니다.

GET API 만들기

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

실무에서는 HTTP 메서드에 따라 컨트롤러 클래스를 구분하지 않지만 여기서는 메서드별로 클래스를 생성한다. 아래와 같이 controller 패키지를 생성하고 GetController 클래스를 생성한다.

그리고 아래와 같이 컨트롤러에 @RestController 와 @RequestMapping을 붙여 내부에 선언되는 메서드에서 사용할 공통 URL을 설정한다.

//컨트롤러 클래스에 @RestController와 @RequestMapping 설정
package com.example.corner.controller;

import com.example.corner.dto.MemberDto;
import org.springframework.web.bind.annotation.*;

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

클래스 수준에서 @RequestMapping을 설정하면 내부에 선언한 메서드의 URL 리소스 앞에 @RequestMapping의 값이 공통 값으로 추가된다.

@RequestMapping으로 구현하기

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

package com.springboot.api.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api/v1/get-api")
public class GetController {
    //http://localhost:8080/api/v1/get-api/hello
    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    public String getHello(){
        return "Hello World";
    }
}

스프링 4.3 버전 이후로는 새로 나온 아래의 어노테이션을 사용하기 때문에 @RequestMapping 어노테이션은 더 이상 사용되지 않는다. 앞으로 예제에서는 특별히 @RequestMapping을 활용해야 하는 내용이 아니라면 아래의 각 HTTP 메서드에 맞는 어노테이션을 사용할 예정이다.

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

매개변수가 없는 GET메서드 구현

별도의 매개변수 없이 GET API를 구현하는 경우 아래와 같이 코드를 작성할 수 있다.

//http://localhost:8080/api/v1/get-api/name
    @GetMapping(value = "/name")
    public String getName(){
        return "Flature";
    }

@PathVariable을 활요한 GET메서드 구현

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

//http://localhost:8080/api/v1/get-api/variable1/{String 값}
    @GetMapping(value = "variable1/{variable}")
    public String getVariable1(@PathVariable String variable){
        return variable;
    }

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

만약 @GetMapping 어노테이션에 지정한 변수의 이름과 메서드 매개변수의 이름을 동일하게 맞추기 어렵다면 @PathVariable 뒤에 괄호를 열어 @GetMpping 어노테이션의 변수명을 지정한다.

//http://localhost:8080/api/v1/get-api/variable2/{String 값}
    @GetMapping(value = "variable2/{variable}")
    public String getVariable2(@PathVariable("variable") String var){
        return var;
    }

@RequestParam을 활용한 GET 메서드 구현

GET 요청을 구현할 때 앞에서 살펴본 방법처럼 URL 경로에 값을 담에 요청을 보내는 방법 외에도 쿼리 형식으로 값을 전달할 수도 있다. 즉, URI에서 '?'를 기준으로 우측에 '{키} = {값}' 형태로 구성된 요청을 전송하는 방법이다. 애플리케이션에서 이 같은 형식을 처리하려면 @RequestParam을 활용하면 되는데, 아래와 같이 매개변수 부분에 @RequestParam 어노테이션을 명시해 쿼리 값과 매핑하면 된다.

//http://localhost:8080/api/v1/get-api/request1?name=value1&email=value2&organization=value3
    @GetMapping(value = "variable2/request1")
    public String getRequestParam1(
            @RequestParam String name,
            @RequestParam String email,
            @RequestParam String organization) {
        return name + " " + email + " " + organization;
    }

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

💡 Tip. URI와 URL의 차이
URL은 우리가 흔히 말하는 웹 주소를 의미하며, 리소스가 어디에 있는지 알려주기 위한 경로를 의미한다. 반면 URI는 특정 리소스를 식별할 수 있는 식별자를 의미한다.

웹에서는 URL을 통해 리소스가 어느 서버에 위치해 있는지 알 수 있으며, 그 서버에 접근해서 리소스에 접근하기 위해서는 대부분 URI가 필요하다.

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

DTO란?
DTO는 Data Transfer Object의 약자로, 다른 레이어 간의 데이터 교환에 활용된다. 간략하게 설명하자면 클래스 및 인터페이스를 호출하면서 전달하는 매개변수로 사용되는 데이터 객체이다.

DTO는 데이터를 교환하는 용도로만 사용하는 객체이기 때문에 DTO에는 별도의 로직이 포함되지 않는다. 이 책에서는 6장의 데이터베이스를 연동하는 작업을 시작으로 본격적인 데이터를 다룰 예정이므로 DTO 클래스의 역할은 이때 좀 더 다루도록 하겠다.

package com.example.corner.dto;

public class MemberDto {
    private String name;
    private String email;
    private String organization;

    public String getName(){
        return name;
    }

    public void setName(String name){
        this.name = name;
    }

    public String getEmail(){
        return email;
    }

    public void setEmail(String email){
        this.email = email;
    }

    public String getOrganization(){
        return organization;
    }

    public void setOrganization(String organization){
        this.organization = organization;
    }

    @Override
    public String toString(){
        return "MemberDto{" +
                "name='" + name + '\'' +
                ", email ='" + email + '\'' +
                ", organization='" + organization + '\'' +
                '}';
    }
}

DTO 클래스에는 전달하고자 하는 필드 객체를 선언하고 getter/setter 메서드를 구현한다. DTO 클래스에 선언된 필드는 컨트롤러의 메서드에서 쿼리 파라미터의 키와 매핑된다. 즉, 쿼리스트링의 키가 정해져 있지만 받아야 할 파라미터가 많을 경우에는 아래와 같이 DTO 객체를 활용해 코드의 가독성을 높일 수 있다.

// http://localhost:8080/api/v1/get-api/request3?name=value1&email=value2&organization=value3
    @GetMapping(value="/request3")
    public String getRequestParam3(MemberDto memberDto){
        //return memberDto.getName() + " " + memberDto.getEmail() + " " + memberDto.getOrganization();
        return memberDto.toString();
    }

0개의 댓글