Notice
Recent Posts
Recent Comments
Link
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |
Tags
- 백엔드 부트캠프
- 객체지향
- Be
- 오픈패스
- OPENPATH
- 내일배움카드
- UXUIPrimary
- 디자인챌린지
- 티스토리챌린지
- 백준
- 디자인강의
- Spring
- UXUI챌린지
- 국비지원취업
- 오픈챌린지
- 오블완
- 환급챌린지
- 백엔드개발자
- 패스트캠퍼스
- Java
- 국비지원
- 자바
- mysql
- JPA
- baekjoon
- 부트캠프
- 디자인교육
- UXUI기초정복
- 국비지원교육
- KDT
Archives
- Today
- Total
군만두의 IT 개발 일지
[스터디13] 03. API 명세 및 구현 본문
목차
3장. API 명세 및 구현
3.1 OAS로 API 설계
- 프로그래밍 시에는 설계 우선(design-first) 접근 방식을 사용해야 한다.
- OAS는 REST API의 명세와 설명을 해결하기 위해 도입되었다.
- YAML(YAML Ain't Markup Language) 또는 JSON(JavaScript Object Notation) 형식으로 REST API를 작성할 수 있다.
- OAS는 Swagger 명세에 많이 쓰이게 되면서 널리 알려졌다.
Swagger 도구
- Swagger Editor: REST API를 설계 및 설명 작성
- Swagger Codegen: Spring 기반 API 인터페이스 생성
- Swagger UI: REST API 문서 생성
3.2 OAS 기본 구조 이해
OAS의 메타데이터 절
- openapi: 시맨틱 버전 관리를 사용하며, 버전이 major.minor.patch 형식이다.
- info: API에 대한 메타데이터가 포함되며, title과 version만 필수 필드다.
- externalDocs: 노출된 API의 확장 문서를 가리키는 선택적 필드다.
openapi: 3.0.3
info:
title: 샘플 전자 상거래 앱
description: '이것은 ***샘플 전자 상거래 앱***이다.'
termsOfService: https://github.com/LICENSE
contact:
email: support@packtpub.com
license:
name: MIT
url: https://github.com/LICENSE
version: 1.0.0
externalDocs:
description: API와 함께 생성하고자 하는 문서 링크.
url: http://swagger.io
OAS의 servers와 tags 절
- servers: API를 호스팅하는 서버 목록을 가지는 선택적 항목이다.
- tags: 리소스에서 수행되는 작업을 그룹화하는 데 사용된다.
OAS의 경로(path) 절
- paths: 엔드포인트를 정의한다.
- 엔드포인트 경로에는 연결된 HTTP 메서드가 있으며, 각 메서드는 필드(tags, summary, description, operationId, parameters, responses, requestBody)를 가질 수 있다.
OAS의 components 절
- components: 재사용 가능한 스키마, 요청 본문, 응답 등을 정의한다.
- 기본 데이터 타입(string, number, integer, boolean, object, array)을 지원한다.
3.3 OAS를 스프링 코드로 변환
Swagger 플러그인을 사용하여 API 정의로부터 코드를 생성한다.
코드 생성 단계
- Gradle 플러그인 추가
- 코드 생성을 위한 OpenAPI config 정의
- OpenAPI 생성기 ignore 파일 정의
- openapi.yaml에서 OAS 파일 복사해서 /src/main/resources/api에 넣기
- Gradle 빌드 파일에서 swaggerSources 태스크 정의
- compileJava 작업 의존성에 swaggerSources 추가
- 생성된 소스 코드를 Gradle sourceSets에 추가
- 빌드 실행
3.4 OAS 코드 인터페이스 구현
생성된 API 인터페이스를 구현하여 비즈니스 로직을 작성한다. Swagger Codegen은 제공된 각 태그에 대한 API 인터페이스를 생성한다.
@RestController
public class CartsController implements CartApi {
private static final Logger log = LoggerFactory.getLogger(CartsController.class);
@Override
public ResponseEntity<List<Item>> addCartItemsByCustomerId(
String customerId, @Valid Item item) {
log.info("고객 ID 요청: {}\nItem: {}", customerId, item);
return ok(Collections.EMPTY_LIST);
}
@Override
public ResponseEntity<List<Cart>> getCartByCustomerId(String customerId) {
throw new RuntimeException("수동 예외 발생 (Manual Exception thrown)");
}
}
3.5 전역 예외 처리기 추가
여러 컨트롤러와 메서드에서 발생하는 예외를 중앙에서 처리하기 위해 전역 예외 처리기를 구현한다.
- @ControllerAdvice: REST 컨트롤러의 모든 요청 및 응답 처리를 추적한다.
- @ExceptionHandler: 특정 예외를 처리하는 메서드를 정의한다.
Error 모델 정의
public class Error {
private static final long serialVersionUID = 1L;
private String errorCode; // HTTP 오류 코드와 다른 애플리케이션 오류 코드
private String message; // 문제에 대한 요약
private Integer status; // 문제 발생 시 서버에 설정된 HTTP 상태 코드
private String url = "Not available"; // 오류를 발생시킨 요청의 URL
private String reqMethod = "Not available"; // 오류를 발생시킨 요청의 메서드
// getter와 setter 생략
}
전역 예외 처리기 구현
@ControllerAdvice
public class RestApiErrorHandler {
private final MessageSource messageSource;
@Autowired
public RestApiErrorHandler(MessageSource messageSource) {
this.messageSource = messageSource;
}
@ExceptionHandler(Exception.class)
public ResponseEntity<Error> handleException(
HttpServletRequest request, Exception ex, Locale locale) {
Error error = ErrorUtils.createError(
ErrorCode.GENERIC_ERROR.getErrMsgKey(),
ErrorCode.GENERIC_ERROR.getErrCode(),
HttpStatus.INTERNAL_SERVER_ERROR.value())
.setUrl(request.getRequestURL().toString())
.setReqMethod(request.getMethod());
return new ResponseEntity<>(error, HttpStatus.INTERNAL_SERVER_ERROR);
}
@ExceptionHandler(HttpMediaTypeNotSupportedException.class)
public ResponseEntity<Error> handleHttpMediaTypeNotSupportedException(
HttpServletRequest request,
HttpMediaTypeNotSupportedException ex, Locale locale) {
Error error = ErrorUtils.createError(
ErrorCode.HTTP_MEDIATYPE_NOT_SUPPORTED.getErrMsgKey(),
ErrorCode.HTTP_MEDIATYPE_NOT_SUPPORTED.getErrCode(),
HttpStatus.UNSUPPORTED_MEDIA_TYPE.value())
.setUrl(request.getRequestURL().toString())
.setReqMethod(request.getMethod());
return new ResponseEntity<>(error, HttpStatus.UNSUPPORTED_MEDIA_TYPE);
}
// 생략
}
3.6 API 구현 테스트
빌드 완료 후 curl 명령을 사용하여 API를 테스트할 수 있다.
# 빌드 및 실행
$ gradlew clean build
$ java -jar build/libs/Chapter03-0.0.1-SNAPSHOT.jar
# XML 응답 요청
$ curl --request GET 'http://localhost:8080/api/v1/carts/1' \
--header 'Accept: application/xml'
# JSON 응답 요청
$ curl --request GET 'http://localhost:8080/api/v1/carts/1' \
--header 'Accept: application/json'
# 장바구니에 아이템 추가
$ curl --request POST 'http://localhost:8080/api/v1/carts/1/items' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data-raw '{
"id": "1",
"quantity": 1,
"unitPrice": 2.5
}'

이 글은 『스프링 6와 스프링 부트 3로 배우는 모던 API 개발』 책의 내용을 바탕으로 작성되었습니다.
'학습일지' 카테고리의 다른 글
| [스터디13] 02. 스프링의 개념과 REST API (0) | 2025.12.22 |
|---|---|
| [스터디13] 01. RESTful 웹 서비스 기본사항 (0) | 2025.12.16 |
Comments