항해99

23.11.14 항해 99 16기 실전 프로젝트 36일차

김용글 2023. 11. 14. 21:37

오늘 공부한 것

* Swagger

* QueryDSL

* S3

* AWT

* TestContainer + LocalStack

 

1. Swagger

더보기

1) Swagger 란?

    Web API 문서화를 위한 도구

    Swagger 홈페이지에서는 Swagger 를 OAS(Open API Specification) 이라고 소개하고 있다

    즉, API 들이 가지는 명서(Spec) 을 관리하기 위한 프로젝트이다

 

2) 도입 이유

    개발 초기 단계에서 API 명세서를 일일이 문서화 작업을 하고 시작하였으나, 개발이 될 수록 아래와 같은

    문제가 발생했다

    (1) 지속적인 데이터 변경

    (2) 추가되는 API

    (3) 프론트와 협업

    기존에 작성된 API 명세서만 가지고 프론트팀과 백엔드팀이 협업을 진행하는 것이 효율적이지 않다는 판단이

    들었고 뚜렷하게 잘 정리된 API 명세서의 필요성을 느끼게 되어 협업 도구로 적용하기로 하였다

 

3) 기술결정

    (1) 선택지

          a) Swagger

               (a) API 문서를 자동으로 만들어주는 라이브러리

               (b) 어노테이션을 통해 생성된 API 를 문서내에서 parameter 조작을 통해서 바로 실행 가능

               (c) 장점

                     i. 테스트 코드를 작성하지 않아도 어토네이션을 통해 API 문서를 간단하게 작성가능

                        -> 어노테이션만 달면 자동으로 문서가 생성되기 때문에 RestDocs 와 비교하여 쉽게 문서화

                     ii. API 를 통해 parameter, 응답 정보, 예제 등 Spec 정보 전달 용이

                     iii. 실제로 사용되는 parameter 로 테스트 가능

               (d) 단점

                     i. 구현 코드에 Swagger 를 사용하기 위한 어노테이션 추가 필요

           b) Spring REST Docs

               (a) RESTful 서비스의 문서화를 도와주는 도구

               (b) Spring 테스트로 생성된 자동 생성 문서를 통해 API 실행

               (c) 장점

                     i. 구현 코드에 문서화를 위한 어노테이션을 작성하지 않아도됨

                     ii. 테스트 코드를 통해 문서화를 하기 때문에, 테스트코드 작성을 강제할 수 있음

               (d) 단점

                     i. 테스트 코드 작성시 문서화가 가능하기 때문에, 테스트코드 관리를 지속적으로 해줘야함

                        (단점이라기엔 애매)

                     ii. 문서에서 API 를 즉석으로 테스트할 수 없다

                     iii. 문서를 커스터마이징 하려면 AsciiDoc 문법을 알아야 한다

 

4) 갈래! 팀에서는 Swagger 를 사용

    (1) API call 을 직접할 수 있어 postman 을 통해 테스트를 할 필요가 없다

    (2) 프론트와의 협업에 더 직관적으로 알 수 있는 Swagger 가 좋다고 판단

    (3) 정해진 기간에 개발이 진행되야하므로 테스트코드가 필요한 Docs 보다 시간관리가 용이

    (4) 백엔드에서 추가된 API 를 미리 코드만 짜주면 자동 추가됨

    (5) 여러 데이터 들을 request 를 할 때, 형식을 맞춰주기 때문에 데이터 누락 가능성을 줄임

 

5) 어려웠던점

    (1) 사진 파일을 업로드하는 API 는 테스트시 직접 파일 탐색기를 통해 파일을 업로드 해야 하는데 사진 파일

         탐색기 접근이 어려웠다

    (2) requestBody 에 따옴표를 빼먹는 경우 postman 은 빨간 줄로 표시되어 실수한 부분을 알 수 있지만

         Swagger 는 잘못된 부분을 따로 알려주지 않는다

 

2. QueryDSL

더보기

1) 도입 이유

    게시글 작성 시 다른 테이블에 데이터까지 접근해서 조회하는 경우가 많이 발생, 그때마다 해당 테이블에 대한

    repository 에 접근하여 JPA 쿼리메서드로 조회를 하면 그만큼 hibernate 가 발생함

     -> 쿼리를 불러오는 것을 효율적으로 처리할 필요가 생김

    또한, 기존의 JPA 쿼리 메서드를 사용할 경우 해당 Entity 내에서만 접근하여서 조회할 수 있는 폭이 좁아지고

    작성한 메서드의 문법에 문제가 있으면 컴파일 이후에 확인이 되었다

 

2) 기술결정

    (1) 선택지

          a) QueryDSL

               (a) 정적 타입(컴파일 시 타입에 대한 정보를 결정)을 이용해서 SQL 과 같은 쿼리를 생성 할 수 있도록

                    해주는 오픈소스 프레임워크

               (b) SQL, JPQL 을 코드로 작성할 수 있도록 해주는 빌더 API

               (c) Entity 클래스와 매핑되는 QClass 객체를 사용해서 쿼리실행

                    * QClass : Entity 와 형태가 같은 Static Class

                                     QueryDSL 은 컴파일 단계에서 Entity 를 기분으로 QClass 를 생성한다

                                     JPA Annotation Processor 가 컴파일 시점에 작동해서 @Entity 등의 애너테이션을 찾아

                                     해당 파일을 분석하여 QClass 를 만듬

               (c) 장점

                     i. 오타 확률이 적어짐 -> 문자열이 아닌 코드를 통해 작성하기 때문

                     ii. 코드로 작성하기 때문에 컴파일 단계에서 오류를 빠르게 발견할 수 있다

                     iii. 객체 지향적인 개발 가능

                     iiii. 복잡한 쿼리나 동적 쿼리 작성 편리

                     iiii. 쿼리 작성시 제약 조건 등을 메서드 추출을 통해 재사용 가능

               (d) 단점

                     i. QueryDSL 의 추가적인 API 를 배우고 해당 API 를 사용하는 방법을 이해해야한다

                     ii. QueryDSL 은 자체 코드 생성을 통해 QClass 를 생성하는데 이 과정은 초기 설정과 유지보수가

                        필요할 수 있다

          b) JPQL

               (a) Entity 객체를 조회하는 객체지향 쿼리

               (b) 테이블을 대상으로 쿼리하는 것이 아니라 Entity 객체를 대상으로 쿼리함

               (c) JPA 에서 제공하는 메소드 호출만으로 섬세한 쿼리 작성이 어렵다는 문제에서 탄생함

               (d) 장점

                     i. 반환 유형을 지정할 수 있다

                     ii. 특수 유형의 DB(MySQL, Oracle)에 연결된 것이 아니기에 DB 변경시에도 유지, 보수 부분에서

                        유연하며 쿼리를 재작성 할 필요가 없다

               (e) 단점

                     i. 기본 문자열로 작성되기 때문에 컴파일시 에러를 발생하지 않는다

                        문제가 있음에도 불구하고 정상적으로 작동하여 배포시 문제가 발생 할 수 있다

                     ii. 동적으로 쿼리 언어를 작성하는데 효율적이지 못하다

                         예) 특정 조건이 참일 경우엔 A SQL 쿼리를, 거짓인 경우 B 쿼리를 실행하는 등

 

3) 갈래! 팀에서는 QueryDSL 을 사용

    (1) JPQL 사용시 다중 조건절 발생시 코드가 지저분해지면서 가독성이 떨어졌다

    (2) QueryDSL 은 다중 조건절을 BooleanExperssion 형식의 필드로 빼면서 쿼리 작성 코드가 간결해지고

         가독성이 높아졌다

    (3) 서브쿼리를 위한 유틸리티 클래스인 JPAExpressions 를 제공함으로써 JPA 쿼리 메서드로는 구현하기

         힘든 부분을 해결해주었다    

    (4) QClass 라는 Entity 클래스의 메타 정보를 담고 있는 클래스를통해 타입의 안정성을 보장해 주면서

         문법 오류시 바로 확인이 가능하여 수정이 용이했다

 

4) 어려웠던점

    (1) QueryDSL 은 자체 코드생성을 통해 QClass 를 생성하는데 초기설정과 유지보수가 조금 어려웠다

 

3. S3

더보기

1) 도입이유

    상세게시글 및 게시글에서의 사진 업로드 그리고 프로필 사진 업로드 기능이 필요했다

 

2) 기술결정

    (1) 선택지

          a) S3

               (a) Amazon 에서 제공하는 확장성, 데이터 가용성 및 보안과 성능을 제공하는 객체 스토리지 서비스

               (b) 많은 사용자가 접속해도 이를 감당하기 위한 시스템적인 작업을 하지 않아도 됨

               (c) 버전관리 기능을 통해 사용자에 의한 실수도 복원 가능

               (d) 장점

                     i. 저렴한 비용

                     ii. SSL을 통한 데이터 전송방식으로 보안성이 뛰어남

                         * SSL : 웹사이트와 브라우저 사이(또는 두 서버 사이)에 전송되는 데이터를 암호화 하여

                                     인터넷 연결을 보호하기 위한 표준기술

                     iii. 업로드 및 다운로드시 지역시간 최소화를 위한 멀티파트 업로드 지원

                     iv. 최소 1byte ~ 최대 5TB 의 데이터를 저장하고 서비스 할 수 있고 저장할 수 있는 파일 수의

                         제한이 없다

               (e) 단점

                     i. 스토로지가 객체를 내부 복제하는데에 시간이 조금 소요된다

          b) 파일업로드 로직 직접구현

               (a) 장점

                     i. 커스터마이징의 유연성

               (e) 단점

                     i. 구현에 시간이 오래걸림

 

3) 갈래! 팀에서는 S3 를 사용

    (1) S3 는 Java 에서 지원하는 Amazon AWS SDK 를 통해 쉽게 Java 프로그램과 연동이 가능했다.

    (2) putObject, deleteObject, getObject 등의 메서드로 쉽게 S3 저장소에 사진을 저장, 삭제, 조회가 가능했다

    (3) 개발자가 처움부터 모든 것을 구현할 필요없다는 점이 좋았다

 

 

4. AWT

더보기

1) 도입 이유

     사진을 업로드 전 사진의 사이즈를 재조정할 필요가 있었다

 

2) 기술결정

    (1) 선택지

          a) AWT

               (a) Java 의 기본라이브러리로 GUI 와 관련된 처리를 할 수 있도록 도와주는 라이브러리

                    * GUI : 사용자가 그래픽을 통해 하드웨어와 상호작용하는 환경

                                (윈도우, 스크롤바, 아이콘 이미지, 버튼등)

               (b) 장점

                     i. 컴포넌트를 추상화 함으로써 각 운영체제에서 구현하는 것이 편하다

                        * 컴포넌트 : 재사용이 가능한 각각의 독립된 모듈

               (c) 단점

                     i. 운영체제에 따른 미묘한 버그 발생

                     ii. 불규칙한 컴포넌트의 모양과 레이아웃 설정 문제 

          b) AWS Lambda

               (a) 클라우드 상에서 특정한 함수를 정의하고 해당 함수를 이벤트 트리거 방식으로 구동할 수 있게

                    해주는 서비스

               (b) AWS 에서 제공하는 서버리스 컴퓨터 플랫폼

                    * 서버리스 : 개발자가 서버의 존재를 신경 쓸 필요가 없음

               (c) 장점

                     i. 서버가 잘돌아가고 있는지 개수와 사양은 적당한지 등등 사용자는 신경쓸 필요가 없다

                     ii. 높은 가용성을 제공

               (d) 단점

                     i. 코드 용량이 최대 250MB 제한

                     ii. 함수 실행시간은 최대 15분 제한

                     iii. 비싼 가격

 

3) 갈래! 팀에서는 AWT 사용

    (1) AWS Lambda 사용시 본래 이미지를 원래 버킷에, 리사이징된 이미지를 별도의 버킷에 저장해야 하므로

         사진 데이터 관리가 복잡해짐 따라서, 서버에 불필요한 데이터를 저장하고 불필요한 HTTP 요청을

         한번 더 해야 함

    (2) 갈래! 는 단순히 크기만 조정하는 것이 주목적이기 때문에 처리 성능이 빠른 AWT를 활용

    (3) Java 이미지 관련 레퍼런스 역시 AWT 를 활용한 것이 가장 많아 참고하기 쉬운것도 매력적

 

4) 추후 보완하고 싶은 점

    (1) AWT 라이브러리를 사용하여 데이터 저장의 복잡성과 요청의 비효율은 줄었지만 리사이징된 해상도가

         약간 떨어지는 단점이 있었다. 이를 유지하는 방법을 모색했으면 좋겠다는 생각이 들었다

 

5. TestContainer + LocalStack

더보기

1) 도입 이유

    사진 기능 테스트 코드 작성시 실제 S3 를 사용하지 않고 가상의 방법으로 테스트하기 위해 도입

 

2) 기술결정

    (1) 선택지

          a) S3 Mock

               (a) S3 를 로컬에서 테스트 진행하기 위한 mock 서버

               (b) 장점

                     i. 구현이 쉽다

               (c) 단점

                     i. S3 클래스인 AmazoneS3Client 를 상속하면서 NullpointerException 에러가 나왔지만 답을

                        찾지 못함

          b) TestContainer 

               (a) 데이터베이스, 메시지브로커, 웹브라우저 또는 Docker 컨테이너에서 실행될 수 있는 모든 것에

                     대한 일회용 경량 인스턴스를 제공하기 위한 오픈 소스 프레임워크

               (b) 테스트 이전에 H2, MySQL 등 Docker Container 를 따로 띄우지 않아도 자동으로 테스트할 때

                     DB Container 를 띄워주고 테스트가 종료되면 같이 종료시켜주는 역활을 하는 라이브러리

               (b) 장점

                     i. Java 코드로 보다 오나벽한 테스트 코드 작성 가능

                     ii. 환경에 구애받지 않고 멱등성 있는 테스트 품질 향상

                         멱등성 : 동일한 요청을 한 번 보내는 것과 여러번 연속으로 보내는 것이 같은 효과를 지니고

                                       서버의 상태도 동일하게 남을 때

                     iii. 클라우드에서 동작하고 있는 Production 과 거의 동일한 테스트 환경 구축 가능

               (d) 단점

                     i. Restarted Lifesycle 을 이용해 독립적인 테스트 환경이 많아질 수록 시간이 오래걸릴 수 있다

                     ii. Docker Container 를 준비하고 실행하는데 시간이 조금 소요됨

          c) LocalStack

               (a) 로컬에서 테스트 할 수 있는 AWS 클라우드 환경 제공

               (b) 단독으로 실행 가능하며 AWS 서비스를 사용하는 어플리케이션을 쉽게 테스트 가능

               (c) AWS 에서 사용되는 서비스들을 대부분 지원하고 있고 Docker 를 사용해 손쉽게 실행 가능

  

3) 갈래! 팀에서는 TestContainer + LocalStack  사용

    (1) Docker 상의 가상환경에서 S3 에뮬레이션을 활용해 테스트 가능

    (2) TestContainer 로 가상환경을 만들고 LocalStack 이라는 이미지를 통해 AWS S3 기능을 흉내내어

          AWS S3 를 활용해 구현된 부분에 영향을 주거나 받지 않고 독립적으로 순수하게 테스트를 위해

         활용할 수 있었다

    (3) 구현방식이 비교적 복잡했지만 Docker 설정으로 문제없이 로컬환경에서 구현이 가능했고 AWS S3 서비스를

         건들이지 않고 테스트가 가능하다는 안정성이 있었다