1. REST API란?
REST API는 웹 서비스 간의 통신을 위한 아키텍처 스타일입니다.
REST(Representational State Transfer)의 원칙을 따르며 리소스를 중심으로 설계됩니다.
1-1. REST(Representational State Transfer)의 개념
- REST 아키텍처의 주요 원칙
- 클라이언트-서버 구조: 관심사의 분리를 통해 확장성을 개선합니다.
- 무상태성: 각 요청은 독립적이며, 서버는 클라이언트의 상태를 저장하지 않습니다.
- 캐시 가능성: 응답은 캐시 가능 여부를 명시해야 합니다.
- 계층화 시스템: 클라이언트는 서버와 직접 연결되었는지 중간 서버와 연결되었는지 알 수 없습니다.
- 인터페이스 일관성: 일관된 인터페이스로 전체 시스템 아키텍처를 단순화합니다.
2. REST API의 구성요소
- 자원 : URI로 표현됩니다.
- 행위 : HTTP 메서드(GET, POST, PUT, DELETE 등)로 표현됩니다.
- 표현 : 주로 JSON 형식으로 데이터를 주고받습니다.
- HTTP 상태 코드: 요청의 처리 결과를 나타냅니다.
3. Spring에서 REST API 구현하기
3.1 기본 설정
@RestController
@RequestMapping("/api")
public class UserController {
// 컨트롤러 내용
}
3.2 주요 어노테이션
Spring에서 REST API 구현 시 사용되는 주요 어노테이션들입니다.
- @RestController: RESTful 웹 서비스의 컨트롤러를 나타냅니다.
- @RequestMapping: 요청 URL을 특정 메서드에 매핑합니다.
- @GetMapping, @PostMapping, @PutMapping, @DeleteMapping: 각각 GET, POST, PUT, DELETE HTTP 메서드에 대한 요청을 처리합니다.
- @PathVariable: URL 경로에 변수를 넣어 사용할 때 사용합니다.
- @RequestBody: HTTP 요청 본문을 자바 객체로 변환합니다.
- @ResponseEntity: HTTP 응답의 전체 내용을 제어할 수 있게 해줍니다.
RESTful은 웹 서비스 설계를 위한 아키텍처 스타일인 REST 원칙을 완벽히 준수하는 시스템을 의미합니다
3.3 HTTP 메서드별 구현 예시
- GET 요청 처리
➔ 역할: 서버에서 데이터를 조회합니다.
➔ 응답: 성공 시 200 OK 상태 코드와 함께 사용자 데이터 (JSON/XML)
@GetMapping("/users/{id}")
public ResponseEntity<User> getUser(@PathVariable Long id) {
User user = userService.findById(id);
return ResponseEntity.ok(user);
}
- POST 요청 처리
➔ 역할: 새로운 리소스를 생성합니다.
➔ 응답: 생성 완료 시 201 Created 상태 코드와 생성된 사용자 정보 반환
@PostMapping("/users")
public ResponseEntity<User> createUser(@RequestBody UserDto userDto) {
User savedUser = userService.save(userDto);
return ResponseEntity.status(HttpStatus.CREATED).body(savedUser);
}
- PUT 요청 처리
➔ 역할: 기존 리소스를 전체 수정합니다.
➔ 응답: 성공 시 200 OK 상태 코드와 수정된 사용자 데이터 반환
@PutMapping("/users/{id}")
public ResponseEntity<User> updateUser(@PathVariable Long id, @RequestBody UserDto userDto) {
User updatedUser = userService.update(id, userDto);
return ResponseEntity.ok(updatedUser);
}
- DELETE 요청 처리
➔ 역할: 특정 리소스를 삭제합니다.
➔ 응답: 성공 시 204 No Content (반환할 데이터 없음)
@DeleteMapping("/users/{id}")
public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
userService.delete(id);
return ResponseEntity.noContent().build();
}
4. REST API 응답 처리
4.1 ResponseEntity 활용
ResponseEntity를 사용하면 HTTP 응답의 상태 코드, 헤더, 본문을 세밀하게 제어할 수 있습니다.
@GetMapping("/users")
public ResponseEntity<List<User>> getAllUsers() {
List<User> users = userService.findAll();
return ResponseEntity
.ok()
.header("Custom-Header", "value")
.body(users);
}
4.2 예외 처리
예외 처리는 @ExceptionHandler를 사용하여 구현할 수 있습니다.
아래 방법을 통해 특정 예외에 대해 일관된 응답을 제공할 수 있습니다.
@ExceptionHandler(UserNotFoundException.class)
public ResponseEntity<ErrorResponse> handleUserNotFoundException(UserNotFoundException e) {
ErrorResponse error = new ErrorResponse(HttpStatus.NOT_FOUND.value(), e.getMessage());
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(error);
}
5. API 문서화
- Swagger/OpenAPI 활용
- API 문서화는 개발자들이 API를 쉽게 이해하고 사용할 수 있게 해줍니다. Swagger는 이를 위한 강력한 도구입니다.
@Configuration
public class OpenAPIConfig {
@Bean
public OpenAPI customOpenAPI() {
return new OpenAPI()
.info(new Info()
.title("Your API Title")
.version("1.0")
.description("Your API Description"));
}
}
이 설정으로 Swagger UI를 통해 API 문서를 자동으로 생성하고 테스트할 수 있습니다.
6. REST API 테스트
테스트는 API의 신뢰성을 보장하는 중요한 단계입니다.
6.1 단위 테스트
이 테스트는 특정 사용자 조회 API의 동작을 검증합니다.
@WebMvcTest(UserController.class)
class UserControllerTest {
@Autowired
private MockMvc mockMvc;
@Test
void getUserTest() throws Exception {
mockMvc.perform(get("/api/users/1"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.name").value("John"));
}
}
6.2 통합 테스트
이 통합 테스트는 실제 애플리케이션 컨텍스트에서 사용자 생성 API를 테스트합니다.
@SpringBootTest
class UserApiIntegrationTest {
@Autowired
private TestRestTemplate restTemplate;
@Test
void createUserTest() {
UserDto userDto = new UserDto("John", "john@example.com");
ResponseEntity<User> response = restTemplate.postForEntity("/api/users", userDto, User.class);
assertEquals(HttpStatus.CREATED, response.getStatusCode());
}
}
7. 보안 처리
REST API의 보안은 매우 중요합니다. Spring Security를 사용하여 인증과 권한 부여를 구현할 수 있습니다. JWT를 이용한 토큰 기반 인증도 사용됩니다.
- Spring Security와 JWT를 활용한 인증/인가 구현
- CORS 설정으로 크로스 오리진 요청 제어
8. API 버전 관리
API 버전 관리는 기존 클라이언트에 영향을 주지 않고 API를 발전시킬 수 있게 해줍니다. URI, 헤더, 파라미터 등을 통해 버전을 관리할 수 있습니다.
- URI 버전 관리: /api/v1/users
- 헤더 버전 관리: Accept: application/vnd.company.app-v1+json
9. 성능 최적화
캐싱, 페이징, N+1 문제 해결 등을 통해 API의 성능을 최적화할 수 있습니다. 특히 대량의 데이터를 다룰 때 이러한 최적화는 필수적입니다.
- 캐싱 전략: @Cacheable 어노테이션 활용
- 페이징 처리: Spring Data JPA의 Pageable 인터페이스 사용
- N+1 문제 해결: 적절한 fetch 전략과 쿼리 최적화
10. 모범 사례
REST API 설계 시 다음과 같은 모범 사례를 따르는 것이 좋습니다.
- URI 설계: 명확하고 직관적인 URI 설계
- HTTP 상태 코드: 적절한 상태 코드 사용 (200 OK, 201 Created, 204 No Content 등)
- 에러 처리: 일관된 에러 응답 형식 사용
- API 문서화: 충분한 API 문서화
'개발 이야기 > Spring' 카테고리의 다른 글
[Spring JPA] JPA란 ? (0) | 2025.01.18 |
---|---|
[Spring Boot / JWT] Spring Boot에서 JWT를 활용한 인증 시스템 구현 (0) | 2025.01.11 |
[Spring Boot] Maven과 Gradle의 차이점 (0) | 2024.12.22 |
[spring/ flutter] flutter를 활용해 Spring Boot 서버 화면을 웹뷰로 띄우기 [2/2] (5) | 2024.12.12 |
[spring/ flutter] flutter를 활용해 Spring Boot 서버 화면을 웹뷰로 띄우기 [1/2] (3) | 2024.11.11 |