스프링부트 핵심 가이드 책을 통한 글 입니다.
GET API는 웹 애플리케이션 서버에서 값을 가져올 때 사용하는 API이다. GET을 쉽게 말하자면, 서버에게 리소스(데이터)를 가져와라(GET)라는 의미이다. GET API를 작성하는 방법은 다양하며, 이번 장에서는 애플리케이션으로 들어오는 여러 요청에 대한 처리 방법의 하나로서 소개한다. 추가로 프론트엔드에서 백엔드로 데이터를 요청할 때 쓰인다.
아래의 예제 코드를 통해 여러 GET 방식을 알아보자.
@RestController
@RequestMapping("/api/v1/get-api")
public class GetController {
//5.2.1 @RequestMapping으로 구현하기
@RequestMapping(value="/hello",method = RequestMethod.GET)
public String getHello(){
return "Hello World";
}
//5.2.2 매개변수가 없는 GET 메서드 구현
@GetMapping(value="/name")
public String getName(){
return "Flature";
}
//5.2.3 @PathVariable을 활용한 GET 요청(매개변수 있는 GET요청)
@GetMapping(value="/variable1/{variable}")
public String getVariable1(@PathVariable String variable){
return variable;
}
@GetMapping(value="/variable2/{variable}")
public String getVariable2(@PathVariable("variable") String var){
return var;
}
//5.2.4 @RequestParam을 활용한 GET 메서드 구현+Map 함수
@GetMapping(value="/request1")
public String getRequestParam1(
@RequestParam String name,
@RequestParam String email,
@RequestParam String organization){
return name+" "+email+" "+organization;
}
@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();
}
@GetMapping(value="/request3")// DTO를 활용한 GET 요청
public String getRequestParam3(MemberDto memberDto){
return memberDto.toString();
}
}
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(){//원래의 toString()함수를 오버라이딩하여 재정의하였다.
return "MemberDto{"+"name=`"+name+'\''+", email='"+email+'\''+
",organization='"+organization+'\''+'}';
}
//결국 System.out.println(member);을 호출하면 오버라이딩한 toString()이 불린다.
}

@RestController은 내부적으로 @Controller + @ResponseBody의 기능을 합친 것이다. 이 클래스 안의 메서드들이 데이터(String, JSON 등)를 직접 반환하며, 뷰(view)를 사용하지 않는다.@ResponseBody는 Controller에서 return 할 때 json형식으로 반환하는 역할을 한다. @RequestMapping(value="/hello",method = RequestMethod.GET)
public String getHello(){
return "Hello World";
}
@RequestMapping어노테이션은 이 클래스의 모든 요청 경로 앞에는 /api/v1/get-api가 붙게 매핑된다. 클래스 안에 있는 매서드(getHello)에 붙어있는 @RequestMapping은 /hello 요청을 보내려면 실제 요청 경로는 /api/v1/get-api/hello가 되어 Hello World를 출력한다.@RequestMapping의 단점은 GET메서드를 매개변수로 받아야 하기 때문에 잘 쓰이지 않고 아래 내용인 @GetMapping을 더 많이 쓴다. @GetMapping(value="/name")
public String getName(){
return "Flature";
}
@GetMapping을 통해 응답을 반환한다. 즉, http://localhost:8080/api/v1/get-api/name을 입력하면 Flature가 반환된다.@RequestMapping과의 차이점은 GET요청을 한다는 가독성과 @RequestMapping보다 편리하다는 점에서 더 많이 쓰인다. @GetMapping(value="/variable1/{variable}")//URL값과 매개변수 값 같은 경우
public String getVariable1(@PathVariable String variable){
return variable;
}
@GetMapping(value="/variable2/{variable}")//URL값과 매개변수값이 다른 경우
public String getVariable2(@PathVariable("variable") String var){
return var;
}
{variable})과 메서드 매개변수(variable)를 바인딩(연결)해 주는 어노테이션이고, @GetMapping("/변수포함경로")와 함께 쓰여 URL을 통해 매개변수를 받게 할 수 있는 어노테이션이다.variable로 같다. @GetMapping(value="request1")
public String getRequestParam1(
@RequestParam String name,
@RequestParam String email,
@RequestParam String organization){
return name+" "+email+" "+organization;
}
?{key}:{value}&{key}:{value}... 이러한 식으로 요청을 전송할 수 있다. 위의 코드를 예시로 들면http://localhost:8080/api/v1/get-api/request1?name=value1 &email=value2&organization=value3 이렇게 요청을 전송한다.GET결과는 value1 value2 value3가 된다. @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();
}
Map 객체로 받는 것이 효율적이다.1) @RequestParam Map<String, String> param
클라이언트가 보낸 쿼리 파라미터를 Map 형태로 전부 받아온다.
예를 들어 요청이 GET /request2?name=Tom&age=30 라면,
param = {
"name" : "Tom",
"age" : "30"
}
2) StringBuilder sb = new StringBuilder();
여러 문자열을 효율적으로 연결하기 위해 사용하는 클래스이다.
여기선 key와 value를 "key : value" 형식으로 하나의 문자열로 합칠 때 사용된다.
3) param.entrySet().forEach(...)
Map의 모든 key-value 쌍을 하나씩 반복(.forEach)하면서,
각 쌍을 "key : value\n" 형식으로 만들어 StringBuilder에 추가한다.
// 반복 예시:
"Tom" -> sb.append("name : Tom\n")
"30" -> sb.append("age : 30\n")
4) return sb.toString();
StringBuilder에 저장된 모든 문자열을 하나로 묶어 String으로 변환해서 반환한다.
이 값이 HTTP 응답 본문으로 클라이언트에게 전달된다.
다른 레이어 간의 데이터 교환에 활용
(예를 들어 Controller<->DTO<->Service)된다. 각 클래스 및 인터페이스를 호출하면서 전달하는 매개변수로 사용되는 데이터 객체이다. 즉, 별도의 로직이 필요없다.
//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(){//원래의 toString()함수를 오버라이딩하여 재정의하였다.
return "MemberDto{"+"name=`"+name+'\''+", email='"+email+'\''+
",organization='"+organization+'\''+'}';
}
//결국 System.out.println(member);을 호출하면 오버라이딩한 toString()이 불린다.
}
//Controller 클래스
@GetMapping(value="/request3")
public String getRequestParam3(MemberDto memberDto){
return memberDto.toString();
}
DTO 패키지에 있는 MemberDto 클래스에서 toString()함수를 오버라이딩 했기 때문에 memberDto.toString()시 밑의 요청이 return되게 한다."MemberDto{"+"name=`"+name+'\''+", email='"+email+'\''+ ",organization='"+organization+'\''+'}'http요청이 어떻게 자동으로 set되는지 궁금했는데 DTO 클래스에는 setter가 있으면 자동으로 set된다고 한다 즉, 스프링이 자동으로 쿼리스트링 값(?기호 뒤에 붙는 키-값 쌍의 데이터)을 DTO의 `setter에 매핑한다.http://localhost:8080/api/v1/get-api/request3?name=value1&email=value2&organization=value3