RESTful이란?
RESTful은 REST(Representational State Transfer) 아키텍처 스타일을 따르는 API를 의미합니다. REST는 HTTP 프로토콜을 기반으로 자원을 관리하는 방식이며, RESTful API는 이 원칙을 준수하여 설계된 API입니다.
REST의 주요 원칙
- 클라이언트-서버 구조
- 클라이언트와 서버는 서로 독립적으로 동작하며, 클라이언트는 서버의 자원을 요청하고 서버는 이를 처리하여 응답합니다.
- 무상태성 (Stateless)
- 서버는 클라이언트의 상태를 저장하지 않습니다. 모든 요청은 필요한 정보를 포함해야 하며, 세션 정보를 서버가 유지하지 않습니다.
- 캐시 가능 (Cacheable)
- HTTP 캐싱을 활용하여 성능을 개선할 수 있습니다.
- 계층적 시스템 (Layered System)
- 클라이언트는 중간 서버(예: 프록시, 로드 밸런서 등)의 존재를 알 필요 없이 API를 사용할 수 있습니다.
- 일관된 인터페이스 (Uniform Interface)
- URI(Uniform Resource Identifier)를 통해 자원을 명확히 식별하며, HTTP 메서드를 사용하여 해당 자원을 조작합니다.
RESTful API 설계 시 HTTP 메서드의 역할
HTTP |
메서드역할 |
예시 (URI) |
GET |
리소스 조회 |
GET /users (모든 사용자 조회) |
POST |
리소스 생성 |
POST /users (새 사용자 생성) |
PUT |
리소스 전체 수정 |
PUT /users/1 (ID가 1인 사용자 전체 수정) |
PATCH |
리소스 부분 수정 |
PATCH /users/1 (ID가 1인 사용자 일부 수정) |
DELETE |
리소스 삭제 |
DELETE /users/1 (ID가 1인 사용자 삭제) |
Spring Boot를 이용한 RESTful API 예제
1. Spring Boot 프로젝트 설정
Gradle 기반으로 프로젝트를 생성하고, 필요한 의존성을 추가합니다.
build.gradle:
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'com.h2database:h2'
}
2. 엔티티(Entity) 생성
사용자 정보를 저장하는 User 엔티티를 생성합니다.
package com.example.restfulapi.model;
import jakarta.persistence.*;
import lombok.*;
@Entity
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String email;
}
3. JPA Repository 생성
데이터베이스와 연결할 UserRepository를 작성합니다.
package com.example.restfulapi.repository;
import com.example.restfulapi.model.User;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User, Long> {
}
4. Controller 생성 (RESTful API 구현)
사용자 정보를 CRUD 할 수 있는 REST API 컨트롤러를 만듭니다.
package com.example.restfulapi.controller;
import com.example.restfulapi.model.User;
import com.example.restfulapi.repository.UserRepository;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/users")
public class UserController {
private final UserRepository userRepository;
public UserController(UserRepository userRepository) {
this.userRepository = userRepository;
}
// 1. 모든 사용자 조회 (GET /users)
@GetMapping
public List<User> getAllUsers() {
return userRepository.findAll();
}
// 2. 특정 사용자 조회 (GET /users/{id})
@GetMapping("/{id}")
public ResponseEntity<User> getUserById(@PathVariable Long id) {
return userRepository.findById(id)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
// 3. 사용자 추가 (POST /users)
@PostMapping
public User createUser(@RequestBody User user) {
return userRepository.save(user);
}
// 4. 사용자 수정 (PUT /users/{id})
@PutMapping("/{id}")
public ResponseEntity<User> updateUser(@PathVariable Long id, @RequestBody User updatedUser) {
return userRepository.findById(id)
.map(user -> {
user.setName(updatedUser.getName());
user.setEmail(updatedUser.getEmail());
userRepository.save(user);
return ResponseEntity.ok(user);
})
.orElse(ResponseEntity.notFound().build());
}
// 5. 사용자 삭제 (DELETE /users/{id})
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
return userRepository.findById(id)
.map(user -> {
userRepository.delete(user);
return ResponseEntity.noContent().build();
})
.orElse(ResponseEntity.notFound().build());
}
}
5. 실행 및 테스트
Spring Boot를 실행한 후, RESTful API를 테스트할 수 있습니다.
1. 사용자 추가
curl -X POST -H "Content-Type: application/json" -d '{"name": "홍길동", "email": "hong@example.com"}' http://localhost:8080/users
2. 모든 사용자 조회
curl -X GET http://localhost:8080/users
3. 특정 사용자 조회
curl -X GET http://localhost:8080/users/1
4. 사용자 수정
curl -X PUT -H "Content-Type: application/json" -d '{"name": "이순신", "email": "lee@example.com"}' http://localhost:8080/users/1
5. 사용자 삭제
curl -X DELETE http://localhost:8080/users/1
RESTful API를 만들 때 주의할 점
- URI는 자원을 나타내도록 설계 (/users/{id}처럼 의미 있는 경로 사용)
- HTTP 상태 코드 활용 (200 OK, 201 Created, 404 Not Found 등)
- JSON 형식으로 요청 및 응답 처리 (@RequestBody 사용)
- 예외 처리를 고려한 API 설계 (ResponseEntity 활용)