1월 10일 월요일부터 항해99가 시작되었다. 토요일까지 투입된 시간이 약 97시간인데, 오늘까지 하면 정말 100시간이 넘어간다. 주 100시간 투입이 농담이 아니었구나 싶다.
그간 퇴사 후 계속 미뤄왔던 공부를 이제야 제대로 시작한 느낌이다. QA, 인프라 엔지니어로 5년 반 정도 일하다가 개인적인 이유로 퇴사를 한 후 개발외의 다른 일을 해보며 지내다가, 다시금 개발자로 재도전을 하고 있다.
1월 10일 오전 9시에 오리엔테이션과, 이어서 미니 웹개발 팀 프로젝트 발제가 있었다. 시작하자마자 Gather 에서 팀원들끼리 모이는 게 다들 처음이어서 좀 어색했다가, 이내 당장 당일에 제출해야할 웹 개발 기획 초안을 만들어야 해서 금방 집중을 하고 작성을 시작했다.
프로젝트 주제를 제주도 카페 한눈에 보기
로 잡았는데, 화면 설계를 하는 동안, 팀원분이 돌하르방을 그리셨다. 그래서 제목은 다소 뜬금없이 돌하르방의 티타임
이 되었다. 아래는 실제로 시연 영상에 사용된 썸네일.
4일 기간동안 두 번의 멘토링이 있는데, 중간 멘토링의 목표는 역시 개발 범위를 좁히는 일이었다. 구현 범위가 넓어서 기간내에 끝내지 못할 수 있다며 줄이기를 권장받았지만... 그래도 이정도는 있어야할 것 같아서 그대로 진행하였다. 다행히 처음에 제시했던 기획안에서 모든 기능을 구현했다.
나는 실제 제주도 카페 데이터를 쌓는 스크래핑 부분과 데이터베이스 기본 설계, 카페 카드 전체 보기, 지역별로 보기, 카페를 이름으로 검색, 로그인한 사용자가 본인이 찜한 카페 목록만 볼 수 있도록 메인페이지에 전달하는 부분을 주력으로 담당했다. 스크래핑은 항해99 들어오기 이전에 웹개발종합반을 들으며 진행했던 개인 프로젝트인 오큘러스 퀘스트 VR 앱스토어 한눈에 보기 와 매우 유사하여, 스크래핑 해오는 주소를 제주관광정보센터 페이지의 데이터를 긁어오게 끔 변경하였다.
데이터베이스 쿼리를 짜면서도 고민을 많이했다. 팀원들과 코드 리뷰를 하며, 기존에 배웠던 웹개발종합반 기준으로는 MongoDB
의 find, find_one, insert_one, update_one
정도를 주로 사용했었다. 이 기본 쿼리문을 사용해 다른 팀원분들이 코드를 스스로 보면서도 이해할 수 있도록 우선 구현했다. 검색 기능과, 내가 찜한 카페를 불러오는 기능은 기존 소스를 남겨둔 채로 더 나아가 개선된 기능을 구현해보았다.
- 검색
- 기존 : 카페 이름이 정확히 일치하는 한 개만 가져옴
- 도전 :
LIKE
검색을 사용해 카페 이름의 일부분만 일치해도 검색 가능- 내가 찜한 카페 보기
- 기존 : 사용자가 찜한 목록을 보여줄 경우 찜한 카페가
n
개면n
번의 쿼리를 불러오도록 작성하여 데이터가 많을 수록 부하가 커질 수 밖에 없음- 도전 :
Aggregate
을 사용해 쿼리 한번에 원하는 데이터 모양으로 가져오기
이와 같이 구현되었다. 다만, Aggregate
를 사용하는 부분은 너무나도 어설프게 이해하고 작성하여 동작은 하지만 코드 가독성이 아주 떨어지고, 내가 스스로 납득하고 이해할 수 없게 작성되어 매우 아쉬운 부분이다. 추후에 실전 프로젝트에서 사용할 일이 있다면 반드시 완벽하게 이해하여 꼭 적용해봐야겠다는 생각이 든다.
최종 멘토링때 이에 대해 멘토님이 키워드 CQRS 패턴
을 알려주셨다.
거의 3일차 새벽에 대부분의 기능을 완성하여 끝내고 최종 멘토링때도 좋은 평가를 받았다. Flask에 jinja2 템플릿 엔진을 사용하는데 이를 처음 사용해봐서 많이 헤맸는데, 제공된 강의를 듣고 구글링도 열심히 한 끝에 제대로 동작하는 페이지들을 연결시켜줄 수 있었다.
팀장님이 팀원들을 잘 이끌어준 덕분에 4일간 매일 평균 16시간을 투입하면서도 정말 재미있게 끝낸 프로젝트였다. 팀원끼리 궁금한 것을 서로 물어보고, 좋은 개선사항이 있다면 공유하며 프로젝트의 구현 정도를 계속해서 발전시킬 수 있었다. 아주 짧은 시간동안 팀과 많이 친해지고, 서로 배운 내용을 공유하고 실제로 코드를 들여다보며 공부한 내용을 다시 정리하는 시간을 가졌다. 정말 시작이 좋았다고 생각이 든다.
1주차 일정 진행 중 알고리즘 반 선택에서 걷기반과 달리기반이 있어서, 좀 더 많은 문제를 접해보고 익히는 것이 도움이 될거라 생각하여 달리기 반을 선택하였다. 프로그래머스 - 코딩 테스트 의 문제들을 선별하여 푸는 것인데, 같은 반에 편성된 팀원분들이 푸는 속도가 정말 빠르시다. 항해99에 오기 전에 비슷한, 또는 동일한 문제를 이미 풀어보신 분도 있어서 그런 듯 하다.
이 블로그에 계속해서 문제를 푼 기록을 이어서 작성하고 있는데, 다른 사람이 풀은 답안도 분석하며 작성하느라 조금 느리게 진행하고 있어 조바심이 많이 나고 있다. 좀 더 문법이 눈에 익고 잘 이해해나간다면 속도는 붙을거라고 생각한다.
API(Application Programming Interface)의 정의를 위키백과 - API에서 찾아보면, 아래와 같이 설명하고 있다.
컴퓨터나 컴퓨터 프로그램 사이의 연결로, 일종의 소프트웨어 인터페이스 이며 다른 종류의 소프트웨어에 서비스를 제공한다.
...
컴퓨터와 인간을 연결시키는 사용자 인터페이스(UI)와 반대로, API는 컴퓨터나 소프트웨어를 서로 연결한다.
즉, 컴퓨터나 컴퓨터 프로그램끼리 연결하는 인터페이스인 것이다. 응용 프로그램에서 데이터를 주고 받기 위한 방법, 약속이라고 할 수 있다.
그 중 웹 API(위키백과 - 웹 API)에 대해 다뤄보자면, 정의를 이렇게 하고 있다.
웹 애플리케이션 개발에서 다른 서비스에
요청
을 보내고응답
을 받기 위해정의된 명세
를 일컫는다.
웹개발종합반에서 사실 이미 웹 API를 자주 사용했었다. 서울시 미세먼지 데이터를 받아올때도, 실시간 따릉이 현황을 가져올때도, 환율 정보를 가져올때도 사용했다.
GET
형식 (서버로부터 정보를 조회) 으로 서울 미세먼지 조회 OpenAPI 에 접근하여 데이터를 요청
하면, 서버에서 서울시 미세먼지 정보
를 내 브라우저에 응답
으로 보내준다. <form>
항목을 작성하여 POST
형식으로 보내 데이터 추가를 요청
서버 데이터베이스에 실제로 추가가 되고, 추가가 완료되었다고 응답
을 브라우저에 보내준다.이렇게 API 라는 서로 정해진 프로토콜을 통해 서버는 사용자가 원하는 정보를 제공하고, 클라이언트는 받아온다고 할 수 있겠다.
JWT란 인증에 필요한 정보들을 암호화시킨 토큰을 말하며, 하나의 인터넷 표준 인증 방식이다. 쿠키&세션 기반 방식의 단점을 보완한 방식이다.
쿠키&세션 기반 방식은 비밀번호 등 클라이언트의 인증 정보를 서버 측에 저장하고 관리하기 위해 세션 저장소를 사용하게 되는데, 요청이 많아지면 서버에 부하가 심해지고 이는 곧 비용과 성능 문제로 이어질 수 있다.
JWT의 구조는 .을 구분자로 나누어지는 세 가지 문자열의 조합으로, 암호화 전 각 문자열은 Header
, Payload
, Signature
로 나뉘어진다.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Header : 정보를 암호화 할 해싱 알고리즘 및 토큰의 타입 지정
{ "alg": "HS256", "typ": "JWT" }
Payload : 토큰에 담을 정보. 클라이언트의 고유 ID, 유효기간 등이 포함됨
{ "sub": "1234567890", "name": "John Doe", "iat": 1516239022 }
Signature : 인코딩된Header
와Payload
를 더한 뒤, 서버측에서 관리하는 비밀키로 해싱하여 생성됨. 토큰의 위변조 여부 확인
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), %YOUR-256-BIT-SECRET% )
Header
, Payload
를 가지고 Signature
를 생성하므로 데이터 위변조를 막을 수 있음쿠키&세션 방식과 달리 JWT는 토큰 길이가 길어, 인증 요청이 많아지면 네트워크 부하가 심해짐
토큰이 한 번 발급되면 유효기간 만료될 때까지 계속 사용이 가능하므로, 탈취당하면 대처하기 어려움
특정 사용자의 접속을 서버쪽에서 쉽게 세션 삭제할 수 있는 쿠키&세션 방식과 달리, JWT 방식은 강제로 만료시키기 어렵다.
Github을 팀 단위로 사용하는 걸 다들 처음 사용해보면서 많이들 헤맸다. 일단 스코프가 많이 작은 프로젝트를 같은 파일에 다들 달라붙어 하다보니, Conflict
가 계속해서 발생했다.
당연한 현상이지만, 이렇게 충돌하여 낭비되는 시간을 최소화 하기 위해 Gather에서 항상 캠과 마이크를 켜놓고 수정 전에 미리 이야기했다. 한 사람이 Commit
, Push
를 완료하고 난 뒤 알려주면 다른 사람이 그 파일을 Pull
하여 이어받아 수정사항을 다시 적용하고, 커밋하고 하는 것을 반복했다. 2일차 중간 멘토링 후에는 Conflict
가 거의 발생하지 않았다.
나 스스로 이해를 하기 전에는 남에게 설명할 수 없다. 이해를 하지 못한 채 설명하면 하는 도중에 횡설수설하거나, 설명하다가 말을 흐리거나 더듬게 된다.
어떤 코드, 개념 등을 설명하기 위해 준비해야 할 시간은 오래걸리지만, 그만큼 내가 제대로 이해하도록 시간을 많이 쓰면 다른 팀원들의 시간을 아껴주게 되므로 서로에게 윈윈 아닐까 생각한다.
1주차 팀 프로젝트때 사용했던, 사용자 정보 테이블
과 카페 정보 테이블
두 테이블을 JOIN
하여 묶어서 데이터를 검색하여 필요한 정보를 뿌려주는 것은 분명히 필요한 기능이었다. 다만 이런 기능이 있고 잠깐 써본적은 있다 정도만 알고 있는 상태로 불완전하게 구현하게 되니, 팀원들에게 이 내용을 설명할 때 스스로에게 너무나 난해해서 제대로 설명을 하지 못했다.
혼자 시간을 더 들여서 설명가능하게끔 과정을 눈에 보이게 쪼개고 나누어 다시 설명하여 공유를 하긴 했지만 찝찝한 기분을 감출 순 없었다. 다음에는 제한된 시간 내에서 구현에 집중해야 된다면, 알고 있는 구현 방식을 개선할 수 있는 방법을 우선적으로 찾거나, 좀 더 확실하게 이해한 후에 정확한 방법으로 구현하기 위해 더 노력해야 겠다는 생각이 든다.
앞서 있었던 일들을 좀 길게 회고해보았다. 다음주에도 이 정도 내용을 써내려갈 수 있을지 모르겠지만, 기술적인 내용들은 잊어버리지 않도록 꾸준히 정리해서 올리고 참고한 URL도 계속해서 붙여나가려고 한다. 미래의 내가 구글링 하다 내 블로그를 찾아 도움을 받는 그날까지.
위키백과 - API
IT용어 API란 무엇인가?
봐도봐도 모르겠는 API 개념 설명
API란 무엇일까? API 쉽게 이해하기
JSON Web Token 공식 페이지
인증 방식 : Cookie & Session vs JWT
JWT(Json Web Token) 알아가기
세션 vs 토큰 vs 쿠키? 기초개념 잡아드림. 10분 순삭! (영상)