Home > Today I Learned > 2026_06_TIL > 2026-06-11 일지

2026-06-11 일지
swagger CI/CD javascript

JS 비동기 통신 구축


비동기 통신이란?

비동기 통신은 요청을 보낸 후 응답이 올 때까지 기다리지 않고 다음 작업을 수행하는 통신 방식이다.

서론

JavaScript에서 비동기 통신을 위해 JQuery의 AJAX를 많이 사용했었다. AJAX(Asynchronous JavaScript And XML)는 페이지 전체를 새로고침하지 않고 서버와 데이터를 주고받을 수 있게 해주었다.
최근에는 JQuery 없이 Javascript 내장인 Fetch API를 주로 사용한다. Fetch API는 Promise 기반으로 동작하고 코드가 훨씬 직관적이라고 볼 수가 있다.

fetch_api

Promise

미래에 완료될 비동기 작업의 결과를 나타내는 객체이다. Promise는 다음 세 가지 상태(State)를 가진다.

  1. Pending : 아직 작업이 완료되지 않은 상태
  2. Fulfilled : 비동기 작업이 성공한 상태
  3. Rejected : 비동기 작업이 실패한 상태

코드에서의 js 사용

<!DOCTYPE html>
<html lang="en">
<head>
    <link href="https://cdn.jsdelivr.net/npm/daisyui@5" rel="stylesheet" type="text/css" />
    <script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
    <script th:src="@{~/js/global.js}"></script>
    <script th:src="@{~/js/api.js}"></script>
    <meta charset="UTF-8">
    <title>API 테스트</title>
</head>
<div class="card-actions justify-center mt-12">
                <button class="btn btn-soft" onclick="getPost()">GET</button>
                <button class="btn btn-soft btn-accent" onclick="post_body.showModal()">POST</button>
                <dialog id="post_body" class="modal">

-> index.html 일부

function getSequence() {
    return parseInt(window.localStorage.getItem(SEQUENCE_KEY));
}

function validate() {

    if ( getSequence() === 0 ) {
        alert('게시글을 먼저 작성해주시기 바랍니다');
        return false;
    }

    return true;

}

-> global.js 파일

이런 식으로 resources templates에 저장한 js 파일을 head에 미리 선언하는 것으로 관련 함수를 사용하는 것이 가능하다.
두번째 코드는 body 안에 기술한 html문으로 기존의 html코드 대신 js의 함수를 사용하도록 대체했다.

Swagger 도입


목적

swagger은 백엔드 개발자가 클라이언트 통신을 위해 API문서를 만들 때 도움을 받을 수 있는 프로그램이다. dependency로 쉽게 도입이 가능하고
직관적으로 각 엔드포인트에 따른 request, response를 보여줄 수가 있어서 쉽게 API문서로 제작하는 것이 가능하다.

첫걸음

 // Source: https://mvnrepository.com/artifact/org.springdoc/springdoc-openapi-starter-webmvc-ui
 implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.14'

mavenrepository에 springdoc openAPI를 검색하여 사용, spring boot 버전에 따라 지원해주는 것이 다르기 때문에 spring boot 4버전 이상은
3버전 이상을 사용하는 것이 가능하지만 3버전이라면 2.8.x 버전을 사용해주도록 하자.

springdoc:
  api-docs:
    enabled: true
    path: /v3/api-docs

  swagger-ui:
    enabled: true
    path: /v3/api-docs
    operations-sorter: alpha # method # alpha # method
    display-request-duration: true
    doc-expansion: list
    persist-authorization: true

application.yml 파일에 다음과 같은 코드를 추가해준다. 이중 operations-sorter은 API목록의 정렬 기준을 의미한다.
alpha는 URL경로 기준으로 알파벳 순서로 정렬, method는 HTTP Method 순서대로 정렬하는 것을 의미한다.

기본정보 추가

@Configuration
public class SwaggerConfiguration {
    @Bean
    public OpenAPI openAPI(){
        return new OpenAPI()
                .info(
                        new Info()
                                .title("상품 API")
                                .description("상품 관련된 API문서")
                                .version("0.0.1")
                );
    }
}

config와 같은 패키지에 다음 코드를 만들어 넣어주도록 하자. OpenAPI 객체는 Swagger문서의 기본정보를 추가하고 싶을 때 사용을 하게 된다.

테스트 데이터 추가

@Slf4j
@Component
@RequiredArgsConstructor
public class DataInit implements ApplicationRunner {

    private final ProductService service;
    
    @Override
    public void run(ApplicationArguments args) throws Exception {
        IntStream.rangeClosed(1, 20)
                .forEach( i -> {

                    ProductRequest request = new ProductRequest(
                            "상품명_%d".formatted(i),
                            "상품_설명_%d".formatted(i),
                            i * 10000L
                    );

                    service.save(request);

                });

    }
}

만약 더미데이터가 필요하다면 다음 코드를 사용하도록 하자. 그렇지만 운영서버에는 더미데이터가 들어가면 안되므로 환경을 어느정도 구축한 다음 할 필요가 있다.

Swagger 도입하기

public interface PostApiDocs {
    @Operation(
            summary = "게시글 작성",
            description = "게시글을 작성하기 위한  API",
            security = @SecurityRequirement(name = "bearerAuth")
    )
    @ApiResponse(
            responseCode = "201",
            description = "작성된 게시물에 대한 개략적 정보입니다.",
            content = {
                    @Content(
                            mediaType = "application/json",
                            schema = @Schema(
                                    implementation = PostDescription.class
                            )
                    )
            }
    )
    ResponseEntity<PostDescription> savePost(
            @RequestBody EditPostRequest request,
            Principal principal
    );
}

그냥 위 savePost는 Controller에 작성한 메서드이다. 하지만 위 @Operation, @ApiResponse의 내용을 넣는다면 너무 코드가 난잡해질 것이다.
따라서 인터페이스를 만들고 인터페이스에 @Operation, @ApiResponse에 들어갈 내용을 추가한다.

@Operation의 속성 설명

  • summary API : 한 줄 설명
  • description : API 상세 설명
  • tags : API 그룹 지정
  • operationId : API 고유 식별자
  • deprecated :API 사용 중단 여부

@ApiResponse의 속성 설명

  • responseCode : HTTP 상태 코드
  • description : 응답 설명
  • content : 응답 Body 타입
  • headers : 응답 Header 설명
public record PostDescription(

        @Schema(
            description = "게시물 제목",
            example="너무 멋진 게시글 제목 1"
        )
        String title,

        @Schema(
            description = "게시물 내용",
            example="너무 멋진 게시글 내용 1"
        )
        String content
){
    
}

record에서도 간단한 설명을 @Schema 안에 내용을 넣어서 swagger에 설명을 올리는 것이 가능하다.

CI/CD


서론

소프트웨어 개발에서 새로운 기능을 추가하거나 버그를 수정하면 개발자는 자신의 브랜치에서 작업한 코드를 메인 브랜치에 병합(Merge)하게 된다. 이러한 과정을 통합(Integration) 이라고 한다.
하지만 프로젝트 규모가 커질수록 통합은 매우 빈번하게 발생한다. 코드가 병합될 때마다 개발자가 직접 빌드를 수행하고, 테스트를 실행하고, 오류를 확인하는 과정은 많은 시간과 비용이 소모된다.
이를 위해 도입한 것이 CI , Continuous Integration 즉 지속적 통합이다. 빌드를 하고 테스트를 실행하는 것을 CI이다.
CD는 검증된 코드를 실제 운영 환경에 배포하는 단계라고 볼 수가 있다.

cicd-concept

CI

CI는 개발자가 코드를 병합할 때마다 자동으로 빌드와 테스트를 수행하여 코드 품질을 검증하는 개발 방법론이다.

예를 들어 GitHub에서 Pull Request(PR)를 생성하면 이벤트가 발생하고, CI 도구가 자동으로 프로젝트를 빌드하고 테스트를 실행한다.
빌드나 테스트가 실패하면 개발자는 즉시 문제를 확인할 수 있으며, 안정성이 검증된 코드만 메인 브랜치에 병합할 수 있다.

CD

배포라는 것이 있다. 영어로는 Deployment, 이 배포는 내가 만든 제품을 다른 사람이 이용하기 좋게 만들어 놓는 행위이다.
내가 만든 제품을 공개하는 행위라고 볼 수가 있다. cd는 지속적 배포(Continuous Deployment)와 지속적 배달(Continuous Delivery)의 두가지 개념을 갖고 있다고 볼 수가 있다.

CI/CD 도구예시

  1. Jenkins
    • 오픈소스
    • 높은 확장성
    • 기업에서 많이 사용
  2. GitHub Actions
    • GitHub 내장 컴퓨터를 사용
    • Script를 통해 실행
    • 설정이 간단
    • Pull Request 기반 자동화에 적합
  3. Travis CI
    • 오픈소스 프로젝트에서 많이 사용
    • 현재는 유료 정책 확대
  4. Bamboo
    • Atlassian에서 제공
    • Jira, Bitbucket과 연동이 강력