https://blog.naver.com/occidere/220850682345
API를 만들 수 있는 서버 만들기
Routing 작업
Routing이 많아지면 많아질 수록 앱에서 관리하는데 한계가 생김
https://petstore.swagger.io/?_ga=2.110122051.757277682.1701045196-980531850.1701045196
to-do-list-redux
backend
open terminal
cd backend
npm init -y
{
"name": "backend",
"version": "1.0.0",
"description": "",
"main": "app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "h662",
"license": "MIT"
}
npm i express
git init
node_modules
.env
README.md file 생성
const express = require("express");
const app = express();
const port = 3010;
app.get("/", (req, res) => {
return res.send("Hello, Express!");
});
app.listen(port, () => {
console.log(`🚀 Server is listening on port : ${port}`);
});
node app.js
http://localhost:3010/ 에서 "Hello, express!"뜨는지 확인
routes folder/todos.js
const express = require("express");
const router = express.Router();
router.get("/", (req, res) => {
return res.send("Todo Router");
});
module.exports = router;
npm i -D nodemon하고 package.json에 명령어 등록해줘야 함
{
"name": "backend",
"version": "1.0.0",
"description": "",
"main": "app.js",
"scripts": {
"start": "node app.js", <- 수정해준 것
"dev": "nodemon app.js" <- 수정해준 것
},
"keywords": [],
"author": "h662",
"license": "MIT",
"devDependencies": {
"nodemon": "^3.0.1"
}
}
npm run dev
만약 안 되면 npm i express 다시 실행하고
npm run dev 재명령
const express = require("express");
const router = express.Router();
let todoId = 1;
let todos = [{ id: 1, title: "🧹 청소하기", isDone: false }];
router.post("/", (req, res) => {
console.log(req.body);
return res.json({ message: "ok" });
});
module.exports = router;
Postman에서 날려보기
그러면 Terminal에 undefined 뜸
const express = require("express");
const todosRouter = require("./routes/todos");
const app = express();
const port = 3010;
app.use(express.json());
app.use("/todos", todosRouter);
app.get("/", (req, res) => {
return res.send("Hello, Express!");
});
app.listen(port, () => {
console.log(`🚀 Server is listening on port : ${port}`);
});
postman에서 x-www-form에서 아래와 같이 작성 후 send
const express = require("express");
const todosRouter = require("./routes/todos");
const app = express();
const port = 3010;
app.use(express.json());
app.use(express.urlencoded({ extended: true })); <-- 추가
app.use("/todos", todosRouter);
app.get("/", (req, res) => {
return res.send("Hello, Express!");
});
app.listen(port, () => {
console.log(`🚀 Server is listening on port : ${port}`);
});
const express = require("express");
const router = express.Router();
let todoId = 1;
let todos = [{ id: 1, title: "🧹 청소하기", isDone: false }];
router.post("/", (req, res) => {
const { title } = req.body; <--- 수정
todoId++; <--- todoId = todoId + 1; todoId += 1;
++는 값을 저장하는 의미도 담고 있음
const newTodo = { id: todoId, title, isDone: false } <--- key와 value값이 같으면 생략이 가능하다 title: title
todos.push(newTodo);
console.log(todos);
return res.json({ todo: newTodo });
});
const express = require("express");
const router = express.Router();
let todoId = 1;
let todos = [{ id: 1, title: "🧹 청소하기", isDone: false }];
router.post("/", (req, res) => {
const { title } = req.body;
if (!title) {
return res.status(400).json({
message: "Not exist title.",
});
}
todoId++;
const newTodo = { id: todoId, title, isDone: false }
todos.push(newTodo);
console.log(todos);
return res.json({ todo: newTodo });
});
// router.get("/", (req, res) => {
// return res.send("Todo Router");
// });
module.exports = router;
const express = require("express");
const router = express.Router();
let todoId = 1;
let todos = [{ id: 1, title: "🧹 청소하기", isDone: false }];
router.post("/", (req, res) => {
const { title } = req.body;
if (!title) {
return res.status(400).json({
message: "Not exist title.",
});
}
todoId++;
const newTodo = { id: todoId, title, isDone: false };
todos.push(newTodo);
console.log(todos);
return res.json({ todo: newTodo });
});
router.get("/", (req, rest) => {
return res.json({ todos });
});
module.exports = router;
const express = require("express");
const router = express.Router();
let todoId = 1;
let todos = [{ id: 1, title: "🧹 청소하기", isDone: false }];
router.post("/", (req, res) => {
const { title } = req.body;
if (!title) {
return res.status(400).json({
message: "Not exist title.",
});
}
todoId++;
const newTodo = { id: todoId, title, isDone: false };
todos.push(newTodo);
console.log(todos);
return res.json({ todo: newTodo });
});
router.get("/", (req, res) => {
return res.json({ todos });
});
router.get("/:todoId", (req, res) => {
const { todoId } = req.params;
let existTodo;
todos.map((v, i) => {
if (v.id === +todoId) {
existTodo = v;
}
});
return res.json({ todo: existTodo });
});
module.exports = router;
http://localhost:3010/todos에서도 확인 가능
if (isNaN(todoId)) {
return res.status(400).json({
message: "todoId is not a number.",
});
}
if (!existTodo) {
return res.status(400).json({
message: "Not exist todo.",
});
}
const express = require("express");
const router = express.Router();
let todoId = 1;
let todos = [{ id: 1, title: "🧹 청소하기", isDone: false }];
router.post("/", (req, res) => {
const { title } = req.body;
if (!title) {
return res.status(400).json({
message: "Not exist title.",
});
}
todoId++;
const newTodo = { id: todoId, title, isDone: false };
todos.push(newTodo);
console.log(todos);
return res.json({ todo: newTodo });
});
router.get("/", (req, res) => {
return res.json({ todos });
});
router.get("/:todoId", (req, res) => {
const { todoId } = req.params;
if (isNaN(todoId)) {
return res.status(400).json({
message: "todoId is not a number.",
});
}
let existTodo;
todos.map((v, i) => {
if (v.id === +todoId) {
existTodo = v;
}
});
if (!existTodo) {
return res.status(400).json({
message: "Not exist todo.",
});
}
return res.json({ todo: existTodo });
});
module.exports = router;
Postman 5ea 생성
http://localhost:3010/todos/4
= 4번 출력
http://localhost:3010/todos/12
= "message": "Not exist todo."
http://localhost:3010/todos/abc
= "message": "todoId is not a number."
router.put("/:todoId/done", (req, res) => {
const { todoId } = req.params;
if (isNaN(todoId)) {
return res.status(400).json({
message: "todoId is not a number.",
});
}
let updateTodo;
todos = todos.map((v) => {
if (v.id === +todoId) {
updateTodo = { id: v.id, title: v.title, isDone: !v.isDone };
return updateTodo;
} else {
return v;
}
});
if (!updateTodo) {
return res.status(400).json({
message: "Not exist todo.",
});
}
return res.json({ todo: updateTodo });
});
Postman
post : http://localhost:3010/todos/ 10ea send
put : http://localhost:3010/todos/10/done send
get : http://localhost:3010/todos/ send 후 10번만 true인지 확인
마지막은 delete
const express = require("express");
const todosRouter = require("./routes/todos");
const app = express(); -> express 자체를 함수로 실행
const port = 3010;
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
-> 위 두 줄은 json 형태로 받기 위함
app.use("/todos", todosRouter);
->app.use는 미들웨어. 중간에 위치해서 서버를 다채롭게 하는 역할. 라우터의 경우 첫 번째(/todos)에 경로를 입력하고, 그 라우터에 우리가 만들어 놓은 경로를 이용할 수 있음
app.get("/", (req, res) => {
return res.send("Hello, Express!");
}); -> get 요청. 로컬호스트 들어가면 서버가 열려있는지 아닌지 확인해볼 수 있음. 필수가 아니라면 굳이 안 둬도 되긴 함.
app.listen(port, () => {
console.log(`🚀 Server is listening on port : ${port}`);
}); -> 다 실행하면 마지막에 app.listen 사용. listen은 문자 그대로 요청이 들어오나 안 들어오나 서버가 듣고 있는 것. 3010 port가 열릴 거고, 콘솔로그 찍히면서 서버가 시작.
const express = require("express");
const router = express.Router();
-> express를 router에 담음
let todoId = 1;
let todos = [{ id: 1, title: "🧹 청소하기", isDone: false }]; -> 필요한 데이터를 임시로 변수로 달아놓음. 이 경우 데이터가 메모리에 저장됨. 서버가 리셋되면 데이터가 날라가는 것.
router.post("/", (req, res) => {
const { title } = req.body; -> body로부터 타이틀을 받아옴
if (!title) {
return res.status(400).json({
message: "Not exist title.",
});
} -> title이 없으면 예외처리 한다는 명령어
todoId++; -> 투두아이디값 증가시키고
const newTodo = { id: todoId, title, isDone: false };
todos.push(newTodo);
console.log(todos);
return res.json({ todo: newTodo });
});
router.get("/", (req, res) => {
return res.json({ todos });
}); -> 그냥 리턴하면 안 되고 res.json 해야 함
router.get("/:todoId", (req, res) => {
const { todoId } = req.params;
if (isNaN(todoId)) {
return res.status(400).json({
message: "todoId is not a number.",
});
} -> 숫자가 아니면 에러처리
let existTodo;
todos.map((v, i) => {
if (v.id === +todoId) {
existTodo = v;
}
});
if (!existTodo) {
return res.status(400).json({
message: "Not exist todo.",
});
} -> 존재하지 않는 투두 뿜어내기
return res.json({ todo: existTodo });
});
router.put("/:todoId/done", (req, res) => {
const { todoId } = req.params;
if (isNaN(todoId)) {
return res.status(400).json({
message: "todoId is not a number.",
});
} -> 아이디가 없을 경우 isNaN으로 탐색
let updateTodo;
-> 업데이트 해준 내용을 기존 todos에 반영해줘야 하니 아래 return해준 것
todos = todos.map((v) => {
if (v.id === +todoId) {
updateTodo = { id: v.id, title: v.title, isDone: !v.isDone };
return updateTodo;
} else {
return v;
}
});
if (!updateTodo) {
return res.status(400).json({
message: "Not exist todo.",
});
}
return res.json({ todo: updateTodo });
});
router.put("/:todoId", (req, res) => {
const { todoId } = req.params;
const { title } = req.body;
if (isNaN(todoId) || !title) {
return res.status(400).json({
message: "Not exist data.",
});
} -> isNaN해서 타이틀이 없거나 todoId 한 번에 비교 가능. 물론 퉁쳐서 하면 정확히 어떤 에러인지 알 수 없음
let updateTodo;
todos = todos.map((v) => {
if (v.id === +todoId) {
updateTodo = { id: v.id, title, isDone: v.isDone };
return updateTodo;
} else {
return v;
}
});
return res.json({ todo: updateTodo });
});
router.delete("/:todoId", (req, res) => {
const { todoId } = req.params;
if (isNaN(todoId)) {
return res.status(400).json({
message: "todoId is not a number.",
});
}
todos = todos.filter((v) => {
if (v.id !== +todoId) {
return v;
}
});
console.log(todos);
return res.json({ message: "Deleted todo." });
});
module.exports = router;
자바가 솔리디티랑 적합하고
자바스크립트랑 솔리디티는 다름
솔리디티에서는 if문 쓰는데 map은 안 씀.
공통적인 요소나 로직은 달라지지 않음.
같은 자바스크립트를 써도 프론트엔드랑 백엔드가 다른 게 있음.
이 차이점을 알고 하느냐 모르고 하느냐는 중요.
프론트엔지니어가 데이터베이스까지 붙일 수 있으면 할 수 있는 게 많아짐.
next.js는 서버리스 형태로 백엔드 구현 가능.
이게 express랑 유사함.