60.5 시간 짜리 아이폰 앱 만드는 강의인데 오늘부터 듣는다.

아이폰 앱 만드는 강의

 

강사가 유데미에서는 꽤 유명한 편이라고 한다.

 

강의 들으면 25개의 ios 앱 개발 포트폴리오가 생겨서 이걸로 취준을 할 수 있다가 강의 취지인데, 나는 취미로 앱개발하고 싶어서 듣는다. 강의료는 17,000원이다. 영국 발음의 언니가 나와서 설명해주는데 런던에 사신다고 한다. 

완전 초보를 대상으로 하는 강의이기에 나한테는 제격인거 같다. 디자인이랑 앱 출시하는것 까지 강의 내용에 포함이 된다. 

하루에 3시간이라고 해도 20일걸린다.

 

한달 잡고 다 듣는게 목표.

 

macOS 최신 버전이 필요하다

xCode가 애플에서 제공하는 iOS 앱 만드는 앱인데 최신 OS에서 설치가 가능하다.

여기서부터 강의 수강 딜레이가 시작된다.

 

엄청 오래걸린다.

강의는 4년전꺼라 최신화 한다고는 하지만 Big Sur 11버전 이상이면 된다고 했다. 하지만 2024년은 그걸 허락하지 않았다.

그리고 스타벅스 와이파이는 느렸다.

 

집으로 돌아와서 내 인생 첫 앱을 완성했다.

 

인생 첫 앱 만들기

 

단순히 display를 보여주는 앱인데 simulator를 사용해서도 열 수 있고 내 아이폰과 연결해서 직접 다운로드 받아서 열 수도 있다.

 

 

 




주요 주제


- 주문 시스템의 독특한 특징과 고민
- 시스템의 장애와 대응 방안
- 어플리케이션 샤딩과 데이터 분산 저장 방식의 효과적인 구현 방안
- 대용량 데이터 조회 성능 개선 방안 모색
- 주문 시스템의 도메인 라이프 사이클 분석 및 개선
- 어플리케이션 샤딩 적용을 위한 데이터 정리 및 단일화

 


요약

 


배달의 민족 주문 시스템
- 배달의 민족 주문 시스템을 만들면서 여러 시행착오를 겪었고 그 안에서 굉장히 많이 성장을 해왔음
- 그 경험했던 시행착오들을 여러분들에게 공유드리고 싶어서 이 자리에 서게 되었음
- 배달의 민족 주문 시스템이 어떤 고민을 하면서 만들고 있는지, 성장 통제를 어떻게 극복해 나가면서 시스템이 진화해 나가는지를 말씀드리는 것임

음식 주문 시스템의 특징
- 주문 시스템은 다른 커머스 도메인과 다르게 독특한 특징을 가지고 있음
- 커머스 도메인의 특성과 음식 주문이라는 독특한 도메인의 특성을 고민하면서 시스템을 개발해 나가고 있음
- 마이크로 서비스 아키텍처를 추구하면서 어떻게 하면 시스템들 간에 잘 정리가 되면서 통신을 할 수 있을지 그런 부분을 고민하면서 개발하고 있음
- 대규모 트랜잭션을 안정적으로 처리하기 위해 많은 고민을 하면서 개발하고 있음

대용량 데이터의 조회 성능 개선
- 시스템이 장애가 나게 되면 전체 시스템에 장애가 이어지면서 베딩 서비스 자체가 유통이 되는 크리티컬한 이슈를 가지고 있음
- 대용량 데이터에 대해서 조회 성능이 계속 나빠지는 부분을 어떻게 해소해 나가는지 말씀드릴 것임
- 대규모 트렌드 션 계속 주문 수가 증가하면서 쓰기 처리 장비가 공간 쓰기 처리나 하계치에 도달하는 이슈가 많아짐
- msa로 아키텍처를 전환해 나가다 보니 무분별한 이벤트 발행으로 유실되는 이벤트도 많아지고 서비스의 흐름을 파악하기 어려워지는 아키텍처가 자성을 높아지게 되는데 이런 부분을 어떻게 개선해 나갔는지까지 소개해 드리면서 발표를 마무리해보도록 하겠음

주문 도메인 라이프 사이클
- 주문 인터널 api 서버는 주문 내역이나 기타 주문 정보가 필요한 서비스들에 주문 정보를 조회할 수 있는 데이터를 제공해 주는 ai 서버임
- 주문 내역 상세를 보여주기 위해서는 많은 정보가 필요함
- 주문 내역 상세를 보여주기 위한 api 리스턴스가 우측에 보이는 제이슨 스탭인데 방대한 양의 데이터를 조회해서 보여줘야 함
- 정규화를 해서 해결하기로 함
- 주문 도메인의 생명줄은 주문 생성, 접수 완료, 취소라는 크게 주문 도메인 라이프 사이클을 가지고 있음
- 주문 도메인 라이프 사이클 안에서만 도메인의 변경이 발생함
- 도메인 이벤트가 발행되게 되면 주문 이벤트 처리기 애플리케이션에서 데이터를 동기화해서 데이터 동기화를 이루어낼 수 있음

샤딩 전략
- 분산 처리에서 유통을 분산시켜보자고 설계를 하게 됨
- 오로라 장비는 엔진이 샤딩을 지원하지 않는 엔진이어서 해결이 될 수 없었음
- 어플리케이션 사진을 구현하기 위해서는 데이터를 저장할 때 어떤 카드의 데이터를 저장할지 결정하는 차진 전략에 대한 고민이 필요했고 두 번째로는 저장된 데이터를 어떻게 조회해 와서 시간 순서대로 잘 나열해서 제공해 드릴 수 있을지 데이터를 다시 애그리게이터 하는데 어떻게 해야 될지 하는 크게 두 가지 기능이 필요했음
- 샤딩 전략을 어떤 걸 사용할까 고민을 해봤는데 리서칭한 전략은 크게 세 가지였음
- 키 베이스드 샤딩은 해시 펑션을 통해서 데이터를 고르게 균등하게 내보낼 수 있는 장점이 있음
- 레인지 베이스 샤딩은 특정 값의 렌즈를 통해서 샤드를 결정하면 되기 때문에 구현이 매우 간단하다는 장점을 가지고 있음

주문 시스템의 특징
- 주문 시스템의 특징은 배달의 민족 서비스 특성상 음식 주문이 제대로 일어나지 않으면 대 서비스 자체가 장애라고 예측하는 고객분들이 많은 특징을 가지고 있음
- 주문 시스템은 정책상 최대 30일까지만 주문 취소가 가능해서 데이터의 변경이 최대 30일까지만 가능하며, 음식 주문의 특성상 대부분의 주문은 하루 내에 배달 완료가 돼서 처리가 되기 때문에 데이터가 완결되는 시간은 대체로 하루 내에 스냅샵 형태로 데이터가 바뀜
- 저희는 단일 장애 포인트를 피해서 최대한 시스템에 장애가 가지 않게끔 하자라는 전략을 취함
- 동적 데이터는 길어야 30일 대부분은 하루 내에 완결이 되기 때문에 스타드의 추가는 많이 일어나지 않아도 될 것이며, 차드의 추가가 일어난다 해도 최대 30일이 지나면 대리권은 결국에는 균등하게 붕괴될 것이다라는 결론을 내리게 됨

어플리케이션 샤딩
- 샵의 디터 키는 샵의 키가 어느 샷으로 가라는 걸 매핑해 놓은 매핑 클래스임
- 서비스 레이에서 사드가 어떤 차드로 반환하기로 결정하였고 이를 스레드 로퍼에 저장하는 것까지 해서 에스펙트 j의 동작은 무리되게 됨
- 에스트래픽 라우팅 데이터 소스에서 디디터밍 커런트 로버피라는 메소드를 오버라이즈 해서 미리 저장해놨던 사드 보도기를 3d 오터에서 가져오게 되고 이를 통해서 데이터 소스를 결정하게끔 구현을 해놓게 되었음
- 어플리케이션 샤딩을 적용하면서 쓰기 오천이 증가하는 부분에 대해서 똑같은 ha 구성을 앰버에 가져가면서 스케일 아웃으로 데이터를 고르게 분산시켜서 저장을 하면서 요청을 분산시키며 대응이 가능한 구조를 갖추겠음

도메인 로직과 서비스 로직의 분리
- 어플리케이션 이벤트를 통해 도메인 로직과 서비스 로직을 분리하는 것이 어려움
- 이를 해결하기 위해 내부 데이터와 외부 데이터를 정리함

이벤트 발행 실패 시 서비스의 일관성
- 이벤트 처리의 주체를 단일화함으로써 서비스 로직을 한 곳에서 관리하고자 하는 니즈가 더 컸음
- 도메인 로직과 서비스 로직 모두 실패했을 때 서비스의 일관성을 가져갈 수 있음
- 도메인 로직이 수행돼도 핸드실 커니 때 이후에 이벤트 발행이 실패될 경우에는 도메인 로직은 성공했지만 서비스 로직은 실패하면서 서비스의 일관성을 합치는 경험을 줄 수 있음
- 이벤트 발행이 실패가 되더라도 트랜잭션 커밋이 되면서 아웃바우스 ntt의 데이터 페이보드가 저장이 돼 있었기 때문에 이벤트 유
발생했을 때 다시금 이 아홉마팬티를 통해서 재발행이 가능하게 설계가 가능하게 됨


---------

추천시스템

주요 주제
- 추천 시스템 팀의 구성과 업무 수행 방식
- 데이터 전달 방식과 의존성 관리
- 실시간 데이터 추천 서비스를 위한 필요 사항과 구현 방법


다음 할 일
- 데이터 수집 및 처리 방법 검토


요약
추천 시스템 팀의 성장
- 추천 시스템 팀이 대외적인 공간에서 기술적인 내용을 공유하고 소개하는 것은 처음임
- 추천 시스템 팀이 어떻게 성장했는지 공유하고 배운 교훈들을 공유할 것임

추천 시스템 팀의 고객
- 추천 시스템 팀은 추천이라는 단 하나의 목적을 위해 만들어진 목적 조직임
- 데이터 사이언티스트와 데이터 엔지니어 그리고 dpm 이렇게 세 직군으로 구성되어 있음
- 추천 시스템 팀의 데이터 엔지니어에게는 두 부류의 고객이 있음
- 첫 번째 고객은 데이터 사이언티스트임

추천 시스템의 개발 과정
- 추천 시스템 팀의 데이터 엔지니어는 머신러닝 코드도 보고, api 서버도 개발하고, 데이터 파이 파일도 만들고, 추천과 관련된 모든 업무를 수행하고 있음
- 추천 서비스가 실제로 어떤 과정을 통해 만들어지는지 함께 살펴봄
- 추천 머신러닝 하면 빠지지 않고 등장하는 그림임
- 데이터를 가져와서 저처리하고 모델을 학습하고 평가하고 배포한 다음에 피드백을 받아서 끊임없이 개선하는 과정임
- 머신러닝 서비스를 개발하기 위해서는 필요함
- 학습과 예측을 어떻게 구성하느냐에 따라서 전체적인 시스템의 모습이 달라짐

오프라인 추첨 방식
- 오프라인 추첨 방식은 미리 추첨 결과를 뽑아서 저장해 놓는 방식을 오프라인 추첨 오프라인 예측 방식이라고 부르고 있음
- 학습 후 온라인 예측 방식은 사용자가 장바구니에 어떤 상품을 담았을 때 그 상품과 함께 어울릴 만한 상품을 추천해 주는 서비스임
- 온라인 예측을 위해서는 모델뿐만 아니라 모델에 함께 전달할 피처 데이터도 필요함

데이터베이스의 의존성
- 데이터를 데이터베이스에 올려줌으로써 추천을 전달할 수 있음
- 데이터 전달 방식은 두 가지 의존성을 불러옴
- api를 통해 주고받자 그리고 꼭 필요한 정보만 주고받자는 정책도 의존성을 줄이는 데 매우 큰 영향을 미쳤음

에어플로우의 단점
- 에어플로우에서 모델 학습 테스크를 수행하면 gpu 서버에 베이 콘다 가상 환경에서 활성 파일이 실행되는 시기였음
- 에어플로우에 ssh 오퍼레이터를 사용해서 gpu 서버로 명령어를 날림
- 에어플로우의 단점은 학습 안정성이 떨어지고 의존성 관리가 어렵다는 것임
- 데이터센터의 쿠버네티스 환경을 구축해서 학습 환경을 컨테이너 기반으로 전환함

코네틱스 환경의 실시간 서비스
- 하이퍼 파라미터 튜닝, 벡터 서시, 대용량 데이터 분산 처리 등 새로운 서비스가 보이면 빠르게 셋업해서 테스트해보는 게 중요함
- 코네틱스 환경에서 사용하기 쉬운 형태로 제공이 됨
- 실시간이라는 단어를 잘 살펴볼 필요가 있는데 다 같은 실시간이 아니기 때문임

실시간 데이터 수집
- 장바구니에 담은 상품 등을 추천 서비스에 녹여내면 완전히 새로운 서비스를 만들어낼 수 있음
- 실시간성 데이터를 추천 서비스에 잘 녹여내기 위해서는 실시간 정보를 함께 전달받는 것이 가장 간단한 방법임
- 실시간 데이터를 얻기 위해서 추가로 뭔가를 개발할 필요가 없음
- 모델 혹은 서비스의 요구 사항이 바뀔 수 있음
- 실시간 데이터를 수집하고 전달한다는 것 자체가 앞쪽 서버에게 부담이 될 수 있음

데이터 플랫폼 팀의 ups
- 데이터 플랫폼 팀의 ups에 올라탈까 아니면 우리가 직접 셋업해서 사용할까 두 가지 선택지가 있는데 여러분들이라면 어떤 선택을 할 것 같으신지 물어봄
- 데이터 플랫폼 팀도 일이 바쁘신데 우리의 요구 사항을 다 맞춰주실 수 있을까 또는 새벽에 갑자기 문제가 생기면 데이터 플랫폼 팀에서 빠르게 대응을 해 주실 수 있을까 걱정이 됨

sql 자동 포맷팅
- 목표가 명확해야 함
- sql 자동 포맷팅 또는 api를 빠르게 구현하는 것이 목표임
- 목표를 해결하기 위해 돌진하는 것이 중요함

비전공자 부트캠프 수료 후 근황

오랜만에 개발 블로그에 근황을 남긴다. 취업 후 바쁜 업무와 인생의 빅 이벤트인 결혼이 있어서 한동안 블로그를 소홀히 했었다. 지난 2월 스파르타 코딩클럽 항해99를 수료하고 스프링 개발자가 되겠다는 부푼 꿈을 안고 취업시장에 뛰어들었다. 다시 대학교 4학년 때로 돌아간 느낌이었는데 의외로 그때 보단 스트레스가 덜했다. 어차피 나의 수준 (비전공자 부트캠프 3개월 공부)을 생각하니 그렇게 바라는 게 많지 않아서였다. 회사 입장에서 나를 개발자로 뽑을 이유가 딱히 없다고 생각해서 작은 회사, 신생 회사 위주로 넣었다. 이제는 큰 규모 회사가 싫기도 했기 때문이다. 업계 평균 초봉 범위에 들기만 한다면 땡큐였다. 

부트캠프 수료 기념 여행

비전공자 부트캠프 출신 취업 하다

이력서를 넣은지 한달이 다 되어가니 여러 회사에서 면접 제의가 들어왔다. 규모가 작은 스타트업 위주로 넣었는데 시드 단계에서 부터 시리즈 C, 중견 기업에서 면접 제의가 들어왔다. 그러다가 면접 본 곳 중 가장 나를 필요로 할 거 같은 곳으로 선택했다. 나는 스프링을 겨우 3개월 정도 공부한 완전 초짜인데 node.js를 시키겠다는 곳이었다. 고심 끝에 취직을 결심하고 들어간 곳에서 처음 2주동안은 node.js를 공부하고 바로 개발에 투입되었다. 스프링에 비해서 node.js는 쉬운 편(?)이었다. MongoDB를 사용하는 데 SQL보다 휠씬 개발하기 쉽다. 사람들도 좋고 시니어 개발자와 붙어서 일하는 환경도 모르는 것을 친절하게 알려주시는 환경도 좋다. 입사 3개월 후에는 주 3일 재택도 가능해졌다. 취업 후 3군데 정도에서 더 면접 제의가 왔었고 규모도 훨씬 크고 업력도 훨씬 오래된 곳들이었지만 고사했다. 재택은 최고의 복지다. 

 

주니어 개발자 7개월 후기

개발자가 스트레스가 아예 없는 직업은 아니지만 (그런 직업은 없다. 백수도 스트레스가 있다.) 전에 내 전공일을 하며 사람 스트레스와 내 잘못이 아닌 타인의 잘못된 결정과 판단으로 밤을 새던 날과는 다르게 나의 미숙함과 잘못으로 밤을 새기 때문에 훨씬 낫다. 전직장에서 스트레스가 100이었다면 여기는 10 정도다. 내 업무량은 나의 숙련도와 관련해서 결정된다.  내가 못하면 밤새는 거고 빨리 잘하면 빨리 퇴근하는 거다. 이제 코딩의 ㅋ을 안지 겨우 1년 밖에 안된 비전공자 부트캠프 출신이 개발자로 취직을 했기 때문에 오래 걸리고 실수가 많고 아는 게 없는 게 당연해서 야근을 하는 것에 불만이 없다. 납기를 맞추는 것이 좀 스트레스긴 하지만 말이다. 그리고 체감 상 스프링보다 노드가 상대적으로 쉽다. SQL보다 NoSQL이 쉽다. 

 

스타트업 주니어 개발자

사실 스타트업이란 곳에서 일하는 것은 꽤나 모험적인 일이다. 작은 초기 인원으로 많은 것을 하려다 보니 개발 업무 이외에도 할 것들이 생긴다. 전공을 살려 IR 자료 리서치를 도와드린 적도 있다. 아마 이게 내가 빨리 취업된 이유일 것 같기도 하다. 매 주 각자 자유 주제를 가져와서 모든 구성원 앞에서 스터디 발표를 한다. 생각해보니 다음 주는 내가 발표를 하는 날이다. 큰일이네. 매 주 주제를 생각하는 것도 고역이다. 한 사람이 여러가지 업무를 같이 하다 보니 정신이 없을 때도 있지만 스타트업의 묘미가 아닌가 싶다. 회사가 성장하는 게 눈에 보여서 다들 바쁠수 밖에 없다고 생각했다. 나는 물론 개발 업무가 95%다. 다른 걸 같이 할 여력이 안되는 것도 있다. 그래도 나의 아이디어와 제안들이 받아질 때도 종종 있어서 탑 다운 방식이 99.9%였던 전 직업 보다는 훨씬 직업 만족도나 회사에 대한 만족도가 크다. 연봉은 전보다 3분의 1이 되었지만 돈보다 마음 편한 게 최고다. 아무래도 스타트업은 빨리 성장하는 게 목표인지라 고객의 니즈를 빨리 맞춰주려하고 그에 따라 개발 일정도 산정이 되기도 한다. 

 

node.js를 취업해서 2주 배워놓고 개발자로 일 한지 벌써 7개월이 흘렀다. 아직 아무것도 모르는 거 같고 비동기, 동기가 나를 괴롭히지만 향후 5년 간은 계속해서 개발을 할 것 같다. 개발일은 재미있고 늘 흥미롭기 때문이다. 5년이라는 짧은 텀을 잡은 이유는 인생 어디로 흘러갈지 모르기 때문. 나도 처음 취업했을 때 그 회사 10년 다닐 줄 알았다. 코로나 터질 줄 몰랐고 개발 배울지 몰랐고 올해 결혼할지도 몰랐다. 

 

스타트업의 흔한 전체 회의

 

 

 

현재 진행하는 사이드 프로젝트 'developSpace'에서는 탈퇴하면 '우주미아'라는 닉네임으로 변경해주기로 결정을 했었습니다. 탈퇴 기능 구현을 맡았는데 기존 게시물은 삭제 하지 않으면서 게시물에 나오는 닉네임은 '우주미아'로 변경하고, 프로필 사진도 기본 사진으로 변경하고, 회원 칼럼을 없애려고 합니다. 

 

그런데 모든 탈퇴 회원이 '우주미아'라는 닉네임을 가지면 중복이 되어 문제가 생기니 랜덤 숫자와 형용사를 붙여주기로 했습니다. 

 

랜덤 닉네임 만들기

필수적으로 들어가야 하는 것은 '우주미아'입니다. 겹치지 않기 위해서 형용사와 숫자를 포함시킨 랜덤 닉네임을 만드려고 합니다.

 

public static String randomNickname(){
    List<String> adjective = Arrays.asList("행복한", "슬픈", "게으른", "슬기로운", "수줍은",
            "그리운", "더러운", "섹시한", "배고픈", "배부른", "부자", "재벌", "웃고있는", "깨발랄한");
    String name = "우주미아";
    String number = (int)(Math.random() * 99)+1 +"";
    Collections.shuffle(adjective);
    String adj = adjective.get(0);
    return adj+name+number;
}

 

String 값을 반환하는 randomNickname 메서드를 만들었습니다.

형용사는 제가 맘대로 적어넣은 겁니다.

적다보니 19개를 적었네요. 나중에 20개로 늘려야겠습니다.

 

Collections.shuffle을 사용하면 List의 값들을 섞어줍니다. 

말그대로 셔플을합니다.

셔플 한 값중 가장 첫번째 값을 adj 에 저장합니다.

 

기본으로 들어가는 "우주미아"는 String name에 저장했습니다.

 

마지막으로, 랜덤 숫자(number)를 저장합니다.

99까지 숫자 중에서 랜덤으로 숫자가 나갑니다.

 

이 3가지 값들을 하나로 더하면 adj + name + number 로 랜덤 닉네임이 완성됩니다.

 

랜덤 닉네임 만들기

 

"부자+우주미아+57" 이 나왔네요!

 

어제 CI/CD와 MySQL 연동을 완료했고 이제는 회원 관련 API를 만들어야 합니다. 오늘 밤까지 기능 구현 다 하기로 했거든요. 제가 구현 해야하는 기능들은 아래와 같습니다.

 

  • [ ] 카카오 로그인 - Spring Security
  • [ ] 구글 로그인
  • [x] 멤버 권한 ENUM - MEMBER, ADMIN
  • [x] 관리자 로그인
  • [ ] 닉네임 변경
  • [ ] 탈퇴 → 우주미아

 

카카오 로그인은 이전에도 해봐서 괜찮고 구글 로그인은 뒤로 미뤄도 될 것 같습니다. 관리자 로그인이긴하지만 기본 로그인 이미 구현 완료했고 멤버 권한 칼럼도 따로 만들었습니다. 닉네임 변경과 탈퇴는 안해봤는데 이번 기회로 해보면 좋을 것 같습니다. 닉네임 변경은 별로 안어려울 것 같습니다. 이번 프로젝트에서는 탈퇴 시에 닉네임을 우주 미아로 변경하기로 했습니다. 로그인은 못하지만 게시글 내역은 지우지 않는 것으로 정했습니다. 

 

그리고 swagger를 적용해서 하는 것을 잊지말아야 겠어요. 자꾸 까먹네요.

 

대략적으로 오늘 할 일 순서는

 

1. 카카오 로그인 API (이메일, 닉네임, 프로필 사진)

2. 닉네임 변경 설정 API

3. 탈퇴 API

 

입니다.

 

저녁 먹기전에 다 끝내봅시다.

테스트 코드 짜는 연습하기 전에 CI/CD를 구축하려고 합니다. aws ec2와 codedeploy와 githubaction을 사용하여 무중단 배포를 구현하였습니다. 전에 최종프로젝트할 때 팀장님이 프로젝트 시작도 전에 다 해놓으신거를 사용했었는데 굉장히 효율적으로 잘 사용했었습니다.

 

Codedeploy 설치하기

codedeploy

이제 명령어 치는 것도 익숙해져서 터미널을 겁내지 않게 되었습니다.

원래는 까만건 종이요 하얀건 글씨였답니다.

 

 

 

 

Ubuntu Server용 CodeDeploy 에이전트 설치 - AWS CodeDeploy

출력을 임시 로그 파일에 쓰는 것은 Ubuntu 20.04에서 install 스크립트를 사용하여 알려진 버그를 해결하는 동안 사용해야 하는 해결 방법입니다.

docs.aws.amazon.com

 

Github Actions CD: AWS EC2 에 Spring Boot 배포하기

Overview 애플리케이션을 개발하면 외부에서도 접근 가능하도록 클라우드 환경에 배포합니다. 이전에 포스팅 했던 AWS 1편에서는 마지막에 scp 명령어로 로컬에 존재하는 빌드 파일을 EC2 인스턴스

bcp0109.tistory.com

위의 블로그 글을 참조했습니다.

가장 도움이 되고 깔끔하게 정리되어 있습니다.

 

 

 

CodeDeploy 애플리케이션 사양(AppSpec) 파일 - AWS CodeDeploy

이 페이지에 작업이 필요하다는 점을 알려 주셔서 감사합니다. 실망시켜 드려 죄송합니다. 잠깐 시간을 내어 설명서를 향상시킬 수 있는 방법에 대해 말씀해 주십시오.

docs.aws.amazon.com

 

물론 aws 공식 문서가 가장 정확합니다.

 

 

CI/CD 성공!!!

 

자그만 오류가 하루종일 절 붙들고 있었지만 결국 성공했습니다. 

 

만세.

Could not find mysql:mysql-connector-java:.

하루종일 찾다가 이것 저것 다 시도해봐도 안되서 설마 이거인가 하고 해봤는데 이거였다.

 

 

springframework.book version 이 2.7.8 이었는데

version을 2.7.6으로 변경하자마자 잘되는 걸 확인했다.

 

 

3초만에 build 가 되었다.

 

아래는 전체 build.gradle 이다. 별걸 다 시도 해봤지만 아니어서 허탈하다. 하지만 해결해서 행복.

plugins {
    id 'java'
    id 'org.springframework.boot' version '2.7.6'
    id 'io.spring.dependency-management' version '1.1.0'
}

group = 'developSpace.com'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-security'
    implementation 'org.springframework.boot:spring-boot-starter-web'

    implementation 'io.springfox:springfox-boot-starter:3.0.0'
    implementation 'org.mapstruct:mapstruct:1.5.3.Final'
    implementation 'mysql:mysql-connector-java'

    compileOnly 'org.projectlombok:lombok'
    compileOnly group: 'io.jsonwebtoken', name: 'jjwt-api', version: '0.11.2'
    runtimeOnly group: 'io.jsonwebtoken', name: 'jjwt-impl', version: '0.11.2'
    runtimeOnly group: 'io.jsonwebtoken', name: 'jjwt-jackson', version: '0.11.2'

//    runtimeOnly 'com.h2database:h2'
    runtimeOnly 'mysql:mysql-connector-java'

    annotationProcessor 'org.projectlombok:lombok'
    annotationProcessor 'org.mapstruct:mapstruct-processor:1.5.3.Final'

    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testImplementation 'org.springframework.security:spring-security-test'

}

tasks.named('test') {
    useJUnitPlatform()
}

jar {
    enabled = false
}

이력서 고치랴, 면접준비하랴, 프로젝트 하랴, 그동안 못만난 지인들 만나랴, 밀린 드라마 보랴, 아주 바쁜 생활이 지속되고 있습니다. 친구들이랑 노는 것은 새로운 게 없지만 개발은 늘 새롭네요. 회원가입 로그인을 구현을 작년 11월에 해보고 안하다가 이번에 새로 사이드 프로젝트를 하면서 구현을 담당하게 되었습니다.

 

회원가입이 생각보다 단순하지는 않습니다.

 

1. 이메일 중복체크

2. 닉네임 중복체크

3. 이메일 유효성 확인

4. 비밀번호 유효성 확인

5. 닉네임 유효성 확인

6. 프로필 이미지

 

쓰다 보니까 더 많아졌네요. 

 

우선 오늘은 swagger랑 기본 security 설정을 커밋했고 위에 나열한 것들을 다 하고 잘 예정입니다.

 

@Size(min = 8, max = 15, message = "비밀번호의 길이는 8자에서 15자 사이입니다")
@Pattern(regexp = "[a-zA-Z0-9`~!@#$%^&*()_=+|{};:,.<>/?]*$", message = "비밀번호 형식이 일치하지 않습니다")
private String password;

 

validator 클래스를 따로 만들어서 해야 겠습니다. 생각보다 유효성 검사할 것들이 있네요. 

 

swagger를 프론트와 소통하는 API 명세서로 계속 사용해왔는데 설정하는 법을 정리해보려고 합니다. Spring Boot 2.7.8, Gradle 환경에서 설정하는 방법입니다. swagger를 사용하면 따로 API 명세를 작성하지 않아도 되고 추후에 수정할 일이 생겨도 자동으로 수정이 되서 편합니다. 프론트랑 소통할 때도 문서로 하는 것보다 swagger로 바로바로 업데이트 되어서 생산성도 높아집니다.

 

1. Build.gradle 의존성 추가

implementation 'io.springfox:springfox-boot-starter:3.0.0'

 

build.gradle에 위의 dependency 코드를 추가합니다.

 

2. SwaggerConfig.java

 

@Configuration
public class SwaggerConfig {
    @Bean
    public Docket api() {
        return new Docket(DocumentationType.OAS_30)
                .ignoredParameterTypes(AuthenticationPrincipal.class)
                .ignoredParameterTypes(Pageable.class)
                .useDefaultResponseMessages(false)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("developspace.com.developspace")) // api 스펙이 작성되어 있는 패키지 (controller)
                .paths(PathSelectors.any())
                .build();
    }

    public ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("DevelopSpace Rest API Documentation")
                .description("Develop Space API 명세")
                .version("0.1")
                .build();
    }
}

 

3. security 설정 풀어주기

security로 막아 놓은 것에 swagger url 설정 추가해줬습니다.

 

http.authorizeRequests().antMatchers("/api/member/signup","/api/member/login").permitAll()
        .antMatchers("/v3/api-docs/**", "/swagger-ui/**", "/swagger-resources/**").permitAll()
        .antMatchers(HttpMethod.GET,"/api/answer/**").permitAll()
        .antMatchers("api/question/**").permitAll()
        .anyRequest().authenticated();

 

 

4. Swagger 확인하기

localhost:8080/swagger-ui/index.html

 

위의 주소로 접속하면 swagger api 문서를 볼 수 있습니다.

알고리즘이랑 sql 문제들을 풀어야하는데 또 저는 환경에 밀어넣어져야 열심히 하는 나약한 인간이라서 내기를 하기로 했습니다.

 

다음주 목요일까지 프로그래머스 자바 lv1 문제 다풀기 10만원 빵

 

73문제

총 73문제인데 아직 하나도 안풀어봤습니다. 뇌풀기 몸풀기 용도로 빠르게 풀고 레벨 2로 넘어가야겠습니다. 

 

이제 인성면접은 그냥 하는데 CS는 휴가 다녀왔더니 기억이 안나서 다시 열심히 해야겠어요.

멘토님들은 어떻게 다 외우고 계시는 걸까요..?

근데 생각해보니 저도 회사다닐때 필요에 의해 다 외우고 살았던거 같습니다.

열심히 외우겠습니다...

 

'TIL' 카테고리의 다른 글

TIL 오랜만에 aws ec2 220314  (0) 2023.03.15
TIL 회원가입 로그인 구현하기 230312  (0) 2023.03.12
TIL 취업코칭 230307  (0) 2023.03.07
TIL 일론머스크 230226  (0) 2023.02.27
TIL 오랜만에 주말 230225  (0) 2023.02.27

+ Recent posts