2025-06-10

REST API 설계 & 문서화

REST APISpringSwaggerOpenAPIAPI 설계

REST API 설계 & 문서화

웹 애플리케이션이 성장할수록 "일관성 있는 API 설계"와 "명확한 문서화"는 유지보수성과 확장성의 핵심입니다. 이 포스트는 RESTful URI 설계 원칙, 응답 형태 통일, Swagger/OpenAPI 사용법을 다룹니다.


1. RESTful한 URI 설계 원칙

1-1. 리소스(resource) 중심 설계

  • URI는 행위(동사)가 아니라 명사(리소스)로 표현
  • 예: /orders (주문 목록), /orders/{orderId} (특정 주문)

1-2. HTTP 메서드 활용

| 메서드 | 의미 | 예시 | |--------|------|------| | GET | 조회(Read) | GET /users, GET /users/123 | | POST | 생성(Create) | POST /users | | PUT | 전체 갱신 | PUT /users/123 | | PATCH | 부분 갱신 | PATCH /users/123 | | DELETE | 삭제(Delete) | DELETE /users/123 |

1-3. 계층적 네이밍

  • 관계가 있는 리소스는 하위 경로로 표현
  • 예: /users/{userId}/orders (특정 사용자의 주문)

1-4. 쿼리 파라미터로 필터링/페이징

  • 검색·정렬·페이징 용도로 사용
  • 예: GET /products?category=electronics&page=2&size=20&sort=price,asc

2. 응답 형태 통일 (ResponseEntity & 공통 응답 포맷)

2-1. 공통 응답 포맷 설계

public class ApiResponse<T> {
    private boolean success;
    private String message;
    private T data;
    // 생성자, 게터/세터 생략
}
  • success: 요청 처리 성공 여부
  • message: 실패 시 사용자에게 전달할 설명
  • data: 실제 페이로드

2-2. ResponseEntity로 상태 코드 제어

@RestController
@RequestMapping("/api/users")
public class UserController {
 
    @GetMapping("/{id}")
    public ResponseEntity<ApiResponse<UserDto>> getUser(@PathVariable Long id) {
        UserDto user = userService.findById(id);
        ApiResponse<UserDto> resp = new ApiResponse<>(true, "조회 성공", user);
        return ResponseEntity.ok(resp);
    }
 
    @PostMapping
    public ResponseEntity<ApiResponse<Void>> createUser(@RequestBody UserDto dto) {
        userService.create(dto);
        ApiResponse<Void> resp = new ApiResponse<>(true, "생성 성공", null);
        return ResponseEntity.status(HttpStatus.CREATED).body(resp);
    }
}

2-3. 상태 코드 & 메시지 매핑

| 상황 | HTTP 상태 코드 | 메시지 | |------|----------------|--------| | 정상 조회 | 200 OK | "조회 성공" | | 정상 생성 | 201 Created | "생성 성공" | | 잘못된 요청(Validation) | 400 Bad Request | "입력값을 확인해주세요" | | 권한 없음 | 401 Unauthorized | "인증이 필요합니다" | | 리소스 없음 | 404 Not Found | "존재하지 않는 리소스입니다" | | 서버 오류 | 500 Internal Server Error | "서버에 오류가 발생했습니다" |


3. Swagger/OpenAPI 사용법

3-1. 의의

  • API 명세를 코드 주석에서 자동 생성
  • 팀 내·외부에 실시간 문서 제공

3-2. Springdoc-openapi 설정

<!-- pom.xml -->
<dependency>
  <groupId>org.springdoc</groupId>
  <artifactId>springdoc-openapi-ui</artifactId>
  <version>1.6.14</version>
</dependency>

메인 클래스에는 별도 설정 불필요:

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

3-3. 컨트롤러에 어노테이션 추가

@RestController
@RequestMapping("/api/orders")
@Tag(name = "Order API", description = "주문 관련 API")
public class OrderController {
 
    @Operation(summary = "주문 목록 조회",
               description = "모든 주문을 페이징 조회합니다.")
    @ApiResponses({
        @ApiResponse(responseCode = "200", description = "조회 성공",
            content = @Content(schema = @Schema(implementation = ApiResponse.class)))
    })
    @GetMapping
    public ApiResponse<List<OrderDto>> listOrders(
        @Parameter(description = "페이지 번호", example = "0")
        @RequestParam int page,
        @Parameter(description = "페이지 크기", example = "20")
        @RequestParam int size) {
        // ...
    }
}

3-4. 문서 확인

  • 실행 후 http://localhost:8080/swagger-ui.html 또는 /swagger-ui/index.html 접속
  • 작성한 설명과 스키마가 자동으로 반영됨

마무리

REST API는 "일관된 URI", "통일된 응답 포맷", "명확한 문서화"를 통해 협업과 유지보수 효율을 극대화할 수 있습니다.

  • 리소스 중심의 URI → 직관적인 API
  • ApiResponse + ResponseEntity → 상태 코드와 메시지의 일관성
  • Swagger/OpenAPI → 실시간 문서화로 빠른 커뮤니케이션