@@ -12,11 +12,11 @@ sidebar_position: 1
12
12
13
13
## ์ฌ์ฉ์ ๋ก๊ทธ์ธ ์ ๋ณด ์์ง ๋ฐฉ๋ฒ
14
14
15
- ์ฑ์์ ์ฌ์ฉ์๋ก๋ถํฐ ๋ก๊ทธ์ธ ์ ๋ณด๋ฅผ ์์งํ๋ ๋ฐฉ๋ฒ์ ์์๋ณด๊ฒ ์ต๋๋ค. ๋ง์ฝ์ OAuth๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ, OAuth ์ ๊ณต์์ ๋ก๊ทธ์ธ ํ์ด์ง๋ฅผ ์ฌ์ฉํ์ฌ [ 3๋จ๊ณ] ( #how-to-store-the-token-for-authenticated-requests ) ๋ก ๋ฐ๋ก ๋์ด๊ฐ ์ ์์ต๋๋ค.
15
+ ์ฑ์์ ์ฌ์ฉ์๋ก๋ถํฐ ๋ก๊ทธ์ธ ์ ๋ณด๋ฅผ ์์งํ๋ ๋ฐฉ๋ฒ์ ์์๋ณด๊ฒ ์ต๋๋ค. ๋ง์ฝ์ OAuth๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ, OAuth ์ ๊ณต์์ ๋ก๊ทธ์ธ page๋ฅผ ์ฌ์ฉํ์ฌ [ 3๋จ๊ณ] ( #how-to-store-the-token-for-authenticated-requests ) ๋ก ๋ฐ๋ก ๋์ด๊ฐ ์ ์์ต๋๋ค.
16
16
17
- ### ์ ์ฉ ๋ก๊ทธ์ธ ํ์ด์ง ๋ง๋ค๊ธฐ
17
+ ### ์ ์ฉ ๋ก๊ทธ์ธ page ๋ง๋ค๊ธฐ
18
18
19
- ์น์ฌ์ดํธ์์ ์ฌ์ฉ์ ์ด๋ฆ๊ณผ ๋น๋ฐ๋ฒํธ๋ฅผ ์
๋ ฅํ๋ ๋ก๊ทธ์ธ ํ์ด์ง๋ฅผ ์ ๊ณตํ๋ ๊ฒ์ด ์ผ๋ฐ์ ์
๋๋ค. ์ด๋ฌํ ํ์ด์ง๋ค์ ๊ตฌ์กฐ๊ฐ ๋จ์ํ์ฌ ๋ณ๋์ ๋ณต์กํ ๋ถํด ์์
์ด ํ์ํ์ง ์์ต๋๋ค. ๋ค๋ง, ๋ก๊ทธ์ธ๊ณผ ํ์๊ฐ์
์์์ ์ธํ์ด ๋น์ทํ๊ธฐ ๋๋ฌธ์, ๊ฒฝ์ฐ์ ๋ฐ๋ผ ๋ ์์์ ํ๋์ ํ์ด์ง์์ ํตํฉํ์ฌ ์ ๊ณตํ๊ธฐ๋ ํฉ๋๋ค.
19
+ ์น์ฌ์ดํธ์์ ์ฌ์ฉ์ ์ด๋ฆ๊ณผ ๋น๋ฐ๋ฒํธ๋ฅผ ์
๋ ฅํ๋ ๋ก๊ทธ์ธ page๋ฅผ ์ ๊ณตํ๋ ๊ฒ์ด ์ผ๋ฐ์ ์
๋๋ค. ์ด๋ฌํ page๋ค์ ๊ตฌ์กฐ๊ฐ ๋จ์ํ์ฌ ๋ณ๋์ ๋ณต์กํ ๋ถํด ์์
์ด ํ์ํ์ง ์์ต๋๋ค. ๋ค๋ง, ๋ก๊ทธ์ธ๊ณผ ํ์๊ฐ์
์์์ ์ธํ์ด ๋น์ทํ๊ธฐ ๋๋ฌธ์, ๊ฒฝ์ฐ์ ๋ฐ๋ผ ๋ ์์์ ํ๋์ page์์ ํตํฉํ์ฌ ์ ๊ณตํ๊ธฐ๋ ํฉ๋๋ค.
20
20
21
21
- ๐ pages
22
22
- ๐ login
@@ -28,9 +28,9 @@ sidebar_position: 1
28
28
29
29
๋ก๊ทธ์ธ๊ณผ ํ์๊ฐ์
์ปดํฌ๋ํธ๋ฅผ ๋ณ๋๋ก ๋ง๋ค๊ณ , ํ์์ ๋ฐ๋ผ index ํ์ผ์์ export ํ ์ ์์ต๋๋ค. ์ด ์ปดํฌ๋ํธ๋ค์ ์ฌ์ฉ์๋ก๋ถํฐ ๋ก๊ทธ์ธ ์ ๋ณด์ ์
๋ ฅ๋ฐ๋ ํผ์ ํฌํจํฉ๋๋ค.
30
30
31
- ### ๋ก๊ทธ์ธ ๋ค์ด์ผ๋ก๊ทธ ๋ง๋ค๊ธฐ
31
+ ### ๋ก๊ทธ์ธ widget ๋ง๋ค๊ธฐ
32
32
33
- ์ฑ์ ์ด๋์๋ ์ฌ์ฉํ ์ ์๋ ๋ก๊ทธ์ธ ๋ค์ด์ผ๋ก๊ทธ๊ฐ ํ์ํ๋ค๋ฉด, ์ด ๋ค์ด์ผ๋ก๊ทธ๋ฅผ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ์์ ฏ์ผ๋ก ๋ง๋๋ ๊ฒ์ด ์ข์ต๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ๋ถํ์ํ ์ธ๋ถํ๋ฅผ ํผํ๋ฉด์๋ ์ด๋ค ํ์ด์ง์์๋ ์ฝ๊ฒ ๋ก๊ทธ์ธ ๋ค์ด์ผ๋ก๊ทธ๋ฅผ ๋์ธ ์ ์์ต๋๋ค.
33
+ ์ฑ์ ์ด๋์๋ ์ฌ์ฉํ ์ ์๋ ๋ก๊ทธ์ธ ๋ค์ด์ผ๋ก๊ทธ๊ฐ ํ์ํ๋ค๋ฉด, ์ด ๋ค์ด์ผ๋ก๊ทธ๋ฅผ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ widget์ผ๋ก ๋ง๋๋ ๊ฒ์ด ์ข์ต๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ๋ถํ์ํ ์ธ๋ถํ๋ฅผ ํผํ๋ฉด์๋ ์ด๋ค page์์๋ ์ฝ๊ฒ ๋ก๊ทธ์ธ ๋ค์ด์ผ๋ก๊ทธ๋ฅผ ๋์ธ ์ ์์ต๋๋ค.
34
34
35
35
- ๐ widgets
36
36
- ๐ login-dialog
@@ -39,11 +39,11 @@ sidebar_position: 1
39
39
- ๐ index.ts
40
40
- other widgetsโฆ
41
41
42
- ๊ฐ์ด๋ ๋๋จธ์ง ๋ถ๋ถ์ ์ ์ฉ ํ์ด์ง ๋ฐฉ์์ ๋ํด ์ค๋ช
ํ๊ณ ์์ง๋ง, ๋์ผํ ์์น์ ๋ก๊ทธ์ธ ๋ค์ด์ผ๋ก๊ทธ์๋ ์ ์ฉํ ์ ์์ต๋๋ค.
42
+ ๊ฐ์ด๋ ๋๋จธ์ง ๋ถ๋ถ์ ์ ์ฉ page ๋ฐฉ์์ ๋ํด ์ค๋ช
ํ๊ณ ์์ง๋ง, ๋์ผํ ์์น์ ๋ก๊ทธ์ธ ๋ค์ด์ผ๋ก๊ทธ์๋ ์ ์ฉํ ์ ์์ต๋๋ค.
43
43
44
44
### ํด๋ผ์ด์ธํธ ์ธก ๊ฒ์ฆ
45
45
46
- ํนํ ํ์๊ฐ์
์ ๊ฒฝ์ฐ, ์ฌ์ฉ์๊ฐ ์
๋ ฅํ ๋ด์ฉ์ ๋ฌธ์ ๊ฐ ์์ ๋ ๋น ๋ฅด๊ฒ ํผ๋๋ฐฑ์ ์ ๊ณตํ๊ธฐ ์ํด ํด๋ผ์ด์ธํธ ์ธก ๊ฒ์ฆ์ ์ํํ๋ ๊ฒ์ด ์ข์ต๋๋ค. ์ด๋ฅผ ์ํด ๋ก๊ทธ์ธ ํ์ด์ง์ ` model ` ์ธ๊ทธ๋จผํธ์์ ๊ฒ์ฆ ๋ก์ง์ ๊ตฌํํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด JS/TS์์๋ [ Zod] [ ext-zod ] ์ ๊ฐ์ ์คํค๋ง ๊ฒ์ฆ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค:
46
+ ํนํ ํ์๊ฐ์
์ ๊ฒฝ์ฐ, ์ฌ์ฉ์๊ฐ ์
๋ ฅํ ๋ด์ฉ์ ๋ฌธ์ ๊ฐ ์์ ๋ ๋น ๋ฅด๊ฒ ํผ๋๋ฐฑ์ ์ ๊ณตํ๊ธฐ ์ํด ํด๋ผ์ด์ธํธ ์ธก ๊ฒ์ฆ์ ์ํํ๋ ๊ฒ์ด ์ข์ต๋๋ค. ์ด๋ฅผ ์ํด ๋ก๊ทธ์ธ page์ ` model ` segment์์ ๊ฒ์ฆ ๋ก์ง์ ๊ตฌํํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด JS/TS์์๋ [ Zod] [ ext-zod ] ์ ๊ฐ์ ์คํค๋ง ๊ฒ์ฆ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค:
47
47
48
48
``` ts title="pages/login/model/registration-schema.ts"
49
49
import { z } from " zod" ;
@@ -58,7 +58,7 @@ export const registrationData = z.object({
58
58
});
59
59
```
60
60
61
- ๊ทธ๋ฐ ๋ค์, ui ์ธ๊ทธ๋จผํธ์์ ์ด ์คํค๋ง๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ์ฉ์ ์
๋ ฅ์ ๊ฒ์ฆํ ์ ์์ต๋๋ค:
61
+ ๊ทธ๋ฐ ๋ค์, ui segment์์ ์ด ์คํค๋ง๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ์ฉ์ ์
๋ ฅ์ ๊ฒ์ฆํ ์ ์์ต๋๋ค:
62
62
63
63
``` tsx title="pages/login/ui/RegisterPage.tsx"
64
64
import { registrationData } from " ../model/registration-schema" ;
@@ -90,11 +90,11 @@ export function RegisterPage() {
90
90
91
91
## ๋ก๊ทธ์ธ ์ ๋ณด ์ ์ก ๋ฐฉ๋ฒ
92
92
93
- ๋ก๊ทธ์ธ ์ ๋ณด๋ฅผ ๋ฐฑ์๋ ์๋ฒ๋ก ์ ์กํ๊ธฐ ์ํ ์์ฒญ ํจ์๋ฅผ ์์ฑํ์ธ์. ์ด ํจ์๋ ์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ๋ฎคํ
์ด์
๋ผ์ด๋ธ๋ฌ๋ฆฌ(์: TanStack Query)๋ฅผ ์ฌ์ฉํ์ฌ ํธ์ถํ ์ ์์ต๋๋ค.
93
+ ๋ก๊ทธ์ธ ์ ๋ณด๋ฅผ ๋ฐฑ์๋ ์๋ฒ๋ก ์ ์กํ๊ธฐ ์ํ ์์ฒญ ํจ์๋ฅผ ์์ฑํ์ธ์. ์ด ํจ์๋ ์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ mutation ๋ผ์ด๋ธ๋ฌ๋ฆฌ(์: TanStack Query)๋ฅผ ์ฌ์ฉํ์ฌ ํธ์ถํ ์ ์์ต๋๋ค.
94
94
95
95
### ์์ฒญ ํจ์ ์ ์ฅ ์์น
96
96
97
- ์ด ์์ฒญ ํจ์๋ฅผ ์ ์ฅํ ์ ์๋ ์์น๋ ํฌ๊ฒ ๋ ๊ฐ์ง์
๋๋ค: ` shared/api ` ๋๋ ํ์ด์ง์ ` api ` ์ธ๊ทธ๋จผํธ์
๋๋ค .
97
+ ์ด ์์ฒญ ํจ์๋ฅผ ์ ์ฅํ ์ ์๋ ์์น๋ ํฌ๊ฒ ๋ ๊ฐ์ง์
๋๋ค: ` shared/api ` ๋๋ page์ ` api ` segment์
๋๋ค .
98
98
99
99
#### ` shared/api ` ์ ์ ์ฅํ๊ธฐ
100
100
@@ -108,7 +108,7 @@ export function RegisterPage() {
108
108
- ๐ client.ts
109
109
- ๐ index.ts
110
110
111
- ` ๐ client.ts ` ํ์ผ์ ์์ฒญ์ ์ํํ๋ ์์ ํจ์(์: ` fetch() ` )์ ๋ํ ๋ํผ๋ฅผ ํฌํจํฉ๋๋ค. ์ด ๋ํผ๋ ๋ฐฑ์๋์ ๊ธฐ๋ณธ URL ์ค์ , ํค๋ ์ค์ , ๋ฐ์ดํฐ ์ง๋ ฌํ ๋ฑ์ ์ฒ๋ฆฌํฉ๋๋ค.
111
+ ` ๐ client.ts ` ํ์ผ์ ์์ฒญ์ ์ํํ๋ ์์ ํจ์(์: ` fetch() ` )์ ๋ํ wrapper๋ฅผ ํฌํจํฉ๋๋ค. ์ด wrapper๋ ๋ฐฑ์๋์ ๊ธฐ๋ณธ URL ์ค์ , ํค๋ ์ค์ , ๋ฐ์ดํฐ ์ง๋ ฌํ ๋ฑ์ ์ฒ๋ฆฌํฉ๋๋ค.
112
112
113
113
``` ts title="shared/api/endpoints/login.ts"
114
114
import { POST } from " ../client" ;
@@ -122,9 +122,9 @@ export function login({ email, password }: { email: string, password: string })
122
122
export { login } from " ./endpoints/login" ;
123
123
```
124
124
125
- #### ํ์ด์ง์ ` api ` ์ธ๊ทธ๋จผํธ์ ์ ์ฅํ๊ธฐ
125
+ #### page์ ` api ` segment์ ์ ์ฅํ๊ธฐ
126
126
127
- ๋ก๊ทธ์ธ ์์ฒญ์ด ํน์ ํ์ด์ง์๋ง ํ์ํ ๊ฒฝ์ฐ, ๋ก๊ทธ์ธ ํ์ด์ง์ ` api ` ์ธ๊ทธ๋จผํธ์ ํจ์๋ฅผ ์ ์ฅํ ์ ์์ต๋๋ค:
127
+ ๋ก๊ทธ์ธ ์์ฒญ์ด ํน์ page์๋ง ํ์ํ ๊ฒฝ์ฐ, ๋ก๊ทธ์ธ page์ ` api ` segment์ ํจ์๋ฅผ ์ ์ฅํ ์ ์์ต๋๋ค:
128
128
129
129
- ๐ pages
130
130
- ๐ login
@@ -143,15 +143,15 @@ export function login({ email, password }: { email: string, password: string })
143
143
}
144
144
```
145
145
146
- ์ด ํจ์๋ ํ์ด์ง์ ๊ณต๊ฐ API์์ ๋ด๋ณด๋ผ ํ์๊ฐ ์์ต๋๋ค. ๋ก๊ทธ์ธ ์์ฒญ์ด ๋ค๋ฅธ ๊ณณ์์ ํ์ํ ๊ฐ๋ฅ์ฑ์ด ๋ฎ๊ธฐ ๋๋ฌธ์
๋๋ค.
146
+ ์ด ํจ์๋ page์ ๊ณต๊ฐ API์์ ๋ด๋ณด๋ผ ํ์๊ฐ ์์ต๋๋ค. ๋ก๊ทธ์ธ ์์ฒญ์ด ๋ค๋ฅธ ๊ณณ์์ ํ์ํ ๊ฐ๋ฅ์ฑ์ด ๋ฎ๊ธฐ ๋๋ฌธ์
๋๋ค.
147
147
148
148
### ์ด์ค ์ธ์ฆ(2FA)
149
149
150
- ์ฑ์ด ์ด์ค ์ธ์ฆ(2FA)์ ์ง์ํ๋ ๊ฒฝ์ฐ, ์ฌ์ฉ์๊ฐ ์ผํ์ฉ ๋น๋ฐ๋ฒํธ(OTP)๋ฅผ ์
๋ ฅํ ์ ์๋ ๋ณ๋์ ํ์ด์ง๋ก ์ด๋ํด์ผ ํ ์ ์์ต๋๋ค. ์ผ๋ฐ์ ์ผ๋ก ` POST /login ` ์์ฒญ์ ์ฌ์ฉ์๊ฐ 2FA๋ฅผ ํ์ฑํํ์์ ๋ํ๋ด๋ ํ๋๊ทธ๊ฐ ํฌํจ๋ ์ฌ์ฉ์ ๊ฐ์ฒด๋ฅผ ๋ฐํํฉ๋๋ค. ์ด ํ๋๊ทธ๊ฐ ์ค์ ๋๋ฉด ์ฌ์ฉ์๋ฅผ 2FA ํ์ด์ง๋ก ๋ฆฌ๋๋ ์
ํด์ผ ํฉ๋๋ค.
150
+ ์ฑ์ด ์ด์ค ์ธ์ฆ(2FA)์ ์ง์ํ๋ ๊ฒฝ์ฐ, ์ฌ์ฉ์๊ฐ ์ผํ์ฉ ๋น๋ฐ๋ฒํธ(OTP)๋ฅผ ์
๋ ฅํ ์ ์๋ ๋ณ๋์ page๋ก ์ด๋ํด์ผ ํ ์ ์์ต๋๋ค. ์ผ๋ฐ์ ์ผ๋ก ` POST /login ` ์์ฒญ์ ์ฌ์ฉ์๊ฐ 2FA๋ฅผ ํ์ฑํํ์์ ๋ํ๋ด๋ ํ๋๊ทธ๊ฐ ํฌํจ๋ ์ฌ์ฉ์ ๊ฐ์ฒด๋ฅผ ๋ฐํํฉ๋๋ค. ์ด ํ๋๊ทธ๊ฐ ์ค์ ๋๋ฉด ์ฌ์ฉ์๋ฅผ 2FA page๋ก ๋ฆฌ๋๋ ์
ํด์ผ ํฉ๋๋ค.
151
151
152
- 2FA ํ์ด์ง๋ ๋ก๊ทธ์ธ๊ณผ ๋ฐ์ ํ๊ฒ ์ฐ๊ด๋์ด ์์ผ๋ฏ๋ก Pages ๋ ์ด์ด์ ` login ` ์ฌ๋ผ์ด์ค์ ํจ๊ป ์ ์ฅํ๋ ๊ฒ์ด ์ข์ต๋๋ค.<br />
152
+ 2FA page๋ ๋ก๊ทธ์ธ๊ณผ ๋ฐ์ ํ๊ฒ ์ฐ๊ด๋์ด ์์ผ๋ฏ๋ก Pages layer์ ` login ` slice์ ํจ๊ป ์ ์ฅํ๋ ๊ฒ์ด ์ข์ต๋๋ค.<br />
153
153
154
- ์ด์ค ์ธ์ฆ์ ์ฒ๋ฆฌํ๊ธฐ ์ํด์๋ ` login() ` ํจ์์ ์ ์ฌํ ๋ ๋ค๋ฅธ ์์ฒญ ํจ์๊ฐ ํ์ํ ๊ฒ์
๋๋ค. ์ด๋ฌํ ํจ์๋ค์ ` Shared ` ๋ ๋ก๊ทธ์ธ ํ์ด์ง์ ` api ` ์ธ๊ทธ๋จผํธ์ ํจ๊ป ๋ฐฐ์นํ ์ ์์ต๋๋ค.
154
+ ์ด์ค ์ธ์ฆ์ ์ฒ๋ฆฌํ๊ธฐ ์ํด์๋ ` login() ` ํจ์์ ์ ์ฌํ ๋ ๋ค๋ฅธ ์์ฒญ ํจ์๊ฐ ํ์ํ ๊ฒ์
๋๋ค. ์ด๋ฌํ ํจ์๋ค์ ` Shared ` ๋ ๋ก๊ทธ์ธ page์ ` api ` segment์ ํจ๊ป ๋ฐฐ์นํ ์ ์์ต๋๋ค.
155
155
156
156
## ์ธ์ฆ๋ ์์ฒญ์ ํ ํฐ ์ ์ฅ ๋ฐฉ๋ฒ {#how-to-store-the-token-for-authenticated-requests}
157
157
@@ -163,7 +163,7 @@ export function login({ email, password }: { email: string, password: string })
163
163
164
164
### Shared์ ์ ์ฅํ๊ธฐ
165
165
166
- ` shared/api ` ์ ์ ์ฅํ๋ ์ ๊ทผ ๋ฐฉ์์ API ํด๋ผ์ด์ธํธ์ ์ ๋ง์๋จ์ด์ง๋๋ค. ์ธ์ฆ์ด ํ์ํ ๋ค๋ฅธ ์์ฒญ ํจ์์์ ์ด ํ ํฐ์ ์ฝ๊ฒ ์ฌ์ฉํ ์ ์๊ธฐ ๋๋ฌธ์
๋๋ค. API ํด๋ผ์ด์ธํธ์์ ๋ฐ์ํ ์คํ ์ด๋ ๋ชจ๋ ์์ค ๋ณ์๋ฅผ ์ฌ์ฉํด ํ ํฐ์ ์ ์ฅํ๊ณ , ` login()/logout() ` ํจ์์์ ํด๋น ์ํ๋ฅผ ์
๋ฐ์ดํธํ ์ ์์ต๋๋ค.
166
+ ` shared/api ` ์ ์ ์ฅํ๋ ์ ๊ทผ ๋ฐฉ์์ API ํด๋ผ์ด์ธํธ์ ์ ๋ง์๋จ์ด์ง๋๋ค. ์ธ์ฆ์ด ํ์ํ ๋ค๋ฅธ ์์ฒญ ํจ์์์ ์ด ํ ํฐ์ ์ฝ๊ฒ ์ฌ์ฉํ ์ ์๊ธฐ ๋๋ฌธ์
๋๋ค. API ํด๋ผ์ด์ธํธ์์ ๋ฐ์ํ store๋ module ์์ค ๋ณ์๋ฅผ ์ฌ์ฉํด ํ ํฐ์ ์ ์ฅํ๊ณ , ` login()/logout() ` ํจ์์์ ํด๋น ์ํ๋ฅผ ์
๋ฐ์ดํธํ ์ ์์ต๋๋ค.
167
167
168
168
ํ ํฐ ์๋ ๊ฐฑ์ ์ API ํด๋ผ์ด์ธํธ์์ ๋ฏธ๋ค์จ์ด ํํ๋ก ๊ตฌํํ ์ ์์ต๋๋ค. ๋ชจ๋ ์์ฒญ๋ง๋ค ์คํ๋๋ฉฐ, ์๋์ ๊ฐ์ ๋ฐฉ์์ผ๋ก ๋์ํฉ๋๋ค:
169
169
@@ -177,49 +177,49 @@ export function login({ email, password }: { email: string, password: string })
177
177
178
178
### Entities์ ์ ์ฅํ๊ธฐ
179
179
180
- FSD ํ๋ก์ ํธ์์๋ ์ฌ์ฉ์ ์ํฐํฐ ๋๋ ํ์ฌ ์ฌ์ฉ์ ์ํฐํฐ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ผ๋ฐ์ ์
๋๋ค. ๋ ์ํฐํฐ๋ ๊ฐ์ ๊ฒ์ ๊ฐ๋ฆฌํฌ ์๋ ์์ต๋๋ค.
180
+ FSD ํ๋ก์ ํธ์์๋ user entity ๋๋ current user entity๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ผ๋ฐ์ ์
๋๋ค. ๋ entity๋ ๊ฐ์ ๊ฒ์ ๊ฐ๋ฆฌํฌ ์๋ ์์ต๋๋ค.
181
181
182
182
::: note
183
183
184
184
** ํ์ฌ ์ฌ์ฉ์** ๋ "viewer" ๋๋ "me"๋ผ๊ณ ๋ ํฉ๋๋ค. ์ด๋ ๊ถํ๊ณผ ๊ฐ์ธ ์ ๋ณด๋ฅผ ๊ฐ์ง ๋จ์ผ ์ธ์ฆ ์ฌ์ฉ์์ ๊ณต๊ฐ์ ์ผ๋ก ์ ๊ทผ ๊ฐ๋ฅํ ์ ๋ณด๋ก ๊ตฌ์ฑ๋ ๋ชจ๋ ์ฌ์ฉ์ ๋ชฉ๋ก์ ๊ตฌ๋ณํ๊ธฐ ์ํด ์ฌ์ฉ๋ฉ๋๋ค.
185
185
186
186
:::
187
187
188
- User ์ํฐํฐ์ ํ ํฐ์ ์ ์ฅํ๋ ค๋ฉด ` model ` ์ธ๊ทธ๋จผํธ์ ๋ฐ์ํ ์คํ ์ด๋ฅผ ์์ฑํด์ผ ํฉ๋๋ค. ์ด ์คํ ์ด๋ ํ ํฐ๊ณผ ์ฌ์ฉ์ ๊ฐ์ฒด๋ฅผ ๋ชจ๋ ํฌํจํ ์ ์์ต๋๋ค.
188
+ User entity์ ํ ํฐ์ ์ ์ฅํ๋ ค๋ฉด ` model ` segment์ reactive store๋ฅผ ์์ฑํด์ผ ํฉ๋๋ค. ์ด store๋ ํ ํฐ๊ณผ user ๊ฐ์ฒด๋ฅผ ๋ชจ๋ ํฌํจํ ์ ์์ต๋๋ค.
189
189
190
- API ํด๋ผ์ด์ธํธ๋ ์ผ๋ฐ์ ์ผ๋ก ` shared/api ` ์ ์๋๊ฑฐ๋ ์ํฐํฐ ์ ์ฒด์ ๋ถ์ฐ๋์ด ์์ต๋๋ค. ๋ฐ๋ผ์ ์ฃผ์ ๊ณผ์ ๋ ๋ ์ด์ด์ ์ํฌํธ ๊ท์น([ import rule on layers] [ import-rule-on-layers ] )์ ์๋ฐํ์ง ์์ผ๋ฉด์ ๋ค๋ฅธ ์์ฒญ์์๋ ํ ํฐ์ ์ฌ์ฉํ ์ ์๋๋ก ํ๋ ๊ฒ์
๋๋ค.
190
+ API ํด๋ผ์ด์ธํธ๋ ์ผ๋ฐ์ ์ผ๋ก ` shared/api ` ์ ์๋๊ฑฐ๋ entity ์ ์ฒด์ ๋ถ์ฐ๋์ด ์์ต๋๋ค. ๋ฐ๋ผ์ ์ฃผ์ ๊ณผ์ ๋ layer์ ์ํฌํธ ๊ท์น([ import rule on layers] [ import-rule-on-layers ] )์ ์๋ฐํ์ง ์์ผ๋ฉด์ ๋ค๋ฅธ ์์ฒญ์์๋ ํ ํฐ์ ์ฌ์ฉํ ์ ์๋๋ก ํ๋ ๊ฒ์
๋๋ค.
191
191
192
- > ๋ ์ด์ด ๊ท์น: ์ฌ๋ผ์ด์ค์ ๋ชจ๋์ ์๊ธฐ๋ณด๋ค ๋ฎ์ ๋ ์ด์ด์ ์์นํ ๋ค๋ฅธ ์ฌ๋ผ์ด์ค๋ง ์ํฌํธํ ์ ์์ต๋๋ค.
192
+ > Layer ๊ท์น: slice์ module์ ์๊ธฐ๋ณด๋ค ๋ฎ์ layer์ ์์นํ ๋ค๋ฅธ slice๋ง importํ ์ ์์ต๋๋ค.
193
193
194
194
์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํ ๋ช ๊ฐ์ง ๋ฐฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
195
195
196
196
1 . ** ์์ฒญ ์๋ง๋ค ํ ํฐ ์๋ ์ ๋ฌ**
197
197
์ด ๋ฐฉ๋ฒ์ ๊ฐ์ฅ ๊ฐ๋จํ์ง๋ง, ๋ฒ๊ฑฐ๋กญ๊ณ ํ์
์์ ์ฑ์ด ๋ณด์ฅ๋์ง ์์ผ๋ฉด ์ค์๊ฐ ๋ฐ์ํ ๊ฐ๋ฅ์ฑ์ด ํฝ๋๋ค. ๋ํ Shared์ API ํด๋ผ์ด์ธํธ์ ๋ฏธ๋ค์จ์ด ํจํด์ ์ ์ฉํ๊ธฐ ์ด๋ ต์ต๋๋ค.
198
- 2 . ** ์ฑ ์ ์ญ์์ ๊ธ๋ก๋ฒ ์คํ ์ด๋ก ํ ํฐ ๊ด๋ฆฌ**
199
- ํ ํฐ์ context๋ ` localStorage ` ์ ์ ์ฅํ๊ณ , ` shared/api ` ์ ํ ํฐ ์ ๊ทผ ํค๋ฅผ ๋ณด๊ดํฉ๋๋ค. ํ ํฐ์ ๋ฐ์ํ ์ ์ฅ์๋ User ์ํฐํฐ์์ ๋ด๋ณด๋ด๋ฉฐ, ํ์ํ ๊ฒฝ์ฐ context Provider๋ App ๋ ์ด์ด์์ ์ค์ ํฉ๋๋ค. ์ด ๋ฐฉ๋ฒ์ API ํด๋ผ์ด์ธํธ ์ค๊ณ๋ฅผ ์ ์ฐํ๊ฒ ๋ง๋ค์ง๋ง, ์์ ๋ ์ด์ด์ context ์ ๊ณต์ด ํ์ํ๋ค๋ ์๋ฌต์ ์ธ ์์กด์ฑ์ ๋ฐ์์ํต๋๋ค. ๋ฐ๋ผ์ context๋ ` localStorage ` ๊ฐ ์ ๋๋ก ์ค์ ๋์ง ์์์ ๊ฒฝ์ฐ, ์ ์ฉํ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ์ ๊ณตํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
198
+ 2 . ** ์ฑ ์ ์ญ์์ ๊ธ๋ก๋ฒ store๋ก ํ ํฐ ๊ด๋ฆฌ**
199
+ ํ ํฐ์ context๋ ` localStorage ` ์ ์ ์ฅํ๊ณ , ` shared/api ` ์ ํ ํฐ ์ ๊ทผ ํค๋ฅผ ๋ณด๊ดํฉ๋๋ค. ํ ํฐ์ reactive store๋ User entity์์ ๋ด๋ณด๋ด๋ฉฐ, ํ์ํ ๊ฒฝ์ฐ context Provider๋ App layer์์ ์ค์ ํฉ๋๋ค. ์ด ๋ฐฉ๋ฒ์ API ํด๋ผ์ด์ธํธ ์ค๊ณ๋ฅผ ์ ์ฐํ๊ฒ ๋ง๋ค์ง๋ง, ์์ layer์ context ์ ๊ณต์ด ํ์ํ๋ค๋ ์๋ฌต์ ์ธ ์์กด์ฑ์ ๋ฐ์์ํต๋๋ค. ๋ฐ๋ผ์ context๋ ` localStorage ` ๊ฐ ์ ๋๋ก ์ค์ ๋์ง ์์์ ๊ฒฝ์ฐ, ์ ์ฉํ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ์ ๊ณตํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
200
200
3 . ** ํ ํฐ ๋ณ๊ฒฝ ์ API ํด๋ผ์ด์ธํธ ์
๋ฐ์ดํธ**
201
- ๋ฐ์ํ ์คํ ์ด๋ฅผ ํ์ฉํด ์ํฐํฐ์ ์คํ ์ด๊ฐ ๋ณ๊ฒฝ๋ ๋๋ง๋ค API ํด๋ผ์ด์ธํธ์ ํ ํฐ ์คํ ์ด๋ฅผ ์
๋ฐ์ดํธํ๋ ๊ตฌ๋
(subscribe)์ ์์ฑํ ์ ์์ต๋๋ค. ์ด ๋ฐฉ๋ฒ์ ์์ ๊ณ์ธต์ ์๋ฌต์ ์ธ ์์กด์ฑ์ ๋ง๋ ๋ค๋ ์ ์์๋ ์ด์ ํด๊ฒฐ์ฑ
๊ณผ ๋น์ทํ์ง๋ง, ์ด ๋ฐฉ๋ฒ์ ๋ "๋ช
๋ นํ(push)" ์ ๊ทผ์ด๊ณ , ์ด์ ๋ฐฉ๋ฒ์ ๋ "์ ์ธํ(pull)" ์ ๊ทผ์
๋๋ค.
201
+ reactive store๋ฅผ ํ์ฉํด entity์ store๊ฐ ๋ณ๊ฒฝ๋ ๋๋ง๋ค API ํด๋ผ์ด์ธํธ์ ํ ํฐ store๋ฅผ ์
๋ฐ์ดํธํ๋ ๊ตฌ๋
(subscribe)์ ์์ฑํ ์ ์์ต๋๋ค. ์ด ๋ฐฉ๋ฒ์ ์์ layer์ ์๋ฌต์ ์ธ ์์กด์ฑ์ ๋ง๋ ๋ค๋ ์ ์์๋ ์ด์ ํด๊ฒฐ์ฑ
๊ณผ ๋น์ทํ์ง๋ง, ์ด ๋ฐฉ๋ฒ์ ๋ "๋ช
๋ นํ(push)" ์ ๊ทผ์ด๊ณ , ์ด์ ๋ฐฉ๋ฒ์ ๋ "์ ์ธํ(pull)" ์ ๊ทผ์
๋๋ค.
202
202
203
- ์ํฐํฐ์ ` model ` ์ ํ ํฐ์ ์ ์ฅํ์ฌ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ฉด, ํ ํฐ ๊ด๋ฆฌ์ ๊ด๋ จ๋ ๋ ๋ง์ ๋น์ฆ๋์ค ๋ก์ง์ ์ถ๊ฐํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ` model ` ์ธ๊ทธ๋จผํธ์ ํ ํฐ ๋ง๋ฃ ์ ๊ฐฑ์ ํ๋ ๋ก์ง์ ์ถ๊ฐํ๊ฑฐ๋, ์ผ์ ์๊ฐ์ด ์ง๋๋ฉด ํ ํฐ์ ๋ฌดํจํํ๋ ๋ก์ง์ ํฌํจํ ์ ์์ต๋๋ค.
204
- ๋ฐฑ์๋์ ์์ฒญ์ ๋ณด๋ด์ผ ํ๋ ๊ฒฝ์ฐ์๋ User ์ํฐํฐ์ api ์ธ๊ทธ๋จผํธ๋ ` shared/api ` ๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
203
+ entity์ ` model ` segment์ ํ ํฐ์ ์ ์ฅํ์ฌ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ฉด, ํ ํฐ ๊ด๋ฆฌ์ ๊ด๋ จ๋ ๋ ๋ง์ ๋น์ฆ๋์ค ๋ก์ง์ ์ถ๊ฐํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ` model ` segment์ ํ ํฐ ๋ง๋ฃ ์ ๊ฐฑ์ ํ๋ ๋ก์ง์ ์ถ๊ฐํ๊ฑฐ๋, ์ผ์ ์๊ฐ์ด ์ง๋๋ฉด ํ ํฐ์ ๋ฌดํจํํ๋ ๋ก์ง์ ํฌํจํ ์ ์์ต๋๋ค.
204
+ ๋ฐฑ์๋์ ์์ฒญ์ ๋ณด๋ด์ผ ํ๋ ๊ฒฝ์ฐ์๋ User entity์ api segment๋ ` shared/api ` ๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
205
205
206
206
### Pages/Widgets์ ์ ์ฅํ๊ธฐ (๊ถ์ฅํ์ง ์์)
207
207
208
- ์ ํ๋ฆฌ์ผ์ด์
์ ์ญ์ ์ ์ฉ๋๋ ์ํ(์: ์ก์ธ์ค ํ ํฐ)๋ฅผ ํ์ด์ง๋ ์์ ฏ์ ์ ์ฅํ๋ ๊ฒ์ ๊ถ์ฅ๋์ง ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ๋ก๊ทธ์ธ ํ์ด์ง์ ` model ` ์ธ๊ทธ๋จผํธ์ ํ ํฐ ์คํ ์ด๋ฅผ ๋ฐฐ์นํ๋ ๋์ , ์ด ์ํฐํด์์ ์ ์ํ ์ฒ์ ๋ ํด๊ฒฐ์ฑ
์ธ Shared๋ Entities๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ๊ถ์ฅ๋ฉ๋๋ค.
208
+ ์ ํ๋ฆฌ์ผ์ด์
์ ์ญ์ ์ ์ฉ๋๋ ์ํ(์: ์ก์ธ์ค ํ ํฐ)๋ฅผ page๋ widget์ ์ ์ฅํ๋ ๊ฒ์ ๊ถ์ฅ๋์ง ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ๋ก๊ทธ์ธ page์ ` model ` segment์ ํ ํฐ store๋ฅผ ๋ฐฐ์นํ๋ ๋์ , ์ด ์ํฐํด์์ ์ ์ํ ์ฒ์ ๋ ํด๊ฒฐ์ฑ
์ธ Shared๋ Entities๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ๊ถ์ฅ๋ฉ๋๋ค.
209
209
210
210
## ๋ก๊ทธ์์ ๋ฐ ํ ํฐ ๋ฌดํจํ
211
211
212
- ๋ก๊ทธ์์ ๊ธฐ๋ฅ์ ์ ํ๋ฆฌ์ผ์ด์
์์ ์ค์ํ ๊ธฐ๋ฅ์ด์ง๋ง, ์ด๋ฅผ ์ํ ๋ณ๋์ ํ์ด์ง๋ ์๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค. ์ด ๊ธฐ๋ฅ์ ๋ฐฑ์๋์ ์ธ์ฆ๋ ์์ฒญ์ ๋ณด๋ด๊ณ , ํ ํฐ ์คํ ์ด๋ฅผ ์
๋ฐ์ดํธํ๋ ์์
์ผ๋ก ๊ตฌ์ฑ๋ฉ๋๋ค.
212
+ ๋ก๊ทธ์์ ๊ธฐ๋ฅ์ ์ ํ๋ฆฌ์ผ์ด์
์์ ์ค์ํ ๊ธฐ๋ฅ์ด์ง๋ง, ์ด๋ฅผ ์ํ ๋ณ๋์ page๋ ์๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค. ์ด ๊ธฐ๋ฅ์ ๋ฐฑ์๋์ ์ธ์ฆ๋ ์์ฒญ์ ๋ณด๋ด๊ณ , ํ ํฐ store๋ฅผ ์
๋ฐ์ดํธํ๋ ์์
์ผ๋ก ๊ตฌ์ฑ๋ฉ๋๋ค.
213
213
214
- ๋ชจ๋ ์์ฒญ์ ` shared/api ` ์ ๋ณด๊ดํ๋ค๋ฉด, ๋ก๊ทธ์ธ ํจ์ ๊ทผ์ฒ์ ๋ก๊ทธ์์ ์์ฒญ ํจ์๋ฅผ ๋๋ ๊ฒ์ด ์ข์ต๋๋ค. ๊ทธ๋ ์ง ์์ ๊ฒฝ์ฐ, ๋ก๊ทธ์์ ๋ฒํผ์ด ์๋ ์์น ๊ทผ์ฒ์ ๋ก๊ทธ์์ ์์ฒญ ํจ์๋ฅผ ๋ฐฐ์นํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ๋ชจ๋ ํ์ด์ง์ ๋ํ๋๋ ํค๋ ์์ ฏ์ ๋ก๊ทธ์์ ๋งํฌ๊ฐ ์๋ค๋ฉด, ํด๋น ์์ฒญ์ ๊ทธ ์์ ฏ์ ` api ` ์ธ๊ทธ๋จผํธ์ ๋ฐฐ์นํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
214
+ ๋ชจ๋ ์์ฒญ์ ` shared/api ` ์ ๋ณด๊ดํ๋ค๋ฉด, ๋ก๊ทธ์ธ ํจ์ ๊ทผ์ฒ์ ๋ก๊ทธ์์ ์์ฒญ ํจ์๋ฅผ ๋๋ ๊ฒ์ด ์ข์ต๋๋ค. ๊ทธ๋ ์ง ์์ ๊ฒฝ์ฐ, ๋ก๊ทธ์์ ๋ฒํผ์ด ์๋ ์์น ๊ทผ์ฒ์ ๋ก๊ทธ์์ ์์ฒญ ํจ์๋ฅผ ๋ฐฐ์นํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ๋ชจ๋ page์ ๋ํ๋๋ header widget์ ๋ก๊ทธ์์ ๋งํฌ๊ฐ ์๋ค๋ฉด, ํด๋น ์์ฒญ์ ๊ทธ widget์ ` api ` segment์ ๋ฐฐ์นํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
215
215
216
- ํ ํฐ ์คํ ์ด์ ๋ํ ์
๋ฐ์ดํธ๋ ๋ก๊ทธ์์ ๋ฒํผ์ด ์์นํ ๊ณณ(์: ํค๋ ์์ ฏ )์์ ํธ๋ฆฌ๊ฑฐ๋์ด์ผ ํฉ๋๋ค. ์ด ์์ฒญ๊ณผ ์คํ ์ด ์
๋ฐ์ดํธ๋ฅผ ํด๋น ์์ ฏ์ ` model ` ์ธ๊ทธ๋จผํธ์์ ๊ฒฐํฉํ ์ ์์ต๋๋ค.
216
+ ํ ํฐ store์ ๋ํ ์
๋ฐ์ดํธ๋ ๋ก๊ทธ์์ ๋ฒํผ์ด ์์นํ ๊ณณ(์: header widget )์์ ํธ๋ฆฌ๊ฑฐ๋์ด์ผ ํฉ๋๋ค. ์ด ์์ฒญ๊ณผ store ์
๋ฐ์ดํธ๋ฅผ ํด๋น widget์ ` model ` segment์์ ๊ฒฐํฉํ ์ ์์ต๋๋ค.
217
217
218
218
### ์๋ ๋ก๊ทธ์์
219
219
220
- ๋ก๊ทธ์์ ์์ฒญ ์คํจ๋ ๋ก๊ทธ์ธ ํ ํฐ ๊ฐฑ์ ์คํจ ์๋ฅผ ๋๋นํด ์์ ์ฅ์น๋ฅผ ๋ง๋ จํ๋ ๊ฒ๋ ์ค์ํฉ๋๋ค. ์ด ๋ ๊ฒฝ์ฐ ๋ชจ๋ ํ ํฐ ์คํ ์ด๋ฅผ ๋น์์ผ ํฉ๋๋ค. ํ ํฐ์ Entities์ ์ ์ฅํ๋ ๊ฒฝ์ฐ, ์ด ๋ก์ง์ ` model ` ์ธ๊ทธ๋จผํธ์ ๋ฐฐ์นํ ์ ์์ต๋๋ค. ํ ํฐ์ Shared์ ์ ์ฅํ๋ ๊ฒฝ์ฐ, ์ด ๋ก์ง์ ` shared/api ` ์ ํฌํจํ๋ฉด ์ธ๊ทธ๋จผํธ๊ฐ ๋๋ฌด ๋ณต์กํด์ง ์ ์์ต๋๋ค. ๋ฐ๋ผ์ ํ ํฐ ๊ด๋ฆฌ ๋ก์ง์ ๋ณ๋์ ์ธ๊ทธ๋จผํธ (์: ` shared/auth ` )๋ก ๋ถ๋ฆฌํ๋ ๊ฒ๋ ๊ณ ๋ คํด๋ณผ ๋งํฉ๋๋ค.
220
+ ๋ก๊ทธ์์ ์์ฒญ ์คํจ๋ ๋ก๊ทธ์ธ ํ ํฐ ๊ฐฑ์ ์คํจ ์๋ฅผ ๋๋นํด ์์ ์ฅ์น๋ฅผ ๋ง๋ จํ๋ ๊ฒ๋ ์ค์ํฉ๋๋ค. ์ด ๋ ๊ฒฝ์ฐ ๋ชจ๋ ํ ํฐ store๋ฅผ ๋น์์ผ ํฉ๋๋ค. ํ ํฐ์ Entities์ ์ ์ฅํ๋ ๊ฒฝ์ฐ, ์ด ๋ก์ง์ ` model ` segment์ ๋ฐฐ์นํ ์ ์์ต๋๋ค. ํ ํฐ์ Shared์ ์ ์ฅํ๋ ๊ฒฝ์ฐ, ์ด ๋ก์ง์ ` shared/api ` ์ ํฌํจํ๋ฉด segment๊ฐ ๋๋ฌด ๋ณต์กํด์ง ์ ์์ต๋๋ค. ๋ฐ๋ผ์ ํ ํฐ ๊ด๋ฆฌ ๋ก์ง์ ๋ณ๋์ segment (์: ` shared/auth ` )๋ก ๋ถ๋ฆฌํ๋ ๊ฒ๋ ๊ณ ๋ คํด๋ณผ ๋งํฉ๋๋ค.
221
221
222
222
[ tutorial-authentication ] : /docs/get-started/tutorial#authentication
223
223
[ import-rule-on-layers ] : /docs/reference/layers#import-rule-on-layers
224
224
[ ext-remix ] : https://remix.run
225
- [ ext-zod ] : https://zod.dev
225
+ [ ext-zod ] : https://zod.dev
0 commit comments