"μν€ν μ²μ λν΄ κ³ λ―Όμ΄ μμΌμ κ°μ?"λΌλ μ§λ¬Έμ λν λ΅λ³ μ λ΅ κ°μ΄λ
λ΅λ³ μ λ΅: "μν€ν μ²λΌκ³ νλ©΄ λ²μκ° λμλ°, μ λ ν¬κ² 4κ°μ§ λ λ²¨λ‘ λλ μ κ³ λ―Όνκ³ μμ΅λλ€." λΌκ³ μ΄μ λ λ€, λ©΄μ κ΄μ λ°μμ λ°λΌ κΉμ΄λ₯Ό μ‘°μ ν©λλ€.
μν€ν μ² λΆλΆμ 5λ μ°¨ λ―ΈλκΈ νλ‘ νΈμλ κ°λ°μμ λ©΄μ μν©μ λ°μλ μ§λ¬Έμ λν κ°μΈμ μΈ λ΅λ³μ λλ€.
-
μμ€ν /μΈνλΌ μν€ν μ² π₯- λͺ¨λ리μ vs λ§μ΄ν¬λ‘μλΉμ€ vs BFF
- BFF λμ λ°°κ²½κ³Ό μΈμ¦/κΆν ν΅ν©
- 꼬리 μ§λ¬Έ λλΉ (SPOF, μ ν κΈ°μ€, BFF μν λ²μ)
-
νλ‘ νΈμλ μ ν리μΌμ΄μ μν€ν μ² π₯π₯- μνμ μ±κ²©μ λ°λ₯Έ λꡬ λΆλ¦¬ (μλ² μν / μ μ ν΄λΌμ΄μΈνΈ μν / λ κ±°μ)
- νΌν©ν ν΄λ ꡬ쑰 (feature κΈ°λ° + layer κΈ°λ°)
- 꼬리 μ§λ¬Έ λλΉ (Redux vs Zustand 곡쑴, React Query μν , feature ꡬ쑰 λ¨μ )
-
μ»΄ν¬λνΈ μ€κ³ μν€ν μ² π₯π₯- κ³΅ν΅ μ»΄ν¬λνΈ λν μ λ΅ (MUI λν)
- λΉμ¦λμ€ λ‘μ§ λ°°μΉ κΈ°μ€ (μ¬μ¬μ© μ¬λΆ)
- 꼬리 μ§λ¬Έ λλΉ (λν λ¨μ , Presentational/Container, μΆμν μμ )
-
μ½λ μ€κ³ λ 벨 (κ΄μ¬μ¬ λΆλ¦¬/μμ‘΄μ± λ°©ν₯) π₯- μμ‘΄μ± λ°©ν₯ ν λ°©ν₯ μ μ§ (UI β Business Logic β Data Access)
- TypeScript νμ μμ€ν μ νμ©ν λ μ΄μ΄ κ° κ³μ½
- 꼬리 μ§λ¬Έ λλΉ (API/λλ©μΈ νμ λΆλ¦¬, κ³Όλν μΆμν, ν 곡μ λ°©λ²)
π κ΄λ ¨ μ£Όμ : νλ‘ νΈμλ μ ν리μΌμ΄μ μν€ν μ², μ½λ μ€κ³ λ 벨, CS - λ€νΈμν¬
νμ¬ νλ‘μ νΈμμλ λͺ¨λ리μ, λ§μ΄ν¬λ‘μλΉμ€, BFFλ₯Ό λͺ¨λ κ²½ννμ΅λλ€. μ΄κΈ°μλ λͺ¨λ리μ κ΅¬μ‘°λ‘ λΉ λ₯΄κ² κ°λ°νμ§λ§, μλΉμ€κ° μ±μ₯νλ©΄μ λλ©μΈλ³λ‘ λ§μ΄ν¬λ‘μλΉμ€λ‘ λΆλ¦¬νκ² λμμ΅λλ€.
κ·Έ κ³Όμ μμ νλ‘ νΈμλκ° μ¬λ¬ λ§μ΄ν¬λ‘μλΉμ€μ μ§μ ν΅μ νλ©΄μ μΈμ¦/κΆν μ²λ¦¬κ° λΆμ°λλ λ¬Έμ κ° μκ²Όμ΅λλ€. κ° μλΉμ€λ§λ€ ν ν° κ²μ¦ λ‘μ§μ΄ μ€λ³΅λκ³ , νλ‘ νΈμλμμ μ¬λ¬ μλΉμ€μ μΈμ¦ μνλ₯Ό κ΄λ¦¬ν΄μΌ νμ£ .
μ΄λ₯Ό ν΄κ²°νκΈ° μν΄ BFF λ μ΄μ΄λ₯Ό λμ ν΄μ μΈμ¦/κΆν μ²λ¦¬λ₯Ό ν κ³³μΌλ‘ ν΅ν©νμ΅λλ€. νλ‘ νΈμλλ BFFλ§ λ°λΌλ³΄κ³ , BFFκ° κ° λ§μ΄ν¬λ‘μλΉμ€μ μΈμ¦λ μμ²μ μ λ¬νλ ꡬ쑰μ λλ€.
| μμ μ§λ¬Έ | λ΅λ³ ν¬μΈνΈ |
|---|---|
| BFF λμ ν λ¨μ μ? | BFFκ° λ¨μΌ μ₯μ μ (SPOF)μ΄ λ μ μκ³ , BFF μ체μ λ°°ν¬/κ΄λ¦¬ λΆλ΄ μ¦κ°. μ΄λ₯Ό μν΄ health checkμ graceful shutdown μ μ© |
| λͺ¨λ리μμμ λ§μ΄ν¬λ‘μλΉμ€λ‘ μ ν κΈ°μ€μ? | ν κ·λͺ¨ νλ, λ 립 λ°°ν¬ νμμ±, λλ©μΈ κ²½κ³κ° λͺ νν΄μ‘μ λ |
| BFFμμ μΈμ¦ μΈμ λ€λ₯Έ μν λ νλ? | λ°μ΄ν° μ§κ³(aggregation)λ μΌλΆ μννμ§λ§, κ³Όλν λΉμ¦λμ€ λ‘μ§μ λ£μ§ μμΌλ € νλ€ |
π κ΄λ ¨ μ£Όμ : μμ€ν /μΈνλΌ μν€ν μ², μ»΄ν¬λνΈ μ€κ³ μν€ν μ², μ½λ μ€κ³ λ 벨, React - μν κ΄λ¦¬
νλ‘ νΈμλ μ ν리μΌμ΄μ λ 벨μμλ μνμ μ±κ²©μ λ°λΌ λꡬλ₯Ό λΆλ¦¬νλ κ²μ κ°μ₯ μ€μνκ² μκ°ν©λλ€.
μνλ₯Ό ν¬κ² μΈ κ°μ§λ‘ λλλλ€:
- μλ² μν (λΉλκΈ° λ°μ΄ν°): React Queryλ‘ κ΄λ¦¬ν©λλ€. μΊμ±, 리νμΉ, λ‘λ©/μλ¬ μνλ₯Ό μ μΈμ μΌλ‘ μ²λ¦¬ν μ μμ΄μ, μμ μ Reduxμμ isLoading, error, dataλ₯Ό μΌμΌμ΄ κ΄λ¦¬νλ 보μΌλ¬νλ μ΄νΈλ₯Ό ν¬κ² μ€μμ΅λλ€.
- μ μ ν΄λΌμ΄μΈνΈ μν (μΈμ¦ μ 보, ν λ§ λ±): Zustandλ₯Ό μ¬μ©ν©λλ€. Redux λλΉ λ³΄μΌλ¬νλ μ΄νΈκ° μ κ³ , νμν μ¬λΌμ΄μ€λ§ ꡬλ ν μ μμ΄ λ¦¬λ λλ§ μ΅μ νκ° μ½μ΅λλ€.
- λ κ±°μ/볡μ‘ν μν: κΈ°μ‘΄ μ½λλ² μ΄μ€μ Redux Toolkitμ΄ μ΄λ―Έ μλ κ²½μ° μ μ§νλ, μλ‘μ΄ κΈ°λ₯μμλ μ μ‘°ν©μ μ°μ μ¬μ©ν©λλ€.
ν΄λ ꡬ쑰λ νΌν©νμ μ¬μ©ν©λλ€. μ΅μμλ feature κΈ°λ°(
/features/auth,/features/dashboard)μΌλ‘ λλλ, feature λ΄λΆλ layer κΈ°λ°(components/,hooks/,api/,types/)μΌλ‘ ꡬμ±ν©λλ€. 곡ν΅μΌλ‘ μ°μ΄λ κ²λ€μ/sharedλλ ν 리μ λ‘λλ€.
ν΄λ ꡬ쑰 μμ 보기
src/
βββ features/
β βββ auth/
β β βββ components/
β β βββ hooks/
β β βββ api/
β β βββ store/ # Zustand slice λλ Redux slice
β β βββ types/
β βββ dashboard/
β β βββ components/
β β βββ hooks/
β β βββ ...
βββ shared/
β βββ components/ # κ³΅ν΅ UI (Button, Modal λ±)
β βββ hooks/ # κ³΅ν΅ μ»€μ€ν
ν
β βββ utils/
β βββ types/
βββ app/ # λΌμ°ν
, νλ‘λ°μ΄λ μ€μ
βββ styles/ # κΈλ‘λ² ν
λ§, MUI 컀μ€ν°λ§μ΄μ§
| μμ μ§λ¬Έ | λ΅λ³ ν¬μΈνΈ |
|---|---|
| Reduxκ° μ΄λ―Έ μλλ° μ Zustandλ μ°λ? | μ μ§μ λ§μ΄κ·Έλ μ΄μ . ν λ²μ κ°μμκΈ°λ³΄λ€ μ κΈ°λ₯λΆν° μ μ©νκ³ , νμ νμ΅ κ³‘μ λ κ³ λ € |
| React Queryμ Reduxλ μ΄λ»κ² 곡쑴? | μλ² μνλ React Query, ν΄λΌμ΄μΈνΈ μ μ© μνλ§ Redux/Zustand. μν μ΄ κ²ΉμΉμ§ μκ² κ²½κ³λ₯Ό λͺ νν νλ€ |
| feature κΈ°λ° κ΅¬μ‘°μ λ¨μ μ? | feature κ° κ³΅μ μ½λκ° μ λ§€ν λ /sharedλ‘ λΉΌμΌ νλ νλ¨μ΄ νμ. λ무 μ΄λ₯΄κ² λΉΌλ©΄ premature abstraction |
π κ΄λ ¨ μ£Όμ : νλ‘ νΈμλ μ ν리μΌμ΄μ μν€ν μ², μ½λ μ€κ³ λ 벨
μ»΄ν¬λνΈ μ€κ³μμ κ°μ₯ μ κ²½ μ°λ λΆλΆμ κ³΅ν΅ μ»΄ν¬λνΈμ μΌκ΄μ±κ³Ό λΉμ¦λμ€ λ‘μ§ λ°°μΉμ μ μ°μ±μ λλ€.
κ³΅ν΅ μ»΄ν¬λνΈλ MUIλ₯Ό λνν΄μ μ¬μ©ν©λλ€. MUIμ Button, Modal, TextField λ±μ κ·Έλλ‘ μ°μ§ μκ³ , νλ‘μ νΈμ λμμΈ μμ€ν μ λ§κ² λνλ μ»΄ν¬λνΈλ₯Ό λ§λλλ€. μ΄λ κ² νλ©΄ λμμΈ λ³κ²½μ΄λ λΌμ΄λΈλ¬λ¦¬ κ΅μ²΄ μ λν λ μ΄μ΄λ§ μμ νλ©΄ λκ³ , μ¬μ©νλ μͺ½μ μν₯μ λ°μ§ μμ΅λλ€.
MUI λν μμ μ½λ 보기
// shared/components/Button.tsx
const StyledButton = styled(MuiButton)({
// νλ‘μ νΈ κ³΅ν΅ μ€νμΌ
})
export const Button = ({ ...props }: ButtonProps) => <StyledButton {...props} />λΉμ¦λμ€ λ‘μ§μ μμΉλ μΌμ΄μ€λ§λ€ λ€λ₯΄κ² νλ¨ν©λλ€. κΈ°μ€μ ν΄λΉ λ‘μ§μ΄ μ¬μ¬μ©λλκ°μ λλ€:
- ν μ»΄ν¬λνΈμμλ§ μ°μ΄λ λ‘μ§: μ»΄ν¬λνΈ λ΄λΆμ λ‘λλ€. λΆνμν μΆμνλ₯Ό νΌνκΈ° μν΄μμ λλ€.
- μ¬λ¬ μ»΄ν¬λνΈμμ 곡μ λλ λ‘μ§: 컀μ€ν ν μΌλ‘ λΆλ¦¬ν©λλ€.
- UIμ 무κ΄ν μμ λΉμ¦λμ€ λ‘μ§: λ³λ μ νΈ ν¨μλ μλΉμ€ λ μ΄μ΄λ‘ λΆλ¦¬ν©λλ€.
μ²μλΆν° λΆλ¦¬ν기보λ€, μ€λ³΅μ΄ λ°μνλ μμ μ μΆμΆνλ κ²μ μ νΈν©λλ€. "λ λ²μ§Έ μ¬μ©μ²κ° μκΈΈ λ μΆμννλ€"λ μμΉμ λ°λ¦ λλ€.
| μμ μ§λ¬Έ | λ΅λ³ ν¬μΈνΈ |
|---|---|
| MUI λνμ λ¨μ μ? | λν λ μ΄μ΄κ° λκΊΌμμ§λ©΄ MUIμ propsλ₯Ό λ€ μ λ¬νκΈ° λ²κ±°λ‘μ. νμν propsλ§ μ΄μ΄λλ κ²κ³Ό μ λΆ μ΄μ΄λλ κ²μ νΈλ μ΄λμ€ν |
| Presentational/Container ν¨ν΄μ μ¬μ©νλ? | Hookμ λ±μ₯ μ΄νλ‘ μ격νκ² λλμ§ μμ§λ§, "λ‘μ§ μμ΄ λ λλ§λ§ νλ μ»΄ν¬λνΈ"μ "λ°μ΄ν°λ₯Ό μ‘°ν©νλ μ»΄ν¬λνΈ"μ ꡬλΆμ μ¬μ ν μ ν¨νλ€κ³ λ³Έλ€ |
| "λ λ²μ§Έ μ¬μ©μ²" μμΉμ΄ μ λ§λ κ²½μ°λ? | λͺ ννκ² κ³΅ν΅μ΄ λ κ²μ΄ μμλλ κ²½μ°(λμμΈ μμ€ν μ»΄ν¬λνΈ λ±)λ μ²μλΆν° λΆλ¦¬νλ€ |
π κ΄λ ¨ μ£Όμ : μμ€ν /μΈνλΌ μν€ν μ², νλ‘ νΈμλ μ ν리μΌμ΄μ μν€ν μ², μ»΄ν¬λνΈ μ€κ³ μν€ν μ²
μ½λ μ€κ³μμ κ°μ₯ μ€μνλ μμΉμ μμ‘΄μ± λ°©ν₯μ ν λ°©ν₯μΌλ‘ μ μ§νλ κ²μ λλ€.
νλ‘ νΈμλμμ μ΄λ₯Ό νμ΄λ³΄λ©΄, μλμ κ°μ λ μ΄μ΄λ₯Ό μμν©λλ€:
[UI Layer] β [Business Logic Layer] β [Data Access Layer] μ»΄ν¬λνΈ μ»€μ€ν ν / μλΉμ€ API νΈμΆ / React Query
- UI λ μ΄μ΄λ λΉμ¦λμ€ λ‘μ§ λ μ΄μ΄μ μμ‘΄νμ§λ§, κ·Έ λ°λλ μ λ©λλ€. 컀μ€ν ν μ΄ νΉμ μ»΄ν¬λνΈμ ꡬνμ μ νμκ° μμ΄μΌ ν©λλ€.
- Data Access λ μ΄μ΄λ API νΈμΆμ μΆμνν©λλ€. μ»΄ν¬λνΈκ° fetchλ axiosλ₯Ό μ§μ νΈμΆνμ§ μκ³ , React Queryμ 쿼리 ν μ΄λ λ³λ API ν¨μλ₯Ό ν΅ν΄ μ κ·Όν©λλ€.
μ΄ μμΉμ μ€μ§μ μ₯μ μ ν μ€νΈμ κ΅μ²΄κ° μ¬μμ§λ€λ κ²μ λλ€. API μλ΅ κ΅¬μ‘°κ° λ°λμ΄λ Data Access λ μ΄μ΄λ§ μμ νλ©΄ λκ³ , UIλ₯Ό 리λμμΈν΄λ λΉμ¦λμ€ λ‘μ§μ κ·Έλλ‘μ λλ€.
λν TypeScriptμ νμ μμ€ν μ νμ©ν΄μ λ μ΄μ΄ κ° κ³μ½(contract)μ λͺ μν©λλ€. API μλ΅ νμ , μ»΄ν¬λνΈ Props νμ , λλ©μΈ λͺ¨λΈ νμ μ λΆλ¦¬ν΄μ, ν λ μ΄μ΄μ λ³κ²½μ΄ λ€λ₯Έ λ μ΄μ΄λ‘ μ νλλ λ²μλ₯Ό νμ 체ν¬λ‘ μ¦μ νμ ν μ μμ΅λλ€.
| μμ μ§λ¬Έ | λ΅λ³ ν¬μΈνΈ |
|---|---|
| API μλ΅ νμ κ³Ό λλ©μΈ νμ μ μ λΆλ¦¬νλ? | API μλ΅μ snake_caseμΌ μ μκ³ , νλ‘ νΈ λλ©μΈμμ λΆνμν νλκ° μμ μ μλ€. λ³ν λ μ΄μ΄λ₯Ό λλ©΄ λ°±μλ λ³κ²½ μν₯μ μ΅μν |
| κ³Όλν μΆμνκ° λμ§ μλ? | μκ·λͺ¨ νλ‘μ νΈμμ μ€λ²μμ§λμ΄λ§μΌ μ μλ€. ν κ·λͺ¨μ νλ‘μ νΈ μλͺ μ κ³ λ €ν΄μ νλ¨νλ€ |
| μ΄ κ΅¬μ‘°λ₯Ό νμ μ΄λ»κ² 곡μ νλ? | ADR(Architecture Decision Record)μ΄λ μ½λ 리뷰 컨벀μ μΌλ‘ λ¬Έμν. μ λ©€λ² μ¨λ³΄λ© μ μ°Έκ³ μλ£λ‘ νμ© |
μ 리νλ©΄, μ λ μν€ν μ²λ₯Ό ν κ°μ§ μ λ΅μΌλ‘ 보기보λ€λ νλ‘μ νΈμ κ·λͺ¨, νμ μν©, λ³κ²½ κ°λ₯μ±μ λ°λΌ μ μ ν μμ€μ μ ννλ κ²μ΄ μ€μνλ€κ³ μκ°ν©λλ€.
μμ νλ‘μ νΈμμ λ§μ΄ν¬λ‘μλΉμ€λ μ격ν λ μ΄μ΄ λΆλ¦¬λ₯Ό μ μ©νλ©΄ μ€λ²μμ§λμ΄λ§μ΄ λκ³ , λ°λλ‘ ν° νλ‘μ νΈμμ ꡬ쑰 μμ΄ μ§ννλ©΄ μ μ§λ³΄μκ° μ΄λ €μμ§λλ€.
κ·Έλμ νμ **μ§κΈ μ΄ μμ€μ κ΅¬μ‘°κ° νμ¬ μν©μ μ μ νκ°?**λ₯Ό κ³ λ―Όνλ €κ³ ν©λλ€.