2019-10
2019-10 copied to clipboard
๐บwedev - ๊ธฐ์ ์๊ฐ, ๊ฐ๋ฐ์ ์ปค๋ฆฌ์ด ์กฐ์ธ, ๊ฐ๋ฐ ์ปจํผ๋ฐ์ค ์์ ๊ณต์ ๋ฐ ์คํธ๋ฆฌ๋ฐ ์น ์๋น์ค!
wedev.tv ๐ฉโ๐ป๐จโ๐ป
๊ฐ๋ฐ์์, ๊ฐ๋ฐ์๋ค์ ์ํ, ๊ฐ๋ฐ์๋ฅผ ์ํ ๋์์ ์คํธ๋ฆฌ๋ฐ.๐ค wedev.tv๋ ๋ฌด์์ธ๊ฐ์?
wedev.tv(๋๋ wedev, ์๋ฐ๋ธ)๋ ์ํํธ์จ์ด ์์ง๋์ด๋ค์ด ์ํํธ์จ์ด ๊ธฐ์ ๊ณผ ๊ด๋ จ๋ ๋์์์ ๊ณต์ ํ๊ณ , ์๊ฒฌ์ ๋๋๋ฉฐ, ์ปค๋ฆฌ์ด ํ๋กํ์ ์์ฑํ ์ ์๋ ๊ณณ์ ๋๋ค. ์ปจํผ๋ฐ์ค ๋ฐํ, ํ๋ก๊ทธ๋๋ฐ ๊ฐ์, ๊ธฐ์ ์ค๋ช ๊ณผ ๊ฐ์ ๋์์์ ํ ๋ฐ ๋ชจ์๋ณด๊ณ , ๊ธฐ์ ์ ๋ํ ๊ฑด์ค์ ์ธ ํ ๋ก ์ ํ ์ ์๋ ์ปค๋ฎค๋ํฐ๋ฅผ ์๋๋ก ์ ์๋์์ต๋๋ค.
๐ ๋ชฉ์ฐจ
- ๋ก์ปฌ ๋จธ์ ์์ ์คํํ๊ธฐ
- ๊ธฐ์ ์คํ
- Git ์ปค๋ฐ ๋ฐ ๋ธ๋์น ์ ๋ต
- Mobile First Approach
- ์๋ฒ์ฌ์ด๋ ๋ ๋๋ง
- ํด๋ผ์ด์ธํธ API ๋ฐ์ดํฐ ์์ฒญ ๋ฐ ์บ์ฑ
- ๋์์ ์ ๋ก๋ ๋ฐ ์ธ์ฝ๋ฉ ํ์ดํ๋ผ์ธ
- ์๋ฒ๋ฆฌ์ค ์ํคํ ์ณ
- ์ธ์ฆ ์ํคํ ์ณ ๊ตฌ์ฑ
๐ป ๋ก์ปฌ ๋จธ์ ์์ ์คํํ๊ธฐ
Client
cd packages/client
npm install
npm run dev
Server
cd packages/server
npm install
npm run start:dev
๋ฐ์ดํฐ๋ฒ ์ด์ค migration
cd packages/typeorm
npm run typeorm migration:run
๐๊ธฐ์ ์คํ
๋ค์๊ณผ ๊ฐ์ ๊ธฐ์ ์ ์ฌ์ฉํ์ฌ ์๋น์ค๋ฅผ ์ ์ํ์ต๋๋ค.
Client
- Next.js
- TypeScript
- react-fetching-library
- Material-UI
Server
- NestJS
- TypeScript
- TypeORM
Database
- MySQL
- Redis
Cloud Services
- AWS Lambda
- AWS Cloudfront
- AWS Elastic Transcoder
- AWS S3
- AWS RDS
- AWS ElastiCache
โ Git ์ปค๋ฐ ๋ฐ ๋ธ๋์น ์ ๋ต
Git์ ํ์ฉํ์ฌ ํ์ ํ ๋ ๋ค์๊ณผ ๊ฐ์ commit ๋ฐ ๋ธ๋์น ๋ช ๋ช ๊ท์น์ ์ฌ์ฉํ์ต๋๋ค.
Commit ์ ๋ต
Commit ์ ๋ชฉ์ ํ์์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
[server ? client] | <type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<Fixes>(optional) <link>
<BLANK LINE>
- server ์ client ๋ ๋ค ํฌํจ ๋ ๊ฒฝ์ฐ
[server & client]๋ก ์์ฑํฉ๋๋ค. - subject์ body๋ฅผ ํ๊ธ๋ก ์์ฑํ๊ณ , ๊ทธ ์ธ์ ์์ด๋ก ์์ฑํฉ๋๋ค.
- type: ์ด๋ค ์๋๋ก ์ปค๋ฐํ๋์ง๋ฅผ type์ ๋ช ์ํฉ๋๋ค.
- scope: ์ปค๋ฐ์ ๋์์ด ๋๋ ๊ฒ์ ๋ช ์ํฉ๋๋ค.
- subject: ์ต๋ 50๊ธ์๊ฐ ๋์ง ์๋๋ก ํ๊ณ ย ๋ง์นจํ๋ ์ฐ์ง ์์ต๋๋ค.
- body: ์ต๋ํ ์์ฑํฉ๋๋ค.ย How ์ Why ์์ฃผ๋ก ์์ฑํฉ๋๋ค. ~ํฉ๋๋ค ๋ผ๋ ๋ฌธ์ฒด๋ก ์์ฑํฉ๋๋ค.
- issue: ์ด์์ ๋ํ ์์ธํ ์ค๋ช ์ด ํ์ํ ๊ฒฝ์ฐ ํด๋น ์ด์์ ๋งํฌ๋ฅผ ์ฒจ๋ถํฉ๋๋ค.
- ์ฐธ์กฐ: ํด๋น ์ปค๋ฐ์ ์์ฑํ๊ธฐ ์ํด ์ฐธ๊ณ ํ ๋งํฌ๋ฅผ ์ฒจ๋ถํฉ๋๋ค.
Branch ์ ๋ต
Branch ์ด๋ฆ์ ํ์์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
[์ ํ]/[๋ด์ฉ]_[๋ธ๋์น ์์ฑ ๋ ์ง]
์ ํ์์ ํ์ฉํ์ฌ ๋ค์๊ณผ ๊ฐ์ด ์์ฑํ ์ ์์ต๋๋ค.
feature/search_api_20191219
refactor/search_api_20191220
๐ฑ Mobile First Approach
Wedev๋ UI ๋์์ธ ๋จ๊ณ๋ถํฐ Mobile First Approach ์ ๋ต์ผ๋ก ์ค๊ณ๋๊ณ ๊ฐ๋ฐ๋์์ต๋๋ค.
Mobile First Approach๋?
Mobile First Approach๋, ๋ชจ๋ฐ์ผ ๊ธฐ๊ธฐ์ ์น ๋ธ๋ผ์ฐ์ ๋ก ์ ์ํ ์ฌ์ฉ์๋ฅผ ์ค์ฌ์ ๋๊ณ ์๊ฐํ๋ ์ฌ๊ณ ๋ฐฉ์ ์ ๋๋ค. ์ธํฐ๋ท ํธ๋ํฝ์์ ๋ชจ๋ฐ์ผ ์น ํธ๋ํฝ์ด ๋ฐ์คํฌํฑ์ ๊ฒ์ ์ถ์ํ์ง ์ค๋์ด๊ธฐ ๋๋ฌธ์ ๋ค์ ์ด์ฉ์์ธ ๋ชจ๋ฐ์ผ ์น์ ์ค์ฌ์ ๋๊ณ ์๊ฐํ๋๊ฒ์ด ๋น์ฐํ๊ฒ ๋์์ต๋๋ค. ๊ธฐํ ๋ฐ ๋์์ธ ๊ณผ์ ์์ ๋ชจ๋ฐ์ผ ์น ์ฌ์ฉ์์ UI/UX๋ฅผ ๋จผ์ ๊ณ ๋ คํ๊ณ ๊ทธ ๋ค์์ผ๋ก ๋ฐ์คํฌํฑ ์ด์ฉ์์ UI/UX๋ฅผ ๊ณ ๋ฏผํ๊ฒ ๋ฉ๋๋ค.
Mobile First ๋์์ธ

Mobile First ๋์์ธ์ ์ ์ฝ๋ ์์ ํ๋ฉด์์ ์ ํ ๋์์ธ์ ์์ํด์ ํ๋ธ๋ฆฟ๊ณผ ๋ฐ์คํฌํฑ์ผ๋ก ๋์์ธ์ ํ์ฅํ๋ ๊ธฐ๋ฒ์ ๋งํฉ๋๋ค. Wedev๋ ๋์์ธ ๊ณผ์ ์์ ๋ชจ๋ฐ์ผ ํ๋ฉด์์์ UI/UX๋ฅผ ๋จผ์ ์์ฑํ ํ์ ๋ฐ์คํฌํฑ ํ๋ฉด์์์ UI/UX๋ฅผ ๊ทธ๋ ธ์ต๋๋ค.
Mobile First ์คํ์ผ๋ง
Mobile First Approach ์ ๋ต์ ๋ฐ๋ผ ์คํ์ผ ๊ท์น ๋ํ Mobile First๋ก ์์ฑํฉ๋๋ค.
export const Container = styled.div`
padding-top: 6.4rem;
background-color: #383d3f;
@media only screen and (min-width: ${BREAKPOINT}px) {
width: 22rem;
height: 100%;
}
`;
์์ ๊ฐ์ด, ๊ธฐ๋ณธ ์คํ์ผ์ ๋ชจ๋ฐ์ผ์์ ์ฌ์ฉํ ์คํ์ผ์ ๋จผ์ ์์ฑํ๊ณ media query๋ฅผ ์์ฑํ์ฌ ๊ทธ ๋ด๋ถ์๋ ๋ฐ์คํฌํฑ์ ์ถ๊ฐ๋ ์์ฑ์ ์์ฑํฉ๋๋ค. ์ผ๋ฐ์ ์ผ๋ก ๋ชจ๋ฐ์ผ ํ๋ฉด์ด ๋ฐ์คํฌํฑ ํ๋ฉด๋ณด๋ค ๊ฐ๊ฒฐํ๋ค๋ ํน์ง์ด ์์ต๋๋ค. ๋ง์ฝ์ ์์ ๊ฐ์ด Mobile First ์คํ์ผ ๋์ ์ Desktop First ์ ๊ทผ ๋ฐฉ๋ฒ์ผ๋ก ์คํ์ผ์ ์์ฑํ๋ค๋ฉด ๋ฏธ๋์ด ์ฟผ๋ฆฌ์์ ์์ฑ์ ์ทจ์ํ๋ ์ฝ๋๋ฅผ ์์ฑํด์ผ ํ๊ธฐ ๋๋ฌธ์ ๋ถํ์ํ ์ฝ๋๋์ด ๋์ด๋๋ค๋ ๋จ์ ์ด ์์ต๋๋ค. ๋ฐ๋ผ์ Mobile First ์คํ์ผ ์ ๋ต์ ํตํด ๋ณด๋ค ๊ฐ๊ฒฐํ ์ฝ๋๋ฅผ ์์ฑํ ์ ์์ต๋๋ค.
๐จ ์๋ฒ์ฌ์ด๋ ๋ ๋๋ง

Wedev๋ ์ค์ ๋ก ์ด์ํ ์๋น์ค๋ฅผ ๋ชฉ์ ์ผ๋ก ๊ฐ๋ฐํ์ต๋๋ค. ๋จผ์ , ๊ฒ์ ์์ง ์ต์ ํ(SEO)๋ฅผ ์ ํ ์ ์๋ ๋ฐฉ๋ฒ์ ๋ํ ๊ณ ๋ฏผ์ด ์์์ต๋๋ค. ์๋น์ค๋ ์ต๋ํ ๋ง์ ์ฌ์ฉ์๊ฐ ์ด์ฉํ๋๋ก ์ด์๋์ด์ผ ํ๊ณ , ๊ทธ ๋ฐฉ๋ฒ ์ค์ ํ๋๋ ๊ฒ์ ์์ง ์ต์ ํ๋ฅผ ํตํด ์ต๋ํ ๋ง์ ์ฌ์ฉ์์๊ฒ ๋ ธ์ถ๋๋ ๊ฒ์ ๋๋ค. ํด๋ผ์ด์ธํธ ์ฑ์ ์๋ฒ ์ฌ์ด๋ ๋ ๋๋ง ๋ฐฉ์์ SPA(single page application)๋ก ์์ฑํ๊ฒ ๋๋ฉด SEO์์ ๋ถ๋ฆฌํจ์ด ์์ ์ ์์ต๋๋ค. ๊ทธ๋์, SEO๋ฅผ ์์ฝ๊ฒ ํ ์ ์๋๋ก ์๋ฒ์ฌ์ด๋ ๋ ๋๋ง ๋ฐฉ์์ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ณ ๋ คํ๊ฒ ๋์์ต๋๋ค.
๋, ์ฌ์ฉ์ ๊ฒฝํ์ ๋น์ถ์ด ๋ณผ๋, SPA์ ๊ฒฝ์ฐ์๋ ์ด๊ธฐ ์ ๊ทผ์์ ํ๋ฉด์ ๊ทธ๋ฆฌ๋ ๋ฐ ์ฌ์ฉํ JS ํ์ผ์ ์ ๋ถ ๋ค์ด ๋ฐ์์ค๊ธฐ ๋๋ฌธ์ ์๋นํ ๊ธด ์๊ฐ๋์ ์ฌ์ฉ์์ ํ๋ฉด์๋ ์๋ฌด๊ฒ๋ ๋ํ๋์ง ์์ต๋๋ค. ๋ฐ๋ฉด ์๋ฒ์ฌ์ด๋ ๋ ๋๋ง ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ด๊ธฐ ์ ๊ทผ์์ UI๊ฐ ๋ ๋๋ง html์ ๋ฐ๋ก ๋ฐ์์ค๊ธฐ ๋๋ฌธ์ ๋๋จธ์ง ์์ ์ ๋ก๋ฉํ๋ ์๊ฐ ๋์ ์ฌ์ฉ์๋ ๋น ๋ฅด๊ฒ UI ์์๋ฅผ ์ดํด๋ณผ ์ ์๊ณ ์ด๋ ๋ ๋์ ์ฌ์ฉ์ ๊ฒฝํ์ผ๋ก ๋ค๊ฐ์ต๋๋ค. ์ด๋ฌํ ์ด์ ๋ค์ ๊ณ ๋ คํ์ฌ wedev์์๋ ์๋ฒ์ฌ์ด๋ ๋ ๋๋ง ๋ฐฉ์์ผ๋ก ์๋น์ค๋ฅผ ์ ๊ณตํ๊ธฐ๋ก ๊ฒฐ์ ํ์ต๋๋ค.
์๋ฒ ์ฌ์ด๋ ๋ ๋๋ง ๋ฐฉ์์ผ๋ก ์ ํ๋ฆฌ์ผ์ด์ ์ ์์ฑํ๊ธฐ ์ํด์ create-react-app ํ๋ก์ ํธ๋ฅผ ์๋ฒ ์ฌ์ด๋ ๋ ๋๋ง์ด ๋๋๋ก ๋ณ๋์ webpack ์ค์ ๋ฐ ์คํฌ๋ฆฝํธ๋ฅผ ์์ฑํ๋ ๋ฐฉ๋ฒ๊ณผ next.js ํ๋ ์์ํฌ๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ด ์์์ต๋๋ค. ํ์ง๋ง ์ ์ ๋ฐฉ๋ฒ์ ๊ฒฝ์ฐ์๋ ๊ฐ๋ฐ ๋ฆฌ์์ค๊ฐ ๋ง์ด ์์๋ ๊ฒ์ด๋ผ๊ณ ์๊ฐ๋์ด ๋น ๋ฅธ ๊ฐ๋ฐ์ ์ํด ์๋ฒ ์ฌ์ด๋ ๋ ๋๋ง์ ์์ฝ๊ฒ ๊ตฌํํ ์ ์๋ next.js๋ฅผ ์ฌ์ฉํ๊ธฐ๋ก ๊ฒฐ์ ํ์ต๋๋ค.
๐ฅ ํด๋ผ์ด์ธํธ API ๋ฐ์ดํฐ ์์ฒญ ๋ฐ ์บ์ฑ

Wedev์ ํด๋ผ์ด์ธํธ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋์ ์์ค์ ์ฌ์ฉ์ ๊ฒฝํ๊ณผ ๋คํธ์ํฌ ํต์ ๋ญ๋น๋ฅผ ๋ง๊ธฐ ์ํด์ ํด๋ผ์ด์ธํธ ์ ํ๋ฆฌ์ผ์ด์ ์์์ API ๋ฐ์ดํฐ ์บ์ฑ ๊ธฐ๋ฅ์ ์ฌ์ฉํ๊ณ ์์ต๋๋ค. ์ด๋ฅผ ๊ตฌํํ๊ธฐ ์ํ ์ด๊ธฐ ๋ ผ์ ๋จ๊ณ์๋ ์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค์ ์ฌ์ฉํ๋ ๊ฒ์ ๊ณ ๋ คํ์ต๋๋ค. ๋ํ์ ์ผ๋ก Redux, MobX ๋ฑ์ด ์์์ต๋๋ค. ํ์ง๋ง, ํ๋ก์ ํธ๊ฐ ์์ง ์ด๊ธฐ ๋จ๊ณ์ด๊ณ , API ๋ฐ์ดํฐ ์บ์ฑ ์ด์ธ์๋ ๋ณต์กํ ์ํ๊ด๋ฆฌ๊ฐ ํ์ ์์์ต๋๋ค. ๋, ์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ ๋, ์์ฑํด์ผ ํ๋ action, state ๊ด๋ฆฌ, ์ ๋ง์ ๋ก์ง๋ค์ ์์ฑํ๊ธฐ์๋ ๊ฐ๋ฐ ๋ง๊ฐ์ผ์ ๊ณ ๋ คํ์ ๋ ๊ฐ๋ฐ ๋ฆฌ์์ค๊ฐ ๋ถ์กฑํ๋ค๊ณ ํ๋จํ์ต๋๋ค. ๊ฒฐ๊ตญ Redux, MobX์ ๊ฐ์ ์ํ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ์ค๋ฒ์์ง๋์ด๋ง์ด๋ผ ํ๋จํ๊ณ ๋ณธ ๊ธฐ๋ฅ ๊ตฌํ์ ์ํ ๋์๋ค์ ์ฐพ๊ฒ ๋์์ต๋๋ค.
์ต๊ทผ์๋ GraphQL ์คํ์ ์ ๊ณตํ๋ API๊ฐ ๋ง์์ง๊ณ ์๋๋ฐ, GraphQL API ์๋ฒ์ ์์ฒญ์ ์์ฑํ๊ณ ๊ทธ ๋ฐ์ดํฐ๋ฅผ ์ ๊ด๋ฆฌํ ์ ์๋ ์ ๋ง์ ํ๋ก ํธ์๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค์ด ์์ต๋๋ค. ๊ฐ์ฅ ๋ํ์ ์ธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ค์ ํ๋๋ Apollo Client์ ๋๋ค. Apollo๋ query, mutation ๋ ๊ฐ์ง ๊ฐ๊ฒฐํ ์ธํฐํ์ด์ค๋ฅผ ํ์ฉํด์ ๋ฐ์ดํฐ ์์ฒญ์ ์์ฑํ ์ ์๊ธฐ ๋๋ฌธ์ ๊ต์ฅํ ๋์ ์์ฐ์ฑ์ผ๋ก ๋น ๋ฅด๊ฒ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌํํ ์ ์์ต๋๋ค. ๋, ๋ฐ์์จ ๋ฐ์ดํฐ๋ฅผ ์บ์ฑํด ์ฃผ๋ ๊ธฐ๋ฅ ๊น์ง ํฌํจํ๊ณ ์์ด์, ๋น ๋ฅธ ์๊ฐ๋ด์ ๋์ ์์ค์ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ง๋ค ์ ์์ต๋๋ค.
์ด์ ๊ฐ์ด ๊ฐ๋ฐ์ ์ผ๋ก ๋ค์ํ ํธ๋ฆฌํจ์ ์ ๊ณตํ๋ Apollo์์ ์๊ฐ์ ๋ฐ์ REST API ๋ฐ์ดํฐ ํธ์ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค์ด ์ต๊ทผ์ ๋ง์ด ์์ฑ๋๊ณ ์์ต๋๋ค. ์ด๋ค์ Apollo์ ๊ฐ์ด ๊ฐ๊ฒฐํ ์ธํฐํ์ด์ค๋ฅผ ํตํด ๋ฐ์ดํฐ ์์ฒญ ์์ฑ ์ฝ๋๋ฅผ ์์ฝ๊ฒ ์์ฑํ๊ณ , ์ํ๋ ์๊ฐ ๋งํผ ๋ฐ์ดํฐ๋ฅผ ์บ์ฑํ๋ ๊ธฐ๋ฅ์ ์ ๊ณตํ๊ณ ์์ต๋๋ค. SWR, react-query, react-async, react-fetching-library์ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค์ด ์์๊ณ , ์ ๋ถ hooks ๊ธฐ๋ฐ์ ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํ๊ณ ์์ด์ ๋น ๋ฅด๊ฒ ๊ฐ๋ฐ ์์ฐ์ฑ์ ์ก์ ์ ์๋ค๋ ํน์ง์ด ์์ต๋๋ค. ์ด ์ค์์ ์ด๋ ์ ๋ ์ด์์ ๋ฒ๊ทธ๊ฐ ๋ง์ด ํด๊ฒฐ๋๊ณ , ์ ์ ๋ฒ์ ์ผ๋ก ์ถ์๋์์ผ๋ฉฐ, ์บ์ฑ ๊ธฐ๋ฅ์ด ๊ฐ์ฅ ํ๋ฅญํ๊ฒ ๊ตฌํ๋ react-fetching-library๋ฅผ ์ฌ์ฉํ๊ธฐ๋ก ๊ฒฐ์ ํ์ต๋๋ค.
๋ณธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํ์ฉํ์ฌ ๋ค์๊ณผ ๊ฐ์ด ์ฝ๋๋ฅผ ์์ฑํ์ฌ ๋ฐ์ดํฐ ์์ฒญ์ ์์ฑํ ์ ์์ต๋๋ค.
import { useQuery, Action } from 'react-fetching-library';
export const makeTaglist: Action = (page: number) => ({
method: 'GET',
endpoint: `https://wedev.tv/api/tags?page=${page}`,
});
const action = createTagListAction(1);
const { payload, error } = useQuery(action);
์์ ๊ฐ์ด http ์์ฒญ ์ ๋ณด๋ฅผ ๋ด๊ณ ์๋ action ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ , react-fetching-library๊ฐ ์ ๊ณตํ๋ useQuery์ action ๊ฐ์ฒด๋ฅผ ์ธ์๋ก ์ ๋ฌํ์ฌ ์์ฒญ์ ์์ฑํ๊ฒ ๋ฉ๋๋ค.
๐บ ๋์์ ์ ๋ก๋ ๋ฐ ์ธ์ฝ๋ฉ ํ์ดํ๋ผ์ธ

Wedev์ ๋์์ ์ ๋ก๋ ๋ฐ ์ธ์ฝ๋ฉ ํ์ดํ๋ผ์ธ์ ์ผ๋ จ์ ๋ณต์กํ ๊ณผ์ ์ ๊ฑฐ์น๊ฒ ๋ฉ๋๋ค. ๋จผ์ , ์ฌ์ฉ์๊ฐ wedev ํด๋ผ์ด์ธํธ์์ ์ ๋ก๋ํ ํ์ผ์ ์ ํํ๊ณ ๋์์ ์ ๋ณด(๋์์ ์ ๋ชฉ, ์์ธ์ ๋ณด)๋ฅผ ์ ๋ ฅํ ํ ์ ์ถํฉ๋๋ค.
์์์ด ์ ์ถ๋๋ฉด, ๋จผ์ ์ฌ์ฉ์๊ฐ ์ ํํ ์์์ s3 ๋ฒํท์ ์ ๋ก๋ํด์ผ ํฉ๋๋ค. ์ด๋, s3 ๋ฒํท์ ์์ ์ ๊ทผ ๊ถํ์ ์ ๊ณตํด์ ๋์์ ํ์ผ์ ์ ๋ก๋ ํ ์ ์์ด์ผ ํฉ๋๋ค. ์ด๋, aws์์ ์ ๊ณตํ๋ presigned url์ ํ์ฉํด์ ํด๋ผ์ด์ธํธ ์ฑ์ ์ ๊ทผ ๊ถํ์ ์ ๊ณตํ ์ ์์ต๋๋ค.
Presgined url์ ๋ฐ๊ธ๋ฐ๊ธฐ ์ํด์๋ aws IAM ์ฌ์ฉ์์ ์ก์ธ์ค id์ secret์ ์ ๊ณตํด์ผํ๋๋ฐ, ๋ฏผ๊ฐํ ์ ๋ณด๋ฅผ ํด๋ผ์ด์ธํธ ์ฑ์ ์์ฑํ๊ธฐ์๋ ๋ณด์์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์๊ธฐ ๋๋ฌธ์ presigned url์ ๋ฐ๊ธํ์ฌ ๋ฐํํ๋ ๋ณ๋์ lambda ํจ์๋ฅผ ์์ฑํ์ต๋๋ค. ๊ฒฐ๊ตญ ํด๋ผ์ด์ธํธ๋ lambda๋ก๋ถํฐ presinged url์ ๋ฐ๊ธ ๋ฐ๊ณ , ํด๋น url์ ๋ํด ์์ฒญ์ ์์ฑํ์ฌ ํ์ผ์ ์ ๋ก๋ํ๊ฒ ๋ฉ๋๋ค. ์ด๋ ๊ณ ์ ํ ๊ฐ์ id๋ฅผ ์์ฑํ์ฌ ๋์์ ํ์ผ์ ๋๋ ํ ๋ฆฌ๋ก ๊ด๋ฆฌํ์ฌ ์ธ์ฝ๋ฉ๊ณผ์ ์์ ๋์์์ ์ถ์ ํ ์ ์์ต๋๋ค. ๊ทธ ๋ค์, ์ ํํ ํ์ผ์ ์ ์ธํ ๋๋จธ์ง ์ ๋ณด๋ ์๋ฒ์ ์ ์กํ์ฌ ์๋ฒ๊ฐ redis์ ๊ธฐ๋กํ๊ฒ ๋ฉ๋๋ค.
์์ ๊ฐ์ด ์๋ณธ ์์์ด s3 ๋ฒํท์ ์ ๋ก๋ ๋๋ฉด, ๋ ๋ค๋ฅธ lambda ํจ์๋ฅผ ํธ์ถํ๋๋ฐ, ์ด lambda ํจ์๋ ๋ฐฉ๊ธ ์ ๋ก๋ํ ๋์์์ url์ transcoder์ ์ ๋ฌํ์ฌ ์ธ์ฝ๋ฉ์ ์ํ ์๋ก์ด ์์ ์ ์์ฑํฉ๋๋ค. Transcoder๋ ์ ๋ฌ๋ฐ์ ๋์์ url์ ํตํด ์ธ์ฝ๋ฉ ์์ ์ ์ํํฉ๋๋ค. ์ธ์ฝ๋ฉ์ด ์๋ฃ๋๋ฉด 480p, 720p, 1080p ํด์๋์ ์์๊ณผ ๊ฐ ํด์๋์ ์์ ์ ๋ณด๋ฅผ ๋ด์ .mpd ํ์ฅ์๋ฅผ ๊ฐ์ง๋ DASH ํ์ค์ manifest ํ์ผ์ ์์ฑํฉ๋๋ค. ์ด์๊ฐ์ด ์ธ์ฝ๋ฉ์ด ์๋ฃ๋๋ฉด, ์์ฑ๋ ํ์ผ๋ค์ s3 ๋ฒํท์ ์ ๋ ฅํฉ๋๋ค.
์์ ์ธ์ฝ๋ฉ ์์ ์ํ๋ฅผ ๋ฐ๋ผ๋ณด๋ SNS ์๋น์ค๊ฐ ์ธ์ฝ๋ฉ์์ ์ด ์๋ฃ๋์์์ ๊ฐ์งํ๋ฉด, ์๋ฒ์ ์ธ์ฝ๋ฉํ ๋์์ ์ ๋ณด๋ฅผ ๋ด์ ๋ฉ์์ง๋ฅผ ์ ๋ฌํ๊ฒ ๋ฉ๋๋ค. ์๋ฒ๋ ๋ณธ ๋ฉ์์ง๋ฅผ ๋ฐ๊ฒ ๋๋ฉด ๋์์ ๊ฒฝ๋ก์ ํฌํจ๋ id๋ฅผ ํตํด redis์ ๊ธฐ๋กํ๋ ๋์์ ์ ๋ณด๋ฅผ ์ถ์ถํ๊ณ ๋์์ manifestํ์ผ์ url๊ณผ ํจ๊ป ๋์์ ์ ๋ณด๋ฅผ mysql์ ๊ธฐ๋กํ๊ฒ ๋ฉ๋๋ค.
ฦ ์๋ฒ๋ฆฌ์ค ์ํคํ ์ณ
AWS Lambda๋ฅผ ํ์ฉํ์ฌ ์๋ฒ๋ฆฌ์ค ์ํคํ ์ณ๋ฅผ ๊ตฌ์ถํ์ต๋๋ค. ์๋ฒ๋ฆฌ์ค๋ ํด๋ผ์ฐ๋๊ฐ ์ ๊ณตํ๋ FaaS์ ์ผ์ข ์ธ๋ฐ, ํน์ ๋น์ฆ๋์ค ๋ก์ง์ ํจ์๋ก ์์ฑํ์ฌ ํน์ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ์ ๋ ํจ์๋ฅผ ํธ์ถํ์ฌ ๋ก์ง์ ์ํํ ์ ์๋ ์๋น์ค ์ ๋๋ค. HTTP ์์ฒญ์ด ์์ฑ๋๋ฉด ํจ์๊ฐ ์คํ๋์ด ๋น์ฆ๋์ค ๋ก์ง์ ์ฒ๋ฆฌํ๊ณ ์ข ๋ฃ๋๋ ํน์ง์ด ์์ต๋๋ค.
์๋ฒ๋ฆฌ์ค ์ํคํ ์ณ๋ฅผ ์ฌ์ฉํ๋ฉด ๋น์ฉ์ ๋ํญ ์ค์ผ ์ ์๊ณ , ์ธํ๋ผ ๊ด๋ฆฌ๋ ๋ณด์์ ๋ํด ์ ๊ฒฝ์ฐ์ง ์๊ณ ๋น์ฆ๋์ค ๋ก์ง์ ์ง์คํ ์ ์์ต๋๋ค. ๋, ์ผ๋ฐ์ ์ผ๋ก ๋์ฉ๋ ํธ๋ํฝ์ ๋ํด auto scaling๊ณผ ๊ฐ์ด ์๋ฒ๋ฅผ ์ฆ์คํ๋ ํ ํฌ๋์ ์ฌ์ฉํ์ง๋ง, ์๋ฒ๋ฆฌ์ค ์ํคํ ์ณ์ ๊ฒฝ์ฐ์๋ ์์ฒญ์ด ๋ฐ์ํ ๋ ํจ์๋ฅผ ํธ์ถํ๋ ํน์ฑ์ ๋ณ๋์ ํธ๋ํฝ ์ฒ๋ฆฌ๋ฅผ ํ ํ์๊ฐ ์๋ค๋ ์ฅ์ ์ด ์์ต๋๋ค.
ํด๋ผ์ด์ธํธ
Wedev ํด๋ผ์ด์ธํธ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ค์๊ณผ ๊ฐ์ ์ํคํ ์ณ๋ฅผ ๊ฐ์ง๋๋ค.

์ฌ์ฉ์๊ฐ cloudfront๋ฅผ ๊ฐ๋ฅดํค๋ ์ฃผ์์ ์ ๊ทผํ๋ฉด cloudfront์์ ์ค์ ๋ lambda@edge๋ฅผ ํธ์ถํ๊ฒ ๋ฉ๋๋ค. lamdba@edge๋ ์ฌ์ฉ์์ ๊ฐ์ฅ ๊ฐ๊น์ด ์์น์์ lambda ์ฝ๋๋ฅผ ํธ์ถํ์ฌ ๋น ๋ฅด๊ฒ ์ฐ์ฐ์ ์ฒ๋ฆฌํ ์ ์๋ ์๋น์ค ์ ๋๋ค.
์ฌ๊ธฐ์ ์ฌ์ฉ์๊ฐ ์์ฒญํ ํ์ด์ง๊ฐ ์๋ฒ์ฌ์ด๋ ๋ ๋๋ง ์ฐ์ฐ์ด ํ์ํ ๊ฒฝ์ฐ์๋ ๋๋ค ํจ์๋ฅผ ํตํด ssr์ ์ฒ๋ฆฌํฉ๋๋ค. ์ด๋ฏธ์ง์ ๊ฐ์ static ํ์ผ์ ๋๋ค ํจ์๋ฅผ ๊ฑฐ์น์ง ์๊ณ s3์์ ๊ฐ์ ธ์ค๊ฒ ๋ฉ๋๋ค.
์๋ฒ
Wedev ์๋ฒ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ค์๊ณผ ๊ฐ์ ์ํคํ ์ณ๋ฅผ ๊ฐ์ง๋๋ค.

๋จผ์ , ์๋ฒ ๋ก์ง์ ์ํํ๋ ๋๋ค๋ ์ฐ๊ฒฐ๋ API Gateway๋ฅผ ํตํด ํธ์ถํ๊ฒ ๋ฉ๋๋ค. ์ด๋, API Gateway ์์ cloudfront๋ฅผ ๋๊ณ , cloudfront ์ฃผ์์ ์ฐ๊ฒฐ๋ wedev.tv ๋๋ฉ์ธ์ ํตํด ์ ์ ๊ฐ ๋๋ค ์ ํ๋ฆฌ์ผ์ด์ ์ ํธ์ถํ ์ ์์ต๋๋ค.
๋๋ค ํจ์๋, VPC๋ด๋ถ์ ๊ตฌ์ฑ๋ private subnet ๋ด๋ถ์ ๊ตฌ์ฑ๋ฉ๋๋ค. ๋ณธ private subnet์๋ ๋ฆฌ์์ค ์ ์ฅ์ ์ํ mysql๊ณผ ์ธ๋ฉ๋ชจ๋ฆฌ ๋ฐ์ดํฐ ์ ์ฅ์ ์ํ redis๊ฐ ํจ๊ป ๊ตฌ์ฑ๋์ด ์์ด์ ๋๋ค๊ฐ ๊ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ๊ทผํ ์ ์์ต๋๋ค.
๋๋๋ก ๋๋ค ํจ์๋ ์ธ๋ถ 3์ API์ ์ ๊ทผํด์ผํ๋ ๊ฒฝ์ฐ๊ฐ ์์ต๋๋ค. Wedev ์ฑ์ github์ 3์ ์ธ์ฆ์ ์ฌ์ฉํ๊ณ ์๊ธฐ ๋๋ฌธ์ ๋๋ค๊ฐ ์ธ๋ถ API์ ์์ฒญ์ ์์ฑํ ์ ์์ด์ผ ํฉ๋๋ค. ์ด๋, NAT ์ธ์คํด์ค๋ฅผ ์์ฑํ์ฌ ๋ด๋ถ ๋คํธ์ํฌ ์ฃผ์๋ง์ ๊ฐ์ง๊ณ ์๋ ๋๋ค์๊ฒ ์ธ๋ถ ๋คํธ์ํฌ ์ฃผ์๋ฅผ ์์ฑํด ์ค์ผ๋ก์จ ์ธ๋ถ API์์ฒญ์ ์์ฑํ ์ ์๊ฒ ๋งคํํฉ๋๋ค.
๐ ์ธ์ฆ ์ํคํ ์ณ ๊ตฌ์ฑ
- ๊นํ ์ธ์ฆ ํ์ด์ง
- ๊นํ ๋ก๊ทธ์ธ์ ์ฑ๊ณตํ๊ฒ๋๋ฉด Callback URL ๋ก Redirect
- Callback URL์ ๋ํ ์๋ต์ Auth Module์ด ๋ด๋นํฉ๋๋ค
- ์ธ์ฆ์ด ์ฑ๊ณตํ๋ฉด github ์ผ๋ก ๋ถํฐ code๋ผ๋ ๋ฌธ์์ด์ ๋ฐ์ต๋๋ค
- Auth Module์ ์ป์ code๋ก Third Party Module ์๊ฒ Github AccessToken์ ๋ฌ๋ผ๊ณ ํฉ๋๋ค. Third Party Module๋ ๋ง์ api์ ์ฐ๊ฒฐ๊ณ ๋ฆฌ๋ฅผ ๊ฐ์ง๋๋ค
- ๋๋ฆฌ์ธ์ ์ฑ๊ฒฉ์ ๋๋ Third party Module์ ๋ค์ด์จ ์์ฒญ์ ๋ง๊ฒ Github API module๋ก ๋ถํฐ ์ฃผ์ ๋ฐ์ ์๋น์ค๋ฅผ ์ฌ์ฉํฉ๋๋ค
- GitHub API Module์ ๋ฐ์ code๋ฅผ ํตํด์ Github Api๋ฅผ ์ด์ฉํด Access Token์ ์์ฒญํฉ๋๋ค
- Auth Module์ ์๋ต๋ฐ์ Access Token์ ํ ๋๋ก GitHub API์๊ฒ GIthub ์ ์ ์ ๋ณด๋ฅผ ๋ฌ๋ผ๊ณ ์์ฒญํฉ๋๋ค. ์ด๋ ์์ฒญ๊ณผ์ ์ Auth Module -> Third Party Module -> GitHub API Module -> GitHub API ์ ๋๋ค.
- ๋ฐ์ user ์ ๋ณด๊ฐ ์ฐ๋ฆฌ DB์ ์๋์ง AuthService๊ฐ ํ์ธํฉ๋๋ค.
- ๋ง์ฝ user ์ ๋ณด๊ฐ ์๋ค๋ฉด, ํ์๊ฐ์ ์ ํด์ผํฉ๋๋ค.
- ํ์๊ฐ์ ์ ์ํด์ Access Token์ ํฌํจํ User ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํฉ๋๋ค ๊ทธ๋ฆฌ๊ณ ํ์๊ฐ์ ํ์ด์ง๋ก ๋ฆฌ๋ค์ด๋ ํธ ํฉ๋๋ค
- ์ฌ์ฉ์๊ฐ ํ์๊ฐ์ ํผ์ ์์ฑํด์ ์ ์ถ์ ํฉ๋๋ค
- User Module์ด ์ด ์์ฒญ์ ์์ ํ์ฌ ๋ฌธ์ ๊ฐ ์์ผ๋ฉด ์ฟ ํค์ ๋ น์์ ธ ์๋ Access token ๊ณผ ์๋ฐํ ๋ฑ์ GIthub user ์ ๋ณด์ ํจ๊ป ๋๋น์ ์ ์ฅํฉ๋๋ค.
- ํ์๊ฐ์ ์ด ๋๋ฉด ๋ก๊ทธ์ธ์ ์๋์ผ๋ก ์คํํด์ผํฉ๋๋ค
- user-serializer ๋ชจ๋์ ์ด์ฉํด์ ์ธ์ ํ ์ด๋ธ์ ํ์์ ๋ณด๋ฅผ serialize ํ๊ณ , ๊ทธ์ ํด๋นํ๋ id๋ฅผ ์ฟ ํค์ ๋ น์ฌ์ ๋ฉ์ธํ์ด์ง๋ก ๋ฆฌ๋ค์ด๋ ํธ๋ฅผ ํฉ๋๋ค
- ๊ทธํ user-serializer๊ฐ Serialize ํ ์ ์๊ฒ ๊ฐ์ ์ ์ ๋ฅผ ํด์ user-session-module์๊ฒ insert๋ฅผ ํ๋ฉด user-session-module์ด ElastiCache์ ์ ์ฅํฉ๋๋ค