
📅 2025-11-07
➡️ json-server에 대해 새롭게 알게 된 것 또는 헷갈리는 부분 정리
🔗 https://www.npmjs.com/package/json-server
설치
yarn add json-server
yarn add json-server -D # 개발 환경인 경우, -D 옵션을 함께 입력
db.json 파일 생성
프로젝트 루트 경로에 db.json 파일 생성

json-server는 db.json에 입력한 내용을 바탕으로 데이터베이스를 제공
{
"todos": []
}
yarn json-server db.json --port 4000
{
"users": [],
"todos": []
}import { useEffect, useState } from 'react';
const BASE_URL = 'http://localhost:4000';
const Todo = () => {
const [form, setForm] = useState({
email: '',
password: '',
});
const [user, setUser] = useState(null);
const [todoTitle, setTodoTitle] = useState('');
const [todos, setTodos] = useState([]);
const [filter, setFilter] = useState('all');
const resetForm = () => {
setForm({ email: '', password: '' });
};
useEffect(() => {
if (user) fetchTodos(filter);
}, [user, filter]);
// Todo 목록 조회 + 필터링
const fetchTodos = async (filterType = 'all') => {
const filterQuery = {
all: '',
active: '&completed=false',
completed: '&completed=true',
};
try {
const res = await fetch(`${BASE_URL}/todos?userId=${user.id}${filterQuery[filterType]}`);
const data = await res.json();
setTodos(data);
} catch (err) {
console.error('Todo 목록 조회 실패', err);
}
};
// 회원가입
const handleSignup = async () => {
const res = await fetch(`${BASE_URL}/users`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(form),
});
if (res.ok) {
alert('회원가입 완료!');
resetForm(); // 성공 시 인풋 초기화
} else {
alert('회원가입 실패!');
}
};
// 로그인
const handleLogin = async () => {
const res = await fetch(`${BASE_URL}/users?email=${form.email}`);
const data = await res.json();
if (data.length && data[0].password === form.password) {
setUser(data[0]);
alert('로그인 성공!');
resetForm();
} else {
alert('로그인 실패!');
}
};
// Todo 추가
const handleAddTodo = async () => {
if (!todoTitle.trim()) return alert('할 일을 입력해주세요!');
const res = await fetch(`${BASE_URL}/todos`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
userId: user.id,
title: todoTitle,
completed: false,
}),
});
const newTodo = await res.json();
setTodos((prev) => [...prev, newTodo]);
setTodoTitle('');
};
// Todo 완료 토글
const toggleTodo = async (todo) => {
try {
const res = await fetch(`${BASE_URL}/todos/${todo.id}`, {
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ completed: !todo.completed }),
});
const updatedData = await res.json();
setTodos((prev) => prev.map((t) => (t.id === todo.id ? updatedData : t)));
} catch (err) {
console.error('완료 상태 변경 실패', err);
}
};
// Todo 삭제
const handleDelete = async (id) => {
try {
await fetch(`${BASE_URL}/todos/${id}`, { method: 'DELETE' });
setTodos((prev) => prev.filter((t) => t.id !== id));
} catch (err) {
console.error('Todo 삭제 실패', err);
}
};
// 로그아웃
const handleLogout = () => {
setUser(null);
setTodos([]);
setTodoTitle('');
resetForm();
};
if (!user)
return (
<div>
<h2>로그인 / 회원가입</h2>
<input
placeholder="email"
value={form.email}
onChange={(e) => setForm({ ...form, email: e.target.value })}
/>
<input
type="password"
placeholder="password"
value={form.password}
onChange={(e) => setForm({ ...form, password: e.target.value })}
/>
<div>
<button onClick={handleLogin}>로그인</button>
<button onClick={handleSignup}>회원가입</button>
</div>
</div>
);
return (
<div>
<h2>{user.email}의 Todo List</h2>
<div>
<input
type="text"
placeholder="할 일 입력"
value={todoTitle}
onChange={(e) => setTodoTitle(e.target.value)}
/>
<button onClick={handleAddTodo}>추가</button>
</div>
<div>
<select value={filter} onChange={(e) => setFilter(e.target.value)}>
<option value="all">전체</option>
<option value="active">진행중</option>
<option value="completed">완료</option>
</select>
</div>
<ul>
{todos.map((todo) => (
<li key={todo.id}>
<span style={{ textDecoration: todo.completed ? 'line-through' : '' }}>
<span onClick={() => toggleTodo(todo)}>{todo.title}</span>
</span>
<button onClick={() => handleDelete(todo.id)}>삭제</button>
</li>
))}
</ul>
<button onClick={handleLogout}>로그아웃</button>
</div>
);
};
export default Todo;
| 기능 | HTTP 메서드 | 엔드포인트 |
|---|---|---|
| 회원가입 | POST | /users |
| 로그인 | GET | /users?email= |
| 할 일 조회 | GET | /todos?userId= |
| 할 일 추가 | POST | /todos |
| 완료 토글 | PATCH | /todos/:id |
| 삭제 | DELETE | /todos/:id |