Service ์ฌ์ฉ ๊ฐ์
Namespace ํธ์ถ
UserService.getUser() ๊ฐ๊ฒฐํ ๋ฌธ๋ฒ
ํ์ ์์
์๋ ์์ฑ ์ปดํ์ผ ๊ฒ์ฆ
Subset ์ง์
ํ์ํ ํ๋๋ง ์ฑ๋ฅ ์ต์ ํ
TanStack Query
useUser Hook ์๋ ์บ์ฑ
๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ
Service Import
์์ฑ๋ Service๋services.generated.ts์์ Namespace๋ก export๋ฉ๋๋ค.
- ์ผ๊ด์ฑ: ๋ชจ๋ Service๊ฐ ํ ๊ณณ์์ ๊ด๋ฆฌ๋จ
- ๊ฐํธํ import: ํ์ผ ๊ฒฝ๋ก ์ฐพ์ ํ์ ์์
- ์๋ ์
๋ฐ์ดํธ:
pnpm generate์ ์๋์ผ๋ก ๋๊ธฐํ - ๋ช ํํ ๋ค์ด๋ฐ: Namespace๋ก ๊ทธ๋ฃนํ๋์ด ์ถฉ๋ ์์
๊ธฐ๋ณธ API ํธ์ถ
Service์ ์ ์ ํจ์๋ฅผ ์ง์ ํธ์ถํฉ๋๋ค.await์ผ๋ก ๋น๋๊ธฐ ํธ์ถ- ์๋ต์ ์๋์ผ๋ก ํ์ฑ๋จ (fetch ํจ์ ๋ด๋ถ ์ฒ๋ฆฌ)
- ํ์ ์ด ์์ ํ ๋ณด์ฅ๋จ
- Subset ํ๋ผ๋ฏธํฐ ํ์ (getUser ๋ฑ)
Namespace ๊ธฐ๋ฐ ๊ตฌ์กฐ: - โ ํด๋์ค ์ธ์คํด์ค:
new UserService() ๋ถํ์ - โ
์ ์ ํจ์:
UserService.getUser() ์ง์ ํธ์ถ - ๋ชจ๋ ํจ์๊ฐ ๋
๋ฆฝ์ ์ผ๋ก ๋์Subset ์์คํ ์ดํดํ๊ธฐ
Sonamu์ ํต์ฌ ๊ธฐ๋ฅ์ธ Subset ์์คํ ์ ๋๋ค.- ์ฑ๋ฅ: ํ์ํ ํ๋๋ง ์กฐํํ์ฌ ๋คํธ์ํฌ ๋น์ฉ ์ ๊ฐ
- ํ์ ์์ : ๊ฐ Subset๋ง๋ค ์ ํํ ํ์ ๋ฐํ
- ๋ช ์์ฑ: ์ด๋ค ๋ฐ์ดํฐ๊ฐ ํ์ํ์ง ์ฝ๋์์ ๋ช ํํ ํํ
React์์ ์ฌ์ฉํ๊ธฐ
TanStack Query Hook (๊ถ์ฅ)
๊ฐ์ฅ ๊ฐํธํ ๋ฐฉ๋ฒ์ ์๋ ์์ฑ๋ TanStack Query Hook์ ์ฌ์ฉํ๋ ๊ฒ์ ๋๋ค.- ์๋ ์บ์ฑ (๊ฐ์ userId ์ฌ์ฌ์ฉ)
- ์๋ ์ฌ๊ฒ์ฆ (ํฌ์ปค์ค ์, ์ฌ์ฐ๊ฒฐ ์)
- ๋ก๋ฉ/์๋ฌ ์ํ ์๋ ๊ด๋ฆฌ
- ์ค๋ณต ์์ฒญ ์๋ ์ ๊ฑฐ
ํจ์ ์ปดํฌ๋ํธ (useEffect)
Hook์ ์ฌ์ฉํ์ง ์๊ณ ์ง์ ํธ์ถํ ์๋ ์์ต๋๋ค.๊ถ์ฅ: ๊ฐ๋ฅํ๋ฉด TanStack Query Hook์ ์ฌ์ฉํ์ธ์. ์๋ ์บ์ฑ, ์ฌ๊ฒ์ฆ, ์ํ ๊ด๋ฆฌ๋ฅผ ๋ชจ๋ ์ ๊ณตํ์ฌ
์ฝ๋๊ฐ ํจ์ฌ ๊ฐ๊ฒฐํด์ง๋๋ค.
์ด๋ฒคํธ ํธ๋ค๋ฌ
์ฌ์ฉ์ ์ก์ ์ ๋ฐ๋ผ API๋ฅผ ํธ์ถํฉ๋๋ค.useTypeForm์ผ๋ก ํผ ์ฒ๋ฆฌํ๊ธฐ (๊ถ์ฅ)
@sonamu-kit/react-components์ useTypeForm์ ์ฌ์ฉํ๋ฉด ํ์
์์ ํ ํผ์ ๋ ๊ฐํธํ๊ฒ ์์ฑํ ์ ์์ต๋๋ค.
- โ ํ์ ์์ : Zod ์คํค๋ง์์ ํ์ ์๋ ์ถ๋ก
- โ ์๋ ์ ํจ์ฑ ๊ฒ์ฌ: ์คํค๋ง ๊ท์น ์๋ ์ ์ฉ
- โ
๊ฐ๊ฒฐํ ์ฝ๋:
useState+ ์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ถํ์ - โ ์๋ฌ ์ฒ๋ฆฌ: ํ๋๋ณ ์๋ฌ ๋ฉ์์ง ์๋ ๊ด๋ฆฌ
- โ ํตํฉ ์ปดํฌ๋ํธ: Input, Button ๋ฑ ์ฆ์ ์ฌ์ฉ ๊ฐ๋ฅ
๊ถ์ฅ: ์๋ก์ด ํผ์ ์์ฑํ ๋๋
useTypeForm์ ์ฌ์ฉํ์ธ์. ๋ณด์ผ๋ฌํ๋ ์ดํธ ์ฝ๋๋ฅผ ํฌ๊ฒ ์ค์ด๊ณ
ํ์
์์ ์ฑ์ ๋ณด์ฅํฉ๋๋ค.SSR์์ Service ์ฌ์ฉํ๊ธฐ
Sonamu๋ Vite + React ๊ธฐ๋ฐ์ SSR์ ์ง์ํฉ๋๋ค. SSR์์๋queries.generated.ts์ ์๋ ์์ฑ๋ SSR ์ ์ฉ Service๋ฅผ ์ฌ์ฉํฉ๋๋ค.
SSR Service๋?
ํ๋ก ํธ์๋ Service(services.generated.ts)์๋ ๋ณ๊ฐ๋ก, ๋ฐฑ์๋์ SSR ์ ์ฉ Service๊ฐ ์๋ ์์ฑ๋ฉ๋๋ค.
registerSSR์์ ์ฌ์ฉ
SSR ๋ผ์ฐํธ๋ฅผ ๋ฑ๋กํ ๋ ์ด Service๋ฅผ ์ฌ์ฉํฉ๋๋ค.ํ๋ก ํธ์๋ Service vs SSR Service
ํต์ฌ ์ฐจ์ด์ : SSR Service๋ HTTP ์์ฒญ ์์ด ๋ฐฑ์๋ Model ๋ฉ์๋๋ฅผ ์ง์ ์คํํ๋ฏ๋ก ๋คํธ์ํฌ
์ค๋ฒํค๋๊ฐ ์์ต๋๋ค.
๋ ์์๋ณด๊ธฐ
SSR์ ๋ํ ์์ธํ ๋ด์ฉ์ ๋ค์ ๋ฌธ์๋ฅผ ์ฐธ๊ณ ํ์ธ์.๋ฐ์ดํฐ ํ๋ฆฌ๋ก๋ฉ
registerSSR๋ก ์๋ฒ์์ ๋ฐ์ดํฐ ๋ฏธ๋ฆฌ ๋ก๋ํ๊ธฐ
SSR ์ค์
SSR ์์คํ
์ดํดํ๊ธฐ
Service ์์ฑ ๋ฉ์ปค๋์ฆ ์ดํดํ๊ธฐ
Service๋ Namespace ๊ธฐ๋ฐ์ ์ ์ ํจ์ ๋ชจ์์ ๋๋ค.Service๋ ํด๋์ค๊ฐ ์๋ Namespace
- ๋ฌด์ํ (Stateless): ์ธ์คํด์ค๋ฅผ ์์ฑํ์ง ์์
- ์ ์ ํธ์ถ:
UserService.getUser()์ง์ ํธ์ถ - ํ์ ์์ : TypeScript Namespace๋ก ์๋ฒฝํ ํ์ ์ถ๋ก
- ํธ๋ฆฌ ์ ฐ์ดํน: ์ฌ์ฉํ์ง ์๋ ํจ์๋ ๋ฒ๋ค์ ํฌํจ ์๋จ
Service๋ ์์กด์ฑ ์ฃผ์ (DI)์ด ์์
Service๋ ์์ ํจ์์ด๋ฏ๋ก ์์กด์ฑ์ด ์ฃผ์ ๋์ง ์์ต๋๋ค:Service ์์ฑ ๊ณผ์
์์ฑ ๋จ๊ณ:- ๋ฐฑ์๋: Model์
@api๋ฐ์ฝ๋ ์ดํฐ ์์ฑ - Sonamu Sync:
pnpm sonamu sync์คํ - ์๋ ์์ฑ:
services.generated.tsํ์ผ ์์ฑ - Namespace ํจ์: ๊ฐ API ๋ฉ์๋๊ฐ Namespace ํจ์๋ก ๋ณํ
- Hook ์์ฑ: GET ๋ฉ์๋๋
useQueryHook ์๋ ์์ฑ
Model Instance๋ ์ด๋์ ์๋์?
Server Components์์ ์ง์ ์์ฑ:new UserModel()์ ํด๋ ๋๋์?
- Model์ ๋ฌด์ํ์ด๋ฏ๋ก ๋งค๋ฒ ์๋ก ์์ฑํด๋ ์์
- Constructor์์ ์ด๊ธฐํํ๋ ๊ฒ์ Subset ์ฟผ๋ฆฌ๋ฟ
- Context๋
Sonamu.getContext()๋ก ๋์ ์ผ๋ก ๊ฐ์ ธ์ด
Service vs Model ๋น๊ต
๊ถ์ฅ ํจํด: - Client Component: Service ์ฌ์ฉ - Server Component: Model ์ง์ ์ฌ์ฉ -
API ์๋ํฌ์ธํธ: Model์
@api ๋ฐ์ฝ๋ ์ดํฐClient Components
Client Components์์๋ Service๋ฅผ ์์ ๋กญ๊ฒ ์ฌ์ฉํ ์ ์์ต๋๋ค.์๋ฌ ์ฒ๋ฆฌ
SonamuError ์ฒ๋ฆฌ
Service ํธ์ถ ์ ๋ฐ์ํ๋ ์๋ฌ๋ฅผ ํ์ ์์ ํ๊ฒ ์ฒ๋ฆฌํฉ๋๋ค.React์์ ์๋ฌ ์ฒ๋ฆฌ
๊ณ ๊ธ ํจํด
๋ณ๋ ฌ ์์ฒญ
์ฌ๋ฌ API๋ฅผ ๋์์ ํธ์ถํ์ฌ ์ฑ๋ฅ์ ํฅ์์ํต๋๋ค.- ์์ฐจ: 300ms + 200ms + 150ms = 650ms
- ๋ณ๋ ฌ: max(300ms, 200ms, 150ms) = 300ms
Subset ํ์ฉ ์ต์ ํ
์ํฉ์ ๋ฐ๋ผ ์ ์ ํ Subset์ ์ ํํฉ๋๋ค.TanStack Query ํ์ฉ
์กฐ๊ฑด๋ถ ํ์นญ
์บ์ ๋ฌดํจํ
Prefetching
์ค์ ์์
์ ์ฒด CRUD ํ๋ก์ฐ
์ฃผ์์ฌํญ
๋ค์ ๋จ๊ณ
Service ๋์ ์๋ฆฌ
์๋ ์์ฑ ์ดํดํ๊ธฐ
TanStack Query Hook
React์์ ๋ ์ฝ๊ฒ
์ธ์ฆ
์ธ์ฆ ์์คํ
์๋ฌ ์ฒ๋ฆฌ
์๋ฌ ์ฒ๋ฆฌ ํจํด