스프링

스프링 1-3. GET API

호놀롤루 2022. 3. 15. 15:27

1. 개요

원래 REST API를 기능 별로 분리하지 않지만, 여기선 연습이니 API를 기능별로 나눠서 프로젝트를 만들 것이다.

 

우선 GET API는 처음 만든 프로젝트에 추가해서 만들 것이다.

 

그리고 GET API의 특징을 정리하면

  • 리소스 취득용 (읽기)
  • CRUD의 R
  • 멱등하다 (언제나 결과가 일정함)
  • 결과가 안정함 (다른 데이터 추가되거나 몇백번 확인한다고 return이 달라지는 게 아님)
  • Path Variable 받을 수 있음
  • Query Parameter 받을 수 있음
  • DataBody 사용 안 함

 

2. 사용법

2-1. GetMapping(), RequestMapping()

일단 @GetMapping("주소") 커맨드 누르고 저 코드 누르면 파라미터로 뭐 넣을 수 있는지 확인 가능함

@GetMapping() 어노테이션에서 주소를 넣어도 되지만 안 넣으면 Default로 패싱된다.

명시적으로 지정하는 방법도 있는데

@GetMapping(path = "/hello")

이렇게 명시적으로 지정할 수 있다.

 

그리고 Get이 아닌 @RequestMapping으로 받을 수도 있다.

그런데 이렇게 받으면 GET, POST, PUT, DELETE 이런 거 구분없이 RequestMapping에서 다 처리하니

만약 이걸로 설정하려면

@RequestMapping(value = "/hello", method = RequestMethod.GET) 이런 식으로 지정을 해주는게 좋다.

 

 

2-2. path Variable

Path Variable이란 변수처럼 바뀔 수 있는 수를 집어넣는 것이다.

@GetMapping("/path-variable/{name}")

public String pathVariable(@PathVariable String name) {

    System.out.println("PathVariable : "+name);

    return name;

}

이렇게 사용하면 http://localhost:8080/api/path-variable/원하는 숫자

저기서 넣은 원하는 숫자가 페이지에 나오고 인텔리제이에서도 출력된다.

 

주의할 점은 메소드의 파라미터를 그냥 넣으면 안된다. 파라미터 앞에 @PathVariable을 붙여야 한다.

 

그런데 만약 파라미터로 쓰던 변수 이름을 수정하거나 하면 pathVariable 값과 파라미터가 달라서 제대로

데이터 처리가 되지 않는다.

 

그럴 때 쓸 수 있는 방법이 파라미터 어노테이션에서 이름을 지정하는 것이다. 

만약, @GetMapping("/path-variable/{id}") 로 바뀌었다면

public String pathVariable(@PathVariable(name = "id") String pathName)

이런 식으로 name을 지정해주면 pathName에 get에서 받은 {Id}의 값이 들어가게 된다.

 

 

2-3. query parameter

URL을 보면 중간에 ? 기호가 들어가 있는 경우가 많다.

구글에 "사자" 를 검색하면 이런 URL이 나온다.

https://www.google.com/search?client=safari&rls=en&q=%EC%82%AC%EC%9E%90&ie=UTF-8&oe=UTF-8

분석해보면

https://www.google.com/search?

client=safari&

rls=en&

q=%EC%82%AC%EC%9E%90&

ie=UTF-8&

oe=UTF-8

잘 보니 매핑 변수의 형태를 하고있다. key = value & key = value

이런 형태의 매핑변수를 query parameter라고 한다.

// http://localhost:8080:/api/get/query-param?user=steve&email=steve@gmail.com&age=39
@GetMapping(path ="query-param")
public String queryParam(@RequestParam Map<String, String> queryParam) {

    StringBuilder sb = new StringBuilder();

    queryParam.entrySet().forEach( entry -> {
        System.out.println(entry.getKey());
        System.out.println(entry.getValue());
        System.out.println();

        sb.append(entry.getKey() + " = " + entry.getValue()+"\n");
    });

    return sb.toString();
}

자바의 자료구조 Map도 매핑변수이니 key 문자열, value 문자열을 받아서 forEach로 출력하도록 만들었다.

실행하고 주석된 부분을 입력하면 

User = steve email = steve.gmail.com age = 39 라는 결과가 나온다.

 

그런데 이런 식으로 받으면 name 하나만 구하려고 해도 queryParam.get("name")의 형태로 지정해서

받아야 한다.

 

하지만 각각의 파라미터에 @RequestParam 어노테이션을 붙여주면 더 편하게 작성할 수 있다.

@GetMapping("query-param02")
public String queryParam02(
        @RequestParam String name,
        @RequestParam String email,
        @RequestParam int age
) {
    System.out.println(name);
    System.out.println(email);
    System.out.println(age);
    return name+" "+email+" "+age;
}

 

편하긴 하지만 사용자가 데이터형을 잘못 지정하면 에러가 뜬다. String에 정수를 넣는 등

 

그런데 지금이야 파라미터 수가 적어서 괜찮은데 파라미터 수가 계속 늘어나면 이 방법도 관리가 쉽지 않다.

 

그래서 현업에서 많이 쓰는 방법은 dto를 만드는 방법이다.

 

2-4. dto (Data Transfer Object)

Controller 패키지 옆에 dto 패키지를 만들어서 거기다 dto 클래스를 만들어서 사용하는 방법이다.

package com.example.hello.dto;

public class UserRequest {

    private String name;
    private String email;
    private int age;

    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 int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

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

toString은 그냥 빈 칸에 toString 치고 기다리면 지정하는 방법이 뜬다.

 

@GetMapping("query-param03")
public String queryParam03(UserRequest userRequest) {
    System.out.println(userRequest.getName());
    System.out.println(userRequest.getEmail());
    System.out.println(userRequest.getAge());
    return userRequest.toString();
}

그리고 이 dto 객체를 파라미터로 넣어주면 된다. 근데 여기선 @RequestParam 넣으면 안됨

스프링 부트에서 ? 뒤에 있는 걸 판단해서 key에 매칭해준다.

즉 여기선 name, email, age를 key와 매칭하고 = 뒤에 있는 걸 value로 매칭해준다.

 

이렇게 객체를 만들어서 객체로 받는 게 가장 관리하기도, 요청 값을 검증하기도 편하다.

그리고 만약 객체에 정의되지 않은 값이 넘어왔다면 에러는 안뜨고 무시한다.

만약 http://localhost/api/query-param03?name=asd&email=asd.naver.com&age=38&address=pusan

이라고 입력할 시, address는 처리되지 않는다.

 

그래도 요청값이 적으면 @RequestParam으로 받아도 되긴 함

 

아무튼 GET API를 설정하는 방법에 대해서 정리해봤다.