REST API란?
REST API란?
REST API 제대로 이해하기 💪
REST API란?
REST API는 Representational State Transfer의 약자로, 자원(Resource) 중심의 API 설계 방식을 의미한다. 쉽게 말해, 서버의 데이터(자원)에 접근하는 규칙을 정해둔 표준이다.
🐥 REST의 핵심 원칙
- 클라이언트 - 서버 구조 (Client-Server Architecture)
- 클라이언트(프론트엔드)는 UI/UX를 담당하고, 서버(백엔드)는 데이터 저장 및 처리를 담당한다.
- 이렇게 역할이 분리되어야 유지보수와 확장성이 쉽다.
- 무상태성 (Stateless)
- 서버는 클라이언트의 상태(Session)를 보존하지 않는다.
- 요청마다 필요한 모든 정보를 담아서 보내야 한다.
- 캐시 가능성 (Cacheable)
- GET 요청 같은 경우는 캐시를 활용할 수 있다.
- 예를 들어, 정적 이미지나 자주 조회하는 목록 API는 캐싱하면 성능이 좋아진다.
- 계층화 (Layered System)
- 클라이언트는 서버가 직접 처리하는지, 다른 서버를 거치는지 알 필요가 없다.
- 보안, 로드밸런싱, 프록시 서버 등을 자유롭게 끼워 넣을 수 있다.
- 균일한 인터페이스 (Uniform Interface)
- 요청 방법이 일관되어야 한다.
- 예:
/users에서 GET은 사용자 목록 조회, POST는 사용자 생성 -> 직관적으로 이해 가능해야 한다.
✨ HTTP 메서드 활용
REST API는 HTTP 메서드로 행위를 표현한다.
- GET -> 자원 조회
- 예:
GET /users-> 사용자 목록 가져오기
- 예:
- POST -> 자원 생성
- 예:
POST /users-> 새로운 사용자 등록
- 예:
- PUT -> 자원 전체 수정 (덮어쓰기
- 예:
PUT /users/1-> ID가 1인 사용자의 정보를 전부 업데이트
- 예:
- PATCH -> 자원 일부 수정
- 예:
PATCH /users/1-> ID가 1인 사용자 이메일만 수정
- 예:
- DELETE -> 자원 삭제
- 예:
DELETE /users/1-> ID가 1인 사용자 삭제
- 예:
🥊 실무에서 주의할점
REST API는 이론만 알면 되는게 아니라, 실무에서 지켜야 할 규칙이 있다.
1. URL 설계
- 명사 사용: 동사가 아니라 자원(명사) 중심으로 작성해야 한다.
- 잘못된 예:
/getUser - 올바른 예:
/users
- 잘못된 예:
- 계층 구조 반영: 관계가 있으면 계층 구조로 표현한다.
- 예:
/users/1/orders-> ID가 1인 사용자의 주문 목록
- 예:
- 복수형 사용: 일반적으로 컬렉션 자원은 복수형으로 사용한다.
- 예:
/users(O),/user(X)
- 예:
2. 응답 코드 (Status Code)
- 클라이언트에게 상황을 정확히 알려주려면 HTTP 상태 코드를 올바르게 사용하는게 중요하다.
- 200 OK: 요청 성공 (조회, 수정 성공 시)
- 201 Created: 새로운 자원 생성 성공 (POST)
- 400 Bad Request: 요청이 잘못됨 (파라미터 오류 등)
- 404 Not Found: 요청한 자원이 없음
- 500 Internal Server Error: 서버 내부 오류
3. 버전 관리 API는 시간이 지나면서 변경 및 확장될 수 있다. 그래서 보통 버전을 명시한다.
- 예:
/api/v1/users,/api/v2/users - 이렇게 해두면 구버전을 사용하는 클라이언트도 안전하게 유지할 수 있다.
코드 예시
사용자(User) 엔티티를 대상으로 등록, 조회, 수정, 삭제를 구현하는 예시를 만들어보자.
1
2
3
4
5
6
7
8
9
10
11
12
@Entity
@Getter @Setter
@Table(name = "users")
public class User{
@Id
@GeneratedValue(strategy = GenerationType.IDENTIFY)
private Long id;
private String username;
private String email;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/users") // 버전 관리 포함
public class UserController{
private final UserService userService;
// CREATE
@PostMapping
public ResponseEntity<UserResponseDto> createUser(@RequestBody UserRequestDto userRequestDto){
UserResponseDto user = userService.createUser(userRequestDto);
return ResponseEntity.ok(user);
}
// READ
@GetMapping
public ResponseEntity<List<UserResponseDto>> getUsers(){
List<UserResponseDto> users = userService.getUsers();
return ResponseEntity.ok(users);
}
// READ (단일 조회)
@GetMapping("/{id}")
public ResponseEntity<UserResponseDto> getUser(@PathVariable Long id){
User user = userService.getUser(id);
if(user == null) throw new NotFoundUserException("사용자를 찾을 수 없습니다.");
return ResponseEntity.ok(user);
}
// UPDATE
@PatchMapping("/{id}")
public ResponseEntity<UserResponseDto> updateUser(@PathVariable Long id, @RequestBody UserRequestDto userRequestDto){
User updated = userService.updateUser(id, userRequestDto);
if(update == null) throw new NotFoundUserException("사용자를 찾을 수 없습니다");
return ResponseEntity.ok(updated);
}
// DELETE
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteUser(@PathVariable Long id){
userService.deleteUser(id);
return ResponseEntity.noContent().build();
}
}
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.