json-server로 1분만에 rest api 서버만들기 2
해당 시리즈의 다른 편 확인하기
소스 코드 보러 가기
db.json 파일 작성 및 서버 띄우기
json-server는 json 파일을 만든 후에 해당 파일을 바라보게 하면 바로 작동한다.
우선은 루트 디렉토리에 db.json 파일을 만들어 보자.
// db.json
{
"todos": [
{ "id": 1, "description": "json-server 공부하기", "isCompleted": false },
{ "id": 2, "description": "시리즈 읽어보기", "isCompleted": true }
]
}
위와 같이 적어주면 서버를 띄울 준비는 끝났다.
이제 좀 더 편하게 사용하기 위에 script를 추가해보자.
// package.json
{
"scripts": {
"server": "json-server --watch db.json"
}
}
package.json 파일에서 script에 server라는 명령어를 추가해줬다.
npm run server
위의 명령어를 치면 json-server가 만들어질 것이다.
> json-server --watch db.json
\{^_^}/ hi!
Loading db.json
Done
Resources
http://localhost:3000/todos
Home
http://localhost:3000
Type s + enter at any time to create a snapshot of the database
Watching...
우리가 적은 todos에 접근하려면 http://localhost:3000/todos 로 들어가면 된다.
만약 todo 객체에 접근하고 싶다면 http://localhost:3000/todos/1 처럼 뒤에 아이디를 붙여주면 가능하다.
기본 port는 3000번 이지만 다른 포트로 설정해주고 싶다면 스크립트에 –port 옵션을 붙여주면 된다.
json-server –watch db.json –port 4444 로 수정하면 4444 포트에서 실행될 것이다.
리액트의 기본 포트가 3000이니 다른 포트로 변경하도록 하자.
CREATE 추가하기
우선 axios를 추가해보자. 해당 모듈로 crud 통신을 할 수 있다.
todo를 추가하기 위해 App.js를 다음과 같이 수정해보자.
import axios from "axios";
import React, { useState } from "react";
function App() {
const [description, setDescription] = useState("");
const handleSubmit = async () => {
const { data } = await axios.post("http://localhost:4444/todos", {
description,
isCompleted: false,
});
alert(data.description + "이 추가되었습니다.");
setDescription("");
};
return (
<>
<h1>1분만에 Rest api 만들기</h1>
<div>
<h2>추가하기</h2>
<input
placeholder="할 일"
type="text"
value={description}
onChange={(e) => setDescription(e.target.value)}
/>
<button onClick={handleSubmit}>추가하기</button>
</div>
</>
);
}
export default App;
input을 컨트롤하기 위해 useState 훅을 추가했고, 버튼을 누르면 할 일이 추가되고, 알림창이 뜬다.
추가되었다고 알림창이 뜨면 db.json을 확인해보자.
// db.json
{
"todos": [
{
"id": 1,
"description": "json-server 공부하기",
"isCompleted": false
},
{
"id": 2,
"description": "시리즈 읽어보기",
"isCompleted": true
},
{
"description": "할 일 추가하기2",
"isCompleted": false,
"id": 3
}
]
}
db.json에 추가된 모습을 확인할 수 있다.
Read, Update, Delete 구현
Read 부분을 구현하기 위해서는 페이지가 로드 되었을 때 데이터를 요청할 useEffect 훅과 받아온 데이터를 가지고 있을 state가 필요하다.
// App.js
function App() {
const [todoList, setTodoList] = useState([]);
const readList = async () => {
const { data } = await axios.get("http://localhost:4444/todos");
setTodoList(data);
};
useEffect(() => {
(async () => {
await readList();
})();
}, []);
return (
...
);
}
get 요청은 반복 사용할 것같아서 함수로 만들었다.(readList)
즉시 실행 함수로 페이지가 마운트 되었을 때 get 요청을 날리고 받아온 데이터를 todoList에 담는다.
const toggleCompleteBtn = async (id, isCompleted) => {
await axios.patch(`http://localhost:4444/todos/${id}`, {
isCompleted: !isCompleted,
});
await readList();
};
const deleteTodoBtn = async (id) => {
await axios.delete(`http://localhost:4444/todos/${id}`);
await readList();
};
완료/미완료 버튼을 클릭하면 토글될 수 있도록 함수를 만들었고, 해당 아이디를 받아서 삭제할 수 있도록 만들었다.
return (
<>
<h1>1분만에 Rest api 만들기</h1>
<div>
<h2>추가하기</h2>
<input
placeholder="할 일"
type="text"
value={description}
onChange={(e) => setDescription(e.target.value)}
/>
<button onClick={handleSubmit}>추가하기</button>
<br />
<h2>할 일 목록</h2>
<ul>
{todoList?.map((todo) => (
<div key={todo.id}>
<li key={todo.id}>{todo.description}</li>
<button
onClick={() => toggleCompleteBtn(todo.id, todo.isCompleted)}
>
{todo.isCompleted ? "완료" : "미완료"}
</button>
<button onClick={() => deleteTodoBtn(todo.id)}>삭제하기</button>
</div>
))}
</ul>
</div>
</>
);
해당 함수들을 사용할 수 있도록 리스트를 렌더링하도록 jsx를 수정해보자.
아주 투박한 모습이지만 CRUD를 사용할 수 있을 것이다.
Leave a comment