LOL 게임 유저가 포지션별 필터링을 통해 팀원들을 모집할 수 있는 반응형 웹 서비스입니다.
2021.11.08 ~ 2021.11.19
최근 롤드컵이나 영상매체 등 기존 점유율 1위를 유지하며 상승세를 달리는 게임
"LOL(League of Legend)"을 대상으로 5인 팀 게임 특성상 이상적인 포지션으로
플레이하기 힘든 문제를 해결하고자 POT 프로젝트 기획하였습니다.
현재 등록 된 게시글들을 모두 볼 수 있는 페이지로서 통신량을 관리하기 위해
Intersection Observer API
를 사용하여 Lazy Loading
기법을 구현했습니다.
Quill
에디터 라이브러리를 사용하여 글 작성 기능을 구현했습니다.
작성자의 글에 현재 신청된 신청자를 모두 볼 수 있으며 포지션별, 티어별 등 필터링 기능을 제공하여 사용자 경험을 높이기 위해 노력했습니다.
Node Mailer
라이브러리를 사용하여 특정 포지션에 참여시킬 신청자를 참여 승인 할 경우 신청자에게 참여되었다는 메일을 보내고 해당 포지션의 남은 신청자들은 신청 거부 처리하도록 구현했습니다.
현재 신청한 게시글, 작성한 게시글 등을 확인할 수 있도록 하였습니다.
JWT토큰이 유효한 지 확인하는 /api/validate
쿼리로 접근하여 미들웨어를 거친 후 사용자의 정보를 렌더링하는 공통 헤더 제작
백엔드를 직접 구성했기 때문에 필터링 조건에 맞는 API
를 직접 제작하여 조건에 맞는 신청자 리스트 렌더링 기능 구현
API
를 제공하는지 알게 됨NodeMailer
라이브러리를 사용하여 참여 승인된 신청자에게 메일 전송
React
, Vue
와 같은 라이브러리를 사용하지 않고 Vanilla JS
로만 구현하는 것이 목표였기에 어떻게 컴포넌트형식으로 헤더를 제작하여 팀원들이 사용하기 편한 헤더를 만들지 고민이었습니다.
NodeMailer
라이브러리로 메일 전송기능을 구현했는데 이 때 메일 전송이 실패했음에도 에러를 발생시키지 않아 난항을 겪었습니다.
이번 프로젝트를 진행하며 쿠키에 정보를 저장하면, 즉 클라이언트 측에 정보를 저장하는 것이 얼마나 위험한 것인지 알게 되었습니다.
class Header extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
this._rendered = false;
}
connectedCallback() {
if (this._rendered) return;
this._rendered = true;
this._setHeader();
this.render();
}
async _setHeader() {}
_renderLoginInfo(summoner) {}
_guideLogin() {}
render() {
this.shadowRoot.innerHTML = `
<style> ... </style>
<header>
<div class="wrapper">
<h1>
<a class="logo-link" href="/">
<img class="logo" src="/images/logo.png" alt="logo">
</a>
</h1>
<nav>
<a class="nav-link" href="/createdpot"><span class="create-pot">POT 생성</span></a>
<span class="nav-link login-info"></span>
</nav>
</div>
</header>
`;
}
}
customElements.define('login-header', Header);
React
의 클래스 컴포넌트처럼 사용가능한 Web Component
를 접목시켜
<login-header></login-header>
의 형태, 즉 태그 형태로 사용가능하게 하여 재사용성을 높이고 헤더 자체의 안정성을 확보할 수 있었습니다.
기존에는 G-Mail을 사용하여 메일을 전송하려 했으나 원인을 찾던 중 G-Mail의 SMTP 프로토콜을 제대로 설정해주지 않았기 때문이라는 것을 알게되어 설정이 까다로운 G-Mail보다 설정이 간단한 네이버 메일을 사용하여 문제를 해결했습니다.
결국 본질적인 문제점은 클라이언트 측에 저장되어 변경가능성이 있는 쿠키에 정보를 저장했다는 것이었기에 클라이언트측에서 사용하는 사용자 정보를 JWT에 담아 미들웨어를 통해 검증하고 유효한 사용자 정보
만을 넘겨받아 렌더링하는 방식으로 변경하였습니다.
현재는 웹 컴포넌트를 적용하여 해결했지만 제작 당시에는 웹 컴포넌트를 알지 못해 수동으로 관리하는, 즉 재사용성이 낮은 HTML형식으로 사용했었습니다.
HTML을 Copy & Paste
방식으로 사용하니 예상치 못한 에러가 자주 발생했었고 디버깅도 어려웠었습니다.
최초에 G-Mail을 선택한 이유가 보안이 철저하다는 장점 때문이었는데 오히려 너무 철저하고 복잡했던 과정으로 인해 제가 포기했던 상황이 너무 아쉬웠습니다.
추후 메일을 관리해야 되는 상황이 생긴다면 꼭 G-Mail에 대해 공부해서 제대로 적용해보고 싶습니다.
공통 헤더를 함수처럼 사용하기 위해 재사용성이 높은 웹 컴포넌트 기술을 적용하여 유지보수의 편의성을 높였습니다.
POT 프로젝트 이전에는 기능구현에만 집중하고 리팩토링을 한번에 몰아서 하는 방식으로 진행했는데 코드량이 많아질 경우 리팩토링 과정에서 발생하는 연계적인 문제들을 디버깅하기 힘들었고 작성한지 오래 된 코드를 보면 해석하는 것에 시간을 더 쏟아야하는 경우가 있었는데,
이번 프로젝트에서는 팀원들과 하루마다 코드리뷰를 진행하며 리팩토링을 병행하는 형식으로 진행하니, 최종적으로 리팩토링 단계에서 수정할 부분이 줄어들었고 코드의 가독성을 챙기며 프로젝트를 진행할 수 있어서 더 좋았습니다.
쿠키와 세션은 각각 클라이언트와 서버에 저장한다는 점에서 장단점이 존재했는데,
JWT토큰은 쿠키의 단점인 보안부분과, 세션의 단점인 서버가 여러 개일 경우 새로운 인증을 해야하는 점을 잘 개선한 기술임을 알게 되었습니다.
NodeMailer
를 사용하며 에러를 명확하게 발생시키지 않는다는 점 때문에 큰 난항을 겪었습니다.
덕분에 라이브러리를 만들거나 프로그래밍을 할 때 특히 인터프리터 언어에서 에러처리가 얼마나 중요한지 알게 되었습니다.