๐๐ป velog-server clone to Golang (Gin)
์ผ๋จ ์ค๋์ ๋ฐ์ดํฐ๋ฒ ์ด์ค orm์ ๋ณ๊ฒฝํ๋ค. ๋ด๊ฐ ์ด๊ฑธ ๋ณ๊ฒฝํ๋ ์ด์ ๋ ๊ฐ๋ฐ์ ์งํํ๋ฉด์ gorm์์ ๋ชจ๋ธ๊ฐ์ ๊ด๊ณ์ model์ ํ์๊ฐ nullable์ ํ์ํ๋๊ฒ ์๋นํ ๋ถํธํ๋ค. ๊ทธ๋ฆฌ๊ณ ๋ฌด์๋ณด๋ค ๋ณ๊ฒฝ์ ํ์๊ณ ์๊ฐํ ์ด์ ๋ ๋ญ๊ฐ ์ ์ง๋ณด์๊ฐ ์๋๋ ๊ฒ ๊ฐ์๋ค. ๊ทธ๋์ ๋ณ๊ฒฝ์ ๊ฒฐ์ฌํ๊ณ ent๋ก ๋ณ๊ฒฝ์ ํ๋ค.
ํ์ฌ User ๋ชจ๋ธ๋ง ์์ฑ์ ํ์ง๋ง ๊ณ์ ๋ณ๊ฒฝํด ๋๊ฐ ์์ ์ด๋ค.
- ent orm ์ ์ฉ
- gin server ๊ตฌ์กฐ ๋ณ๊ฒฝ๋ฐ docker ํ์ผ ๋ถ๋ฆฌ (redis, postgresql)
entgo์์ ๋ํด์ ์กฐ๊ธ ์ฐพ์๋ดค๋๋ฐ code frist๋ก ๊ฐ๋ฐ๋์ด์ ๊ทธ๋ฐ์ง ์์์ ์ผ๋ก raw query๋ฅผ ์ง์ํ์ง ์๋๋ค. ๋ง์ฝ์ ์ฌ์ฉํ ๋ ค๋ฉด ๋น๋์ธ sql ๋ชจ๋๊ณผ ์ฐ๋ํด์ ์ฌ์ฉํด์ผ ํ๋ค.
์ด๋ฉ์ผ ๋ฐ์ก API๋ฅผ ์์ฑํ๋๋ฐ ์์ฃผ ์ ์๋ํ๊ณ ์๋ค.
- ent orm (emailAuth, User, UserProfile) ๋ชจ๋ธ ๊ตฌํ
- ent orm์์ raw query๊ฐ ์ง์์ด ์๋๊ธฐ ๋๋ฌธ์ ๋น๋์ธ sql์ ์ฐ๋ํด์ ์ฌ์ฉ
- sendEmail API ์์ฑ
์ค๋์ ์ ์ ํ์๊ฐ์ ๋ฐ ์ฝ๋ ์ธ์ฆ๋ถ๋ถ์ ๊ตฌํํ๋ค. ์ผ๋จ ์ฝ๋๋ก register token์ ๋ฐ๊ธ ๋ฐ๋ ๋ถ๋ถ์ ์ ์์ ์ผ๋ก ์คํ์ ํ๊ณ ์์ง๋ง ๋ก๊ทธ์ธ ๋ถ๋ถ์ ์ค๋ฅ๊ฐ ์์ ๊ฒ ๊ฐ๋ค.
์๋ํ๋ฉฐ ๋ก์ปฌ ํ์๊ฐ์ ์ค authToken ํ ์ด๋ธ์ ์์ฑํ๋ ๋ถ๋ถ์์ sql ์๋ฌ๊ฐ ๋ฐ์ํ๋ค.
insert node to table "auth_tokens": pq: insert or update on table "auth_tokens" violates foreign key constraint "auth_tokens_users_auth_token"
๋ด๊ฐ table ์ค๊ณ๋ฅผ ์๋ชปํ ๊ฒ ๊ฐ๋ค.... ์... ์ ์์ ์ผ๋ก ํ ๊ฒ ๊ฐ์๋ฐ... ์ด๊ฑด ๋ค์์ ์์ ํด์ผ๊ฒ ๋ค.
- ๋ก์ปฌ ํ์๊ฐ์ API
- ์ฝ๋ ์ธ์ฆ API
์ค๋์ ์ ๋ฒ ์ด์ผ๊ธฐ์์ ์ ์ ํ ํฐ์ด ๋ฐ๊ธ์ด ์๋๋ ์ด์๋ฅผ ํด๊ฒฐํ๋ค. ์ด์์ ์์ธ์ entgo์์๋ 1:N N:M๋ฑ ๋ค๋๋ค ๊ด๊ณ์์๋ column์ ์ค์ ํ ๋ s๋ฅผ ๋ถ์ฌ์ผํ๊ณ user ๋ชจ๋ธ์์ ํ ํฐ์ ์ถ๊ฐํด์ค์ผํ๋ ์ด์์๋ค.
ํ์ง๋ง ํ๊ฐ์ง ์ด์๊ฐ ๋ ๋ฐ์ํ๋๋ฐ, authToken์ ์์ฑํ๋ฉด fk_user_id์ ๊ฐ์ด ๋ค์ด๊ฐ์ผํ๋๋ฐ ์ ์ง ๋ชจ๋ฅด๊ฒ ๊ฐ์ด ์๋ค์ด๊ฐ๋ค... ๋ด๊ฐ ์๊ฐํ์ ๋๋ ๋ด๊ฐ ์๋ชปํ ๊ฒ ๊ฐ์๋ฐ ํ๋ฒ ๋ ์ด์ ๋ฅผ ์ฐพ์๋ด์ผ๊ฒ ๋ค.
- ๋ก์ปฌ ํ์๊ฐ์ API - (์ ๋ฒ ์ด์ผ๊ธฐ ์ด์ ์ฒ๋ฆฌ)
์์ง๋ ์ ์ ์ธ์ฆ๋ถ๋ถ์ ํ๊ณ ์๋ค.... authToken ๋ชจ๋ธ๊ณผ ๊ด๋ จ ์๋ฌ๋ก ์ค๋ ์์ ํ๊ณ ์๋๋ฐ, ๊ทธ ์ด์ ๋ฅผ ์ฐพ์๋ค. ์ง๊ธ authToken ๋ชจ๋ธ์ ์์ฑํ๊ณ User ๋ชจ๋ธ์ ๋ฑ๋กํ๋ ๊ฒ์์ ์๋ฌ๊ฐ ๋ฐ์ํ๊ณ ์๋ค. ๊ทธ ์ด์ ๋ ํ ์ด๋ธ์ด ์์ฑ๋ ๋ ๋ด๊ฐ ์๊ฐํ๋ ํ ์ด๋ธ๊ฐ ๊ด๊ณ๊ฐ ์๋ชป ์ค์ ๋๋ ๊ฒ ๊ฐ๋ค. ๋ญ๊ฐ entgo ์ฒ์์ด๋ผ ์ด๋ฐ ์ค์๋ฅผ ๋ง์ดํ๋ ๊ฒ ๊ฐ๋ค. ์ด์ ๋ ์ฐพ์์ง๋ง ์์ง ํด๊ฒฐํ์ง ๋ชปํ๋ค. ์ด๊ฑธ ๋นจ๋ฆฌ ๊ณ ์ณ์ผ ํฌ์คํธ ์์ฑ ๋ถ๋ถ์ ์งํ ํ ํ ๋ฐ...
- ๋ก์ปฌ ํ์๊ฐ์ / ๋ก๊ทธ์ธ API - (์ ๋ฒ ์ด์ผ๊ธฐ ์ด์ ์ฒ๋ฆฌ)
ํ ํฐ ๋ฐ๊ธ์ ๋ํ ์ด์๋ฅผ ์ฒ๋ฆฌํ๋ค. ๋๋ฌด ์ด๋ ต๊ฒ ์๊ฐํ๋ค. ๊ดํ ๊ด๊ณ๋ฅผ ๋ง๋ค๋ ค๋ค๊ฐ ๋ ๋ณต์กํด์ง๋ ๊ฒ ๊ฐ์์ column์ ๊ทธ๋ฅ user id๋ฅผ ์์ฑํ๊ณ ๋์ค์ ์กฐํ ํ ๋ join๋ฅผ ํ๋ฉด ๋๋๊ฑธ ์๊ฐํ์ง ๋ชปํ๋ค. ๊ทธ๋๋ ์ฑ๊ณต์ ์ผ๋ก ์ธ์ฆ์ด ๋๋ค.
๊ทธ๋ฆฌ๊ณ ์์ ๋ก๊ทธ์ธ์ ์ค๋นํ๊ณ ์๋ค. ์๋ง ํ์ด์ค๋ถ ๊นํ ์นด์นด์ค ๊ตฌ๊ธ์ ๋์ ํ ์์ ์ธ๋ฐ... ์์ง์ ํ์คํ์ง ์๋ค
- ๋ก์ปฌ ์ธ์ฆ API ๊ตฌํ ์๋ฃ
- ์์ ์ธ์ฆ ํ ์ด๋ธ ์์ฑ
- ์์ API ์ค๋น
์ค๋์ ์์ ์ธ์ฆ API๋ฅผ ๊ตฌํํ์๋ค. facebook, github๋ฅผ ๊ตฌํํ์๊ณ ์ถ๊ฐ์ ์ผ๋ก kakao๋ ๊ตฌ๊ธ์ ๊ตฌํ ํ ์์ ์ด๋ค. ์์ ์ ์งํํ๋ฉด์ golang์์ multiple type์ ๊ตฌํ์ด ๊ฐ๋ฅํ์ง ์๋ํด ๋ณผ๋ ค๊ณ ํ๋๋ฐ ํ๋ ๊ฒ ๊ฐ์์ ์ผ๋จ ์ฝ๊ฒ ๊ตฌํํ๋ ๋ฐฉ๋ฒ์ผ๋ก ๊ตฌํ
- ์์ callback ๊ตฌํ
์ค๋๋ ์ด๊น์์ด ์์ ์ธ์ฆ์ ๊ตฌํํ๊ณ ์๋ค. ์ผ๋จ ํ์ด์ค๋ถ ๊นํ์ ๋ํด์๋ accessToken, profile ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ค๊ณ ์์ง๋ง ์นด์นด์ค ๋ก๊ทธ์ธ์ ๊ฒฝ์ฐ์๋ token์ ๋ชป๊ฐ์ ธ์ค๊ณ ์๋ค. ์ผ๋จ ๋คํธ์ํฌ์์ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ค๋ ๊ฒ์ ์ฑ๊ณตํ ๊ฒ ๊ฐ์๋ฐ... ์กฐ๊ธ ๋ ๋ก๊น ์ด ํ์ํ ๊ฒ ๊ฐ๋ค. ๊ทธ๋ฆฌ๊ณ ์๋ ์์ ๋ก๊ทธ์ธ์ ๋๊ฒ ์ฝ๋ ์ค๋ณต, switch๋ฌธ์ ์ฌ์ฉ์ ํ์๋๋ฐ, ์ด๋ฒ์ ํจํด๋งค์นญ์ ๊ตฌํํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์์ด์ ์ฌ์ฉ์ ํ์๋ค, ๋งค์ด ๋ง์กฑ์ค๋ฝ๋ค.
- ํ์ด์ค๋ถ token, profile
- ๊นํ token, profile
- kakao
์ค๋๋ ๋๊ฐ์ด ์์ ์ธ์ฆ์ ๊ตฌํํ๊ณ ์๋ค. ์ผ๋จ kakao๋ก ๋ถํฐ token๊ณผ ์ ์ profile ์ ๋ณด๋ฅผ ์ ์์ ์ผ๋ก ๊ฐ์ ธ์ค๊ณ ์๋ค. ๊ทธ๋ฐ๋ฐ ํ๊ฐ์ง ๋ฌธ์ ๊ฐ ์๋ค. ์์ profile ์ ๋ณด๊ฐ ์ ๋ถ ํ์ ์ด ๋ฌ๋ผ์ ๊ณตํต์ ์ธ ์ฒ๋ฆฌ๊ฐ ์ด๋ ต๊ฒ ๋์๋ค. ๊ทธ๋์ profile๋ค์ ๊ฐ๊ฐ ํ์ฑ ํ ๊ณตํต๋ ํ์ ์ผ๋ก ์ฌ์ ์๋ฅผํด์ ๋ฆฌํดํด์ค์ผ๊ฒ ๋ค. ๊ทธ๋ฌ๋ฉด ์ค์ ์์ ํ์๊ฐ์ ๋ฐ ๋ก๊ทธ์ธ ๊ตฌํ์ด ๊ฐ๋ฅํด ์ง ๊ฒ ๊ฐ๋ค.
- kakao token, profile
์ด์ ์์ ์ธ์ฆ์ด ๊ฑฐ์ ๋๋๊ฐ๋ค.... ์ ๋ง ๊ธธ์๋ค... ์ด์ API๋ฅผ ํ ์คํธํ๋ฉด์ ์ ์ ๋ฅผ ์์ฑํ๊ณ ๋ก๊ทธ์ธํ๋ ํ ์คํธ๋ง ์์ ํ๋ฉด ๋์ด๋ค. ๊ทธ๋ผ ์์ฑ ํ์ด์ง๋ฅผ ์์ ํ๋ฉด ๋ ๊ฒ ๊ฐ๋ค.
- ์์ ์ธ์ฆ ๊ธฐ๋ฅ (1)
์ ๋ง ์์ ์ธ์ฆ์ด ์ ๋ง ๊ธธ์ ์งํํ๋ ๊ฒ ๊ฐ๋ค. ๋ญ๊ฐ ์์ธ์ฒ๋ฆฌ๋ฅผ ์๊ฐํ๊ณ ์ข ๋ ์ฝ๊ณ ์ดํดํ๊ธฐ ์ฌ์ด ์ฝ๋๋ฅผ ์๊ฐํด์ ๋ ์ค๋ ๊ฑธ๋ฆฌ๋ ๊ฒ ๊ฐ๋ค. ๊ทธ๋๋ ์ ๋ง ๊ฑฐ์ ๋ค ๋๋๊ฐ๋ค. ์ด์ ์์ ํ์๊ฐ์ ๋ง ์ฒ๋ฆฌํ๋ฉด ์ ๋ง ๋์ด๋ค.
์์ ํ์ ๊ฐ์ ๋ค์์๋ ํฌ์คํธ ์์ฑ ํ์ด์ง๋ฅผ ์์ ํ๊ฒ ๋๋ค. ์ฌ๊ธฐ์ ๋ฐ์ํ๋ ์ด์๋ ์๋ง ํ๊ทธ ์ฒ๋ฆฌ๊ฐ ๋ ๊ฒ ๊ฐ๋ค. gorm์์๋ ๊ตฌํ์ ํ๋๋ฐ ๋ญ๊ฐ ๋ถ์กฑํ ๋๋์ ๋ง์ด ๋ฐ์๋๋ฐ ์ด๋ฒ์๋ ํจ์จ์ ์ผ๋ก ์ฒ๋ฆฌ ํ ๋ ค๊ณ ํ๋ค.
- ์์ ์ธ์ฆ ๊ธฐ๋ฅ (1)
- ์์ token์ผ๋ก profile ์ ๋ณด ๊ฐ์ ธ์ค๊ธฐ
์์ ํ์๊ฐ์ ์๋ฃ!!!
- ์์ ํ์๊ฐ์
์ค๋์ gorm ์ผ๋ก ์์ฑํ ๋ฏธ๋ค์จ์ด๋ฅผ entgo ๋ก ๋ณ๊ฒฝํ๋ ์์ ์ ์งํํ๋ค. ์ค๊ฐ์ ์๋ฒ๊ฐ ์คํ์ด ์๋๋ ์ด์๊ฐ ์์์ด๋๋ฐ database/sql ์ ์ฌ์ฉํด์ entgo ๋ฅผ ์คํํ๋ฉด sql driver๊ฐ ์๋๋ค๋ ์ด์๊ฐ ์์๋๋ฐ, entgo ๋ฌธ์์ github.com/jackc/pgx/v4/stdlib ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ค๋ ๋ด์ฉ์ ๋ณด๊ณ ์์ ํ๋ค.
- ๋ฏธ๋ค์จ์ด
์ค๋์ ๋๋์ด ํฌ์คํธ ์์ฑ API๋ฅผ ์์ ํ๋ค. ํ์ง๋ง ์์ ์ค ์๋นํ ๊ท์ฐฎ์ ๋ฒ๊ทธ๋ค์ด ๋ง์๋๋ฐ, ์ฒซ๋ฒ์งธ๋ import cycle not allowed์ด๋ค.
ํด๋น ์ค๋ฅ๋ Go๋ ์ํ ์ข ์์ฑ์ ์ง์ํ์ง ์๊ธฐ ๋๋ฌธ์ ์ปดํ์ผ ์๊ฐ ๋์ import cycle not allowed ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ ์ด์๊ฐ ์์๊ณ ๋๋ฒ์งธ๋ UrlSlug๋ด์ฉ์ด ์ด์ํ๊ฒ ์ ์ฅ๋๋ ์ด์์ด๋ค. ์ด๊ฑด ๋ค์๋ฒ์ ์์ ํด์ผ๊ฒ ๋ค.
- import cycle not allowed์ดํ ํด๋ ๊ตฌ์กฐ ๋ณ๊ฒฝ
- ํฌ์คํธ ์์ฑ API ์ถ๊ฐ
์ค๋์ ์ด์ ์์๋ ๋ฒ๊ทธ๋ค์ ์์ ํ๊ณ ํ๊ทธ ํ ์ด๋ธ์ ์์ฑํด์ ํฌ์คํธ ์์ฑ์ ์ถ๊ฐํ๋ ๋ก์ง์ ์์ฑํ๊ณ ์๋ค. ์ ์ ๋น์ทํ ์์ ์ ํ์๋๋ฐ ์ด๋ฒ์๋ ์ข ๋ golang ์ค๋ฌ์ด ๋ฐฉ๋ฒ์ผ๋ก ์์ ์ ํ ๋ ค๊ณ ํ๋ค. ๋ฌด์๋ณด๋ค ์ ์ ๊ตฌํํ ์ฝ๋๋ ์ค๋ณต๋ฐ ์ธ๋ฐ์๋ ์์ ๋ ๊ฐ์ด ํ ๊ฒ ๊ฐ์์ ๊ทธ ๋ถ๋ถ์ ์์ ํ ์์ ์ด๋ค.
- ํ๊ทธ ๋ชจ๋ธ ์์ฑ
- ํฌ์คํธ ์์ฑ API ์ด์ ์ฒ๋ฆฌ (urlSlug)
- ํฌ์คํธ ์์ฑ API์์ ํ๊ทธ ์ฐ๊ฒฐ (1)
์ค๋์ ํฌ์คํธ ์์ฑํ๋ API ์์ ์ด ๋๋ฌ๋ค. ๋๋์ด ์ด์ ์ ๋ฐ์ดํธํ๋ API, ์์ธ API๋ฅผ ๋ง๋ค๋ฉด ๋๋ต์ ์ธ ํฌ์คํธ ์์ ์ด ๋๋๊ณ ๋ฆฌ์คํธ๊น์ง ์์ฑํ๋ฉด ๋๊ฒ ๋ค
- ํฌ์คํธ ์์ฑ