d8a80f6272
이름만 다른(표기 변형) [[위키링크]]를 대상 문서의 canonical 제목으로 치환해 끊겼던 1,200개 링크를 연결. 제목/파일명 정규화 일치만 적용하고 별칭 매칭은 과병합 위험으로 제외(애매성 가드). 원본은 _link_reconcile_backup/ 에 백업. 도구: Datacollect/scripts/link_reconcile_apply.mjs Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
7.6 KiB
7.6 KiB
id, title, category, status, canonical_id, aliases, duplicate_of, source_trust_level, confidence_score, verification_status, tags, raw_sources, last_reinforced, github_commit
| id | title | category | status | canonical_id | aliases | duplicate_of | source_trust_level | confidence_score | verification_status | tags | raw_sources | last_reinforced | github_commit | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| wiki-2026-0508-api-응답-모델링-및-상태-머신-state-machine | API Response Modeling + State Machine | 10_Wiki/Topics | verified | self |
|
none | B | 0.85 | applied |
|
2026-05-09 | pending |
API Response Modeling + State Machine
📌 한 줄 통찰
Discriminated union 의 baseline + state machine (XState) 의 complex flow. 매 invalid state + invalid transition 의 prevent. 매 actor model 의 modern.
📖 핵심
매 spectrum
Simple state (1-3 state)
- Discriminated union 충분.
- React useState.
Medium (4-6 state, parallel)
- useReducer / Zustand.
- Manual transition.
Complex (10+ state, hierarchy)
- XState / Robot.
- Visual editor.
- Statecharts.
매 statechart concept (Harel)
Hierarchical state
Authenticated:
- Browsing
- Editing
- Submitting
Unauthenticated:
- LoggingIn
- SigningUp
→ 매 sub-state 의 share parent transition.
Parallel state
[Editing] || [Saving]
→ 매 simultaneously.
History state
- 매 last state 의 remember.
- 매 modal close → previous state.
Guard
- 매 transition 의 condition.
Action
- 매 transition 의 side effect.
XState (TS)
Machine definition
import { createMachine, assign } from 'xstate';
const fetchMachine = createMachine({
id: 'fetch',
initial: 'idle',
context: { data: null, error: null },
states: {
idle: {
on: { FETCH: 'loading' }
},
loading: {
invoke: {
src: 'fetchData',
onDone: { target: 'success', actions: assign({ data: ({ event }) => event.output }) },
onError: { target: 'error', actions: assign({ error: ({ event }) => event.error }) },
}
},
success: {
on: { REFETCH: 'loading' }
},
error: {
on: { RETRY: 'loading' }
},
},
});
Usage (React)
import { useMachine } from '@xstate/react';
function Component() {
const [state, send] = useMachine(fetchMachine, {
services: { fetchData: () => api.fetch() }
});
if (state.matches('loading')) return <Spinner />;
if (state.matches('error')) return <Error msg={state.context.error} />;
if (state.matches('success')) return <Data data={state.context.data} />;
return <button onClick={() => send({ type: 'FETCH' })}>Load</button>;
}
매 advantage
Visual
- 매 state diagram 의 generate.
- 매 stakeholder 의 communicate.
Test
- 매 state + transition 의 explicit.
- 매 path 의 enumerate.
Documentation
- 매 code 의 self-documenting.
Refactor safety
- 매 invalid transition 의 compile fail.
매 limit
Learning curve
- 매 statechart 의 unfamiliar.
- 매 boilerplate.
Over-engineering
- 매 simple state 의 useState 의 enough.
XState 의 specific syntax
- 매 vendor lock-in.
Alternative
Robot
- 매 lighter weight.
- 매 simpler API.
useReducer (React)
- 매 native.
- 매 simple state machine.
Zustand + slice
- 매 store-based.
- 매 manual transition.
매 use case
Complex form
- 매 multi-step.
- 매 validation per step.
- 매 conditional branching.
Authentication flow
- 매 login → 2FA → success.
- 매 multiple path.
Game state
- 매 menu / playing / paused / game-over.
Real-time (chat, video call)
- 매 connecting / connected / disconnected / reconnecting.
Workflow
- 매 multi-stage approval.
💻 Code
Discriminated union (simple)
type State =
| { status: 'idle' }
| { status: 'loading' }
| { status: 'success'; data: User }
| { status: 'error'; message: string };
function reducer(state: State, action: Action): State {
switch (action.type) {
case 'FETCH':
return { status: 'loading' };
case 'SUCCESS':
return { status: 'success', data: action.payload };
case 'ERROR':
return { status: 'error', message: action.error };
}
}
useReducer
function Component() {
const [state, dispatch] = useReducer(reducer, { status: 'idle' });
useEffect(() => {
dispatch({ type: 'FETCH' });
api.fetch()
.then(data => dispatch({ type: 'SUCCESS', payload: data }))
.catch(e => dispatch({ type: 'ERROR', error: e.message }));
}, []);
// ...
}
XState (full)
import { setup, createMachine } from 'xstate';
const machine = setup({
types: { context: {}, events: {} as { type: 'NEXT' } | { type: 'PREV' } },
guards: {
canProceed: ({ context }) => context.formValid === true,
},
}).createMachine({
id: 'wizard',
initial: 'step1',
context: { formValid: false },
states: {
step1: {
on: { NEXT: { target: 'step2', guard: 'canProceed' } }
},
step2: {
on: { NEXT: 'step3', PREV: 'step1' }
},
step3: {
on: { PREV: 'step2', SUBMIT: 'submitting' }
},
submitting: {
invoke: {
src: 'submitForm',
onDone: 'success',
onError: 'step3',
}
},
success: { type: 'final' },
},
});
Hierarchical
const auth = createMachine({
id: 'auth',
initial: 'unauthenticated',
states: {
unauthenticated: {
initial: 'login',
states: {
login: { on: { SIGNUP: 'signup' } },
signup: { on: { LOGIN: 'login' } },
},
on: { AUTHENTICATED: 'authenticated' }
},
authenticated: {
initial: 'browsing',
states: {
browsing: { on: { EDIT: 'editing' } },
editing: { on: { SAVE: 'saving' } },
saving: { on: { DONE: 'browsing' } },
},
on: { LOGOUT: 'unauthenticated' }
},
},
});
Visual (XState VS Code extension)
- 매 .machine.ts file 의 visual.
- 매 state + transition 의 graphical.
Testing
import { createActor } from 'xstate';
test('login flow', () => {
const actor = createActor(authMachine).start();
actor.send({ type: 'SIGNUP' });
expect(actor.getSnapshot().value).toBe('unauthenticated.signup');
actor.send({ type: 'LOGIN' });
expect(actor.getSnapshot().value).toBe('unauthenticated.login');
actor.send({ type: 'AUTHENTICATED' });
expect(actor.getSnapshot().value).toBe('authenticated.browsing');
});
🤔 결정 기준
| Complexity | Tool |
|---|---|
| < 4 state | useState + discriminated union |
| 4-8 simple | useReducer |
| 4-8 complex | XState (lite) |
| 10+ hierarchical | XState (full) |
| Cross-component | XState actor |
| Workflow / multi-step | XState 추천 |
기본값: Discriminated union + useReducer. 매 complex flow 의 XState.
🔗 Graph
- 부모: State Management · API-Design
- 변형: XState
- 응용: FSM
- Adjacent: Discriminated-Union · useReducer · Zustand
🤖 LLM 활용
언제: 매 complex async flow. 매 multi-step form / wizard. 매 game state. 언제 X: 매 simple toggle. 매 trivial component state.
❌ 안티패턴
- Boolean explosion (isLoading, isError, isSuccess separate): invalid combination.
- No state machine + complex flow: bug 폭발.
- State machine + simple state: over-engineer.
- No exhaustive check: missed transition.
- Mixed concerns (UI + business): 매 separate.
🧪 검증 / 중복
- Verified (XState docs, Statecharts.dev).
- 신뢰도 B.
- Related: State Modeling and API Responses (closely related).
🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-09 | Cleanup — XState code + statechart + 결정 기준 |