API 작성법
클래스 단위에 붙이는 어노테이션
@RestController
@RequestMapping("/api?v1/get-api")
public class GetController {
}
클래스 수준에서 @RequestMapping을 설정하면 내부에 선언한 메서드의 URL 리소스 앞에 @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", mehtod = RequestMethod.GET)
public String getHello() {
return "Hello World";
}
}
스프링 4.3 버전 이후로는 새로 나온 아래의 어노테이션을 사용하기 때문에 @RequestMapping 어노테이션은 더 이상 사용되지 않습니다.
- @GetMapping
- @PostMapping
- @PutMapping
- @DeleteMapping
매개변수가 없는 GET 메서드 구현
별도의 매개변수 없이 GET API를 구현하는 경우 아래와 같이 코드를 작성할 수 있습니다.
// http://localhost:8080/api/v1/get-api/name
@GetMapping(value = "/name")
public String getNmae() {
return "Flature";
}
@PathVariable을 활용한 GET 메서드 구현
실무 환경에서는 매개변수를 받지 않는 메서드가 거의 쓰이지 않습니다. 웹 통신의 기본 목적은 데이터를 주고받는 것이기 때문에 대부분 매개변수를 받는 메서드를 작성하게 됩니다. 매개변수를 받을 때 자주 쓰이는 방법 중 하나는 URL 자체에 값을 담아 요청하는 것입니다.
// http://localhost:8080/api/v1/get-api/variable1/{String 값}
@GetMapping(value = "/variable1/{variable}")
public String getVariable1(@PathVariable String variable){
return variable;
}
첫줄에 있는 요청 예시 URL을 보면 이 메서드는 중괄호 ({})로 표시된 위치의 값을 받아 요청하는 것을 알 수 있습니다.(실제 요청 시 중괄호는 들어가지 않으며 값만 존재합니다.) 값을 간단히 전달할 때 주로 사용하는 방법이며, GET 요청에서 많이 사용됩니다.
이러한 방식으로 코드를 작성할 때는 몇 가지 지켜야 할 규칙이 있습니다. @GetMapping 어노테이션의 값으로 URL을 입력할 때 중괄호를 사용해 어느 위치에서 값을 받을지 지정해야합니다. 또한 메서드의 매개변수와 그 값을 연결하기 위해 @PathVariable을 명시하며, @GetMapping어노테이션과 @PathVariable에 지정된 변수의 이름을 동일하게 맞춰야 합니다.
만약 @GetMapping 어노테이션에 지정한 변수의 이름과 메서드 매개변수의 이름을 동일하게 맞추기 어렵다면 @PathVariable뒤에 괄호를 열어 @GetMapping 어노테이션의 변수명을 지정합니다.
// http://localhost:8080/api/v1/get-api/variable2/{String 값}
@GetMapping(value = "/variable2/{variable}")
public String getVariable2(@PathVariable("variable") String var) {
return var;
}
위 예제는 2번째 라인에 적혀있는 변수명인 variable과 3번 줄에 적힌 매개변수명인 var가 서로 일치하지 않는 상황에서 두 값을 매핑하는 방법을 보여줍니다. @PathVarialbe에는 변수의 이름을 특정할 수 있는 value 요소가 존재하며, 이 위치에 변수 이름을 정의하면 매개변수와 매핑할 수 있습니다. 3번 줄의 @PathVariable 사용법을 좀 더 풀어쓰면 다음과 같습니다.
public String getVariable2(@PathVariable(value = "variable") String var) {
@RequestParam을 활용한 GET 메서드 구현
GET 요청을 구현할 때 앞에서 살펴본 방법처럼 URL 경로에 값을 담아 요청을 보내는 방법 외에도 쿼리 형식으로 값을 전달할 수도 있습니다. 즉, URI에서 '?' 를 기준으로 우측에 '{키}={값}' 형태로 구성된 요청을 전송하는 방법입니다. 애플르케이션에서 이 같은 형식을 처리하려면 @RequestParam을 활용하면 되는데, 아래 예제와 같이 매개변수 부분에 @RequestParam 어노테이션을 명시해 쿼리 값과 매핑하면 됩니다.
//http://localhost:8080/api/v1/get-api/request1?name=value1&email=value2&organization=value3
@GetMapping(value = "/request1")
public String getRequestParam1(
@RequestParam String name,
@RequestParam String email,
@RequestParam String organization) {
return name + " " + email + " " + organization;
}
1번 줄을 보면 "?" 오른쪽에 쿼리스트링(query string)이 명시돼 있습니다. 쿼리스트링에는 키(변수의 이름)가 모두 적혀 있기 때문에 이 값을 기준으로 메서드의 매개변수에 이름을 매핑하면 값을 가져올 수 있습니다. 키와 @RequestParam 뒤에 적는 이름을 동일하게 설정하기 어렵다면 @PathVariable 예제에서 사용한 방법처럼 value요소로 매핑합니다.
만약 쿼리스트링에 어떤 값이 들어올지 모른다면 아래와 같이 Map객체를 활용할 수도 있습니다.
// http://localhost:8080/api/v1/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가 필요합니다.
DTO 객체를 활요한 GET 메서드 구현
DTO란?
DTO는 Data Transfer Object의 약자로, 다른 레이어 간의 데이터 교환에 활용됩니다.
각 클래스 및 인터페이스를 호출하면서 전달하는 매개변수로 사용되는 데이터 객체입니다.
참고로 DTO와 VO
DTO와 VO(Value Object)의 역할을 서로 엄밀하게 구분하지 않고 사용할 때가 많습니다. 이렇게 해도 대부분의 상황에서는 큰 문제가 발생하지 않지만 정확하게 구분하자면 역할과 사용법에서 차이가 있습니다.
먼저 VO는 데이터 그 자체로 의미가 있는 객체를 의미합니다. VO의 가장 특징적인 부분은 읽기전용으로 설계한다는 점입니다. 즉, VO는 값을 변경할 수 없게 만들어 데이터의 신뢰성을 유지해야 합니다.
DTO는 데이터 전송을 위해 사용되는 데이터 컨테이너로 볼 수 있습니다. 즉, 같은 애플리케이션 내부에서 사용되는 것이 아니라 다른 서버(시스템)로 전달하는 경우에 사용됩니다.
본문에서는 DTO가 다른 레이어 간 데이터 교환에 활용된다고 설명했습니다. 여기서 레이어는 애플리케이션 내부에 정의된 레이어일 수도 있고 인프라 관점에서의 서버 아키텍처 상의 레이어일 수도 있습니다. 이러한 개념의 혼용이 DTO와 VO의 차이를 흐리게 만듭니다.
이 같은 용어와 개념을 정확하게 사용하는 것도 중요하지만 팀 내부적으로 용어나 개념의 역할 범위를 설정하고 합의해서 사용하는다면 업무를 효율적으로 처리하는 데 도움이 됩니다.
DTO 객체는 아래와 같이 작성할 수 있습니다. 이 클래스 파일은 예제 프로젝트에서 com.springboot.api 패키지 하단에 dto라는 패키지를 생성한 후 그 안에 생성하면 됩니다.
public class MemberDto {
private String name;
private String email;
private String organizaion;
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) {
//retrun memberDto.getName() + " " + memberDto.getEmail() + " " + memberDto.getOrganization();
return memberDto.toString();
}
'웹 개발 > 🍃 SpringBoot' 카테고리의 다른 글
JPA | ORM (1) | 2025.01.07 |
---|---|
SpringBoot | POST,PUT,DELETE API를 작성하는 방법 (1) | 2024.12.26 |
JUnit5 | 기본 테스트 어노테이션 (0) | 2024.12.18 |
Project Metadata - spring initializr 정복하기(4) (1) | 2024.12.17 |
Spring Boot - spring initializr 정복하기(3) (0) | 2024.12.17 |