본문 바로가기

REST API 설계부터 Swagger 문서화까지: 실무 팁과 예제 총정리

by 애덤더미 2024. 11. 27.
반응형

안녕하세요! 오늘 포스팅은 REST API 설계, 문서화, 그리고 Swagger를 활용한 명세화까지, 실무에서 바로 써먹을 수 있는 내용들만 담아봤습니다. 팀원들과 협업할 때도 유용하고, 실제 프로젝트에 적용하기 좋은 팁들이니 끝까지 읽어보세요!

 

REST API 설계의 기본 원칙

1️⃣ 리소스 기반 설계

  • REST는 리소스(데이터)를 중심으로 설계해야 합니다.
  • URI는 명사와 복수형으로 작성하고, HTTP 메서드로 동작을 구분합니다.
메서드 동작 예시
GET 데이터 조회 /users
POST 데이터 생성 /users
PUT 데이터 수정 (전체) /users/{id}
DELETE 데이터 삭제 /users/{id}

 

2️⃣ 상태 코드와 에러 처리 표준화

상태 코드를 통해 클라이언트가 요청 결과를 명확히 이해할 수 있어야 합니다.

상태 코드 의미 사용 예시
200 성공 데이터 조회 성공
201 생성 완료 새 리소스 생성 성공
400 잘못된 요청 필수 필드 누락
401 인증 실패 Bearer Token 만료
404 리소스 없음 없는 ID 조회
500 서버 내부 오류 서버 에러 발생

 

팁: 401 응답 시, 액션 가이드를 포함하면 사용자 경험이 개선됩니다.

{
  "error": "Unauthorized",
  "message": "Access token is invalid or expired. Please log in again."
}

 

3️⃣ JWT와 Bearer Token을 활용한 인증

  • JWT(JSON Web Token): 클라이언트가 로그인하면 서버가 서명된 토큰을 발급합니다.
  • Bearer Token을 요청 헤더에 포함하여 인증을 처리합니다.

헤더 예제:

Authorization: Bearer <JWT 토큰>

 

JWT 구성:

  1. Header: 타입(JWT)과 해싱 알고리즘(예: HS256)
  2. Payload: 사용자 정보와 클레임(예: userId, exp)
  3. Signature: 서버 비밀키로 서명

JWT 활용 인증 흐름:

  1. 클라이언트가 로그인 → 서버가 JWT 발급
  2. 클라이언트가 요청 시 JWT 포함
  3. 서버가 JWT 검증 → 사용자 인증 처리

토큰 만료 시 응답 예제:

{
  "error": "Unauthorized",
  "message": "Access token expired. Please log in again."
}

 

에러 처리 및 로깅 가이드

에러 처리는 API의 신뢰도를 높이는 핵심입니다. 아래는 실무에서 사용할 수 있는 코드 예제와 에러 로그 작성 방법입니다.

1️⃣ Spring Boot로 에러 처리 구현 예제

@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(IllegalArgumentException.class)
    public ResponseEntity<ErrorResponse> handleBadRequest(IllegalArgumentException ex) {
        log.error("Bad Request Error: {}", ex.getMessage());
        return ResponseEntity.status(HttpStatus.BAD_REQUEST)
                .body(new ErrorResponse("INVALID_REQUEST", ex.getMessage()));
    }

    @ExceptionHandler(AuthenticationException.class)
    public ResponseEntity<ErrorResponse> handleUnauthorized(AuthenticationException ex) {
        log.error("Unauthorized Access: {}", ex.getMessage());
        return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
                .body(new ErrorResponse("UNAUTHORIZED", "Authentication failed"));
    }

    @ExceptionHandler(Exception.class)
    public ResponseEntity<ErrorResponse> handleServerError(Exception ex) {
        log.error("Internal Server Error: {}", ex.getMessage());
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body(new ErrorResponse("INTERNAL_ERROR", "An unexpected error occurred"));
    }
}

@Data
@AllArgsConstructor
class ErrorResponse {
    private String errorCode;
    private String message;
}

 

2️⃣ 중요한 로그 작성하기

에러 로그에 포함해야 할 내용:

  • 요청 URI, HTTP 메서드
  • 요청 본문 (민감 정보 제외)
  • 사용자 식별 정보 (ID 또는 IP)
  • 에러 메시지 및 스택 트레이스

로그 예제 (사용량 가상 태그 에러 처리):

log.error("Data collection failed. Resource: /virtual-tags, Method: GET, User: {}, Error: {}", 
          userId, ex.getMessage());

실무 예제: 사용자 관리 API

사용자 생성 (POST /users)

  • Request Body:
{
  "name": "John Doe",
  "email": "john.doe@example.com",
  "password": "securePassword123"
}
  • Response:
{
  "id": 1,
  "name": "John Doe",
  "email": "john.doe@example.com",
  "created_at": "2024-11-27T12:00:00Z"
}
  • 에러 응답 예제 (400 Bad Request):
{
  "errorCode": "INVALID_REQUEST",
  "message": "The 'email' field is required."
}

Swagger를 활용한 문서화

Swagger 문서화의 장점

  1. 자동화된 문서 작성
    코드 주석만으로 API 명세를 자동 생성할 수 있어 관리 부담이 줄어듭니다.
  2. API 테스트 환경 제공
    Swagger UI를 통해 HTTP 요청을 시뮬레이션하며 바로 테스트할 수 있습니다.
  3. 팀 협업 도구로 활용 가능
    백엔드와 프론트엔드 간 API 명세 공유와 동기화에 유용합니다.

Swagger 명세 작성 예제 (YAML)

openapi: 3.0.0
info:
  title: User Management API
  description: "This API manages user data, including creation, retrieval, and deletion."
  version: 1.0.0
servers:
  - url: https://api.example.com/v1
    description: Production server
paths:
  /users:
    get:
      summary: Get all users
      tags:
        - Users
      responses:
        '200':
          description: A list of users
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/User'
    post:
      summary: Create a new user
      tags:
        - Users
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UserCreateRequest'
      responses:
        '201':
          description: User created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
        '400':
          description: Invalid request data
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
components:
  schemas:
    User:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        email:
          type: string
    UserCreateRequest:
      type: object
      required:
        - name
        - email
      properties:
        name:
          type: string
        email:
          type: string
        password:
          type: string
          format: password
    ErrorResponse:
      type: object
      properties:
        errorCode:
          type: string
        message:
          type: string

현업에서 Swagger 활용 팁

1️⃣ Swagger와 Spring Boot 연동

Spring Boot에서 Swagger를 연동하려면 Springdoc OpenAPI 라이브러리를 사용하는 것이 좋습니다.

 

의존성 추가:

<dependency>
  <groupId>org.springdoc</groupId>
  <artifactId>springdoc-openapi-ui</artifactId>
  <version>1.6.15</version>
</dependency>

 

Gradle을 사용하는 경우 build.gradle에 다음 내용을 추가합니다.

implementation 'org.springdoc:springdoc-openapi-ui:1.6.15'

 

Swagger 설정 파일: Swagger 문서를 커스터마이징하려면 Springdoc의 OpenAPI 객체를 설정 파일로 구성합니다.

@Configuration
public class OpenAPIConfig {
    @Bean
    public OpenAPI customOpenAPI() {
        return new OpenAPI()
                .info(new Info()
                        .title("User Management API")
                        .version("1.0.0")
                        .description("API for managing users"))
                .servers(List.of(
                        new Server().url("https://api.example.com").description("Production Server"),
                        new Server().url("https://staging.api.example.com").description("Staging Server")));
    }
}

 

실행 및 확인 방법

1. 애플리케이션 실행
Spring Boot 애플리케이션을 실행합니다.

mvn spring-boot:run

 

또는 IDE에서 main 메서드를 실행합니다.

 

2. Swagger UI 접속
브라우저에서 아래 URL로 Swagger UI에 접속합니다.

  • 기본 URL: http://localhost:8080/swagger-ui/index.html

3. Swagger UI 테스트

  • API 명세를 확인하고, Try it out 버튼으로 실제 요청을 실행합니다.
  • 요청/응답 결과와 상태 코드를 실시간으로 확인할 수 있습니다.

4. Swagger JSON 확인 (선택 사항)

  • JSON 명세 확인: http://localhost:8080/v3/api-docs
  • 이 파일은 클라이언트 코드 생성 및 API 관리 도구와 연동할 때 사용됩니다.

 

※ Swagger 설정 추가 팁

1. Swagger UI 경로 변경
Swagger UI의 기본 경로를 변경하려면 다음 설정을 추가합니다.

springdoc:
  swagger-ui:
    path: /custom-swagger-ui

이후, http://localhost:8080/custom-swagger-ui 로 접근합니다.

 

2. 프로파일 별 Swagger 활성화
운영 환경에서 Swagger UI를 비활성화하려면 application.yml 에 조건을 추가합니다.

springdoc:
  swagger-ui:
    enabled: ${SWAGGER_ENABLED:true}
  • 운영 환경에서 SWAGGER_ENABLED=false 로 설정하면 UI가 비활성화됩니다.

 

이 과정을 통해 Swagger 설정 파일을 작성하고, 실제로 API 문서를 확인하며 테스트할 수 있습니다 :)

반응형