좋은 개발자가 되는 방법.
- 질문할땐 반드시 정리 필수. (상대방의 시간도 중요하며, 질문하려고 정리하다 보면 답이 떠오를 수 있음.)
- 에러가 났을 때, 무작정 솔루션만 찾기보다는 왜 이런 에러가 났는지 그리고 그걸 어떻게 해결하는지 과정이 중요. 이걸 메모하는 습관을 가지면 좋음.
- 사소한 것이라도 스스로 기능이나 페이지를 구현. 또한 이걸 스토리를 붙이면 좋은 이력이 될 수 있음.
- 다른 영어권 개발 글들을 많이 읽어보기.
- 내가 맡아본 기능이 아닌 다른 기능들을 도전해보기.
자바 스크립트
app.js
const express = require('express');
const app = express();
const port = 3000;
const goodsRouter = require('./routes/goods.js');
const cartsRouter = require('./routes/carts.js')
const connect = require("./schemas");
connect();
app.use(express.json());
app.use('/api', [goodsRouter,cartsRouter]);
// 아래는 내가 쓴 코드.. 왜인지 작동하지 않음.
// const goodsRouter = require('./routes/goods.js');
// // goodsRouter가 이제 good.js 19줄에 있는 모듈을 가져오게함
// const cartsRouter = require('./routes/cart.js')
// const connect = require('./schemas/index.js')
// connect(); // 꺼낸 익명함수 connect를 실행해야함.
// app.use(express.json());
// // 리퀘스트.바디를 쓰기위해선 먼저 작성해야한다.
// // 전역 미들웨어에 적용하겠다.
// // app.post("/",(req,res) =>{
// // console.log(req.body)
// // res.send('기본 url에 post 메소드가 정상적으로 실행되었습니다.')
// // })
// // app.get('/', (req,res) => {
// // console.log(req.query)
// // // res.send('정상적으로 반환?')
// // const a = {
// // "name":"하누즈호",
// // "age":50,
// // }
// // res.json(a);
// // // res.status(400).json(a); // 이렇게 쓰면 에러난것처럼 400코드로 날라감
// // })
// // app.get('/:id', (req,res) =>{
// // // 콜론뒤는 /뒤에 뭘쓰던, 그 값은 id에 저장이 된다는 뜻.
// // console.log(req.params)
// // res.send('id url에 정상적으로 반환?')
// // })
// // app.get('/', (req, res) => {
// // res.send('Hello World!');
// // });
// app.use('/api', [goodsRouter,cartsRouter]);
// // api 경로가 추가된 경우에는 모두 goodsRouter를 통해서 가라 라는 뜻.
// // 전역 미들웨어
// // 괄호안의 goodsRouter 말고 다른 라우터가 들어올수도 있기에 배열로써 집어넣어도 된다.
// // ex) [goodsRouter,usersRouter,postRouter .. 등]
// app.get('/',(req,res) => {
// res.send('hello world')
// })
app.listen(port, () => {
console.log(port, '3000 포트로 서버가 열렸어요!');
});
schemas/goods.js
const express = require("express");
const cart = require("../schemas/cart.js");
const router = express.Router();
// 익스프레스 라이브러리안에 있는 라우터()의 함수를 실행하여 그 함수의 결괏값을 router라는 변수에 집어넣을 것이다.
// // 반환받은 router라는 변수를 이용해서 get 메소드를 통해 어떤 위채? '/' 기본 위치에 들어왔었을때
// // 해당하는 코드를 실행할 것이다. 어떤코드? response 즉 반환을 할건데 문자열을 반환할 것이다.
// router.get('/',(req,res) => {
// res.send("default url for goods.js GET Method"); // res가 반환. 즉 반환할것이다 무엇을? send안에 있는 값을
// });
// // '/about' 이라는 경로에 get 메소드가 들어왔을 때 실행할거다. 어떤것을? res를.. 즉 반환할 거다.
// // 저 문자열을 반환할거다.
// router.get('/about',(req,res) => {
// res.send("goods.js about PATH");
// });
// module.exports = router;
// // router를 밖으로 내줘야함
// // router는 module.exports를 통해 밖으로 연결시킬 수 있음
// // 자, 이렇게 밖으래 뺐으면 이제 app.js에서 가지고 와야함!
// /routes/goods.js
const goods = [
{
goodsId: 4,
name: "상품 4",
thumbnailUrl:
"https://cdn.pixabay.com/photo/2016/09/07/02/11/frogs-1650657_1280.jpg",
category: "drink",
price: 0.1,
},
{
goodsId: 3,
name: "상품 3",
thumbnailUrl:
"https://cdn.pixabay.com/photo/2016/09/07/02/12/frogs-1650658_1280.jpg",
category: "drink",
price: 2.2,
},
{
goodsId: 2,
name: "상품 2",
thumbnailUrl:
"https://cdn.pixabay.com/photo/2014/08/26/19/19/wine-428316_1280.jpg",
category: "drink",
price: 0.11,
},
{
goodsId: 1,
name: "상품 1",
thumbnailUrl:
"https://cdn.pixabay.com/photo/2016/09/07/19/54/wines-1652455_1280.jpg",
category: "drink",
price: 6.2,
},
];
// 상품 전체 보기
router.get("/goods", (req,res)=> {
res.status(200).json({"상품":goods}) // "상품"(키)값을 없애고 밸류값인 goods만 써도됨
})
// 특정 상품 보기
router.get("/goods/:goodsID",(req,res)=> {
const {goodsID} = req.params;
let result = null; // 임시로 리절트 값에 아무것도 없는 널을 할당.
for(const good of goods){ // 반복문을 돌면서 good 이라는 임시 변수에 goods의 배열에 있던 요소 하나하나씩 대입.
if(Number(goodsID) === good.goodsId) // 만약 71번째에 정의했던 goodsID의 값이 반복문 변수 good의 goodsId의 값이 일치한다면?
result = good; // 리절트 값은 해당 good으로 변환.
}
// const [result] = goods.filter((good) => Number(goodsID) === good.goodsId)
// 이 위의 코드는 73번째줄~77번째줄과 동일함.
res.status(200).json({"디테일":result});
})
const Cart = require('../schemas/cart.js')
router.post('/goods/:goodsId/cart' , async (req,res) => {
const {goodsId} = req.params
const {quantity} = req.body
const existCarts = await Cart.find({goodsId: Number(goodsId) }); // 카트안에 담긴 아이디가 존재하는지 확인
if (existCarts.length) {
return res.status(400).json({success:false, errorMassage:"이미 장바구니에 해당하는 상품이 있습니다."})
}
await Cart.create({goodsId: Number(goodsId), quantity: quantity})
res.json({result: "success"})
})
router.put('/goods/:goodsId/cart', async (req,res) => {
const {goodsId} = req.params
const {quantity} = req.body
const existCarts = await Cart.find({goodsId})
if (quantity < 1) {
return res.status(400).json({success: "False!! 1미만의 수량은 입력할 수 없습니다!"})
}
// 정답 코드: 어째서 리턴을 맨 마지막을 뺀것일까?
// if (quantity < 1) {
// res.status(400).json({ errorMessage: "수량은 1 이상이어야 합니다." });
// return;
// }
if (existCarts.length) {
await Cart.updateOne(
{goodsId: goodsId}, // 여기선 찾고
{$set: {quantity:quantity}} // 여기서 바꾼다
// 해석하자면, goodsId가 goodsId인 값을 찾아서 set한다(수정한다) 어떻게?
// quantity를 quantity로 수정할 거다
)
}
res.status(200).json({success:true})
})
router.delete('/goods/:goodsId/cart', async (req,res) => {
const {goodsId} = req.params
const existCarts = await Cart.find({goodsId})
if (existCarts.length > 0){
await Cart.deleteOne({goodsId})
}
res.json({result: "success"})
})
const Goods = require("../schemas/goods")
router.post('/goods', async (req,res) => {
const {goodsId, name, thumbnailUrl, category, price, desc} = req.body;
const goods = await Goods.find({goodsId}); // goodsId는 고유값이기에 중복되어있는지 체크가 필요
// 또한 어웨잇을 쓰는이유는 데이터를 가지고 올건데 데이터를 가지고 오는 동안 다음 코드로 가지 않도록 동기적으로 처리할 수 있도록 어웨잇을 건다.
if(goods.length) { // goods.length했을때 goods 값이 있다는 말은 즉 위위위 줄에서 중복되는 값이 있다는 뜻이기에...
return res.status(400).json({success:false,errorMessage:"이미 존재하는 굿즈아이디..."})
}
const createdgoods = await Goods.create({goodsId,name,thumbnailUrl,category,price,desc})
res.json({goods:createdgoods})
})
module.exports = router;
schemas/cart.js
const mongoose = require("mongoose");
const cartSchema = new mongoose.Schema({
goodsId: {
type: Number,
required: true, // 이 값이 무조건 있어야하는가 없어야하는가 정의
unique: true // 해당하는 값이 무조건 고유하여만 하는가? 하나밖에 있을 수 없음.
},
quantity: {
type: Number,
required: true
}
});
module.exports = mongoose.model("Cart", cartSchema);
/routes/goods.js
const express = require("express");
const cart = require("../schemas/cart.js");
const router = express.Router();
// 익스프레스 라이브러리안에 있는 라우터()의 함수를 실행하여 그 함수의 결괏값을 router라는 변수에 집어넣을 것이다.
// // 반환받은 router라는 변수를 이용해서 get 메소드를 통해 어떤 위채? '/' 기본 위치에 들어왔었을때
// // 해당하는 코드를 실행할 것이다. 어떤코드? response 즉 반환을 할건데 문자열을 반환할 것이다.
// router.get('/',(req,res) => {
// res.send("default url for goods.js GET Method"); // res가 반환. 즉 반환할것이다 무엇을? send안에 있는 값을
// });
// // '/about' 이라는 경로에 get 메소드가 들어왔을 때 실행할거다. 어떤것을? res를.. 즉 반환할 거다.
// // 저 문자열을 반환할거다.
// router.get('/about',(req,res) => {
// res.send("goods.js about PATH");
// });
// module.exports = router;
// // router를 밖으로 내줘야함
// // router는 module.exports를 통해 밖으로 연결시킬 수 있음
// // 자, 이렇게 밖으래 뺐으면 이제 app.js에서 가지고 와야함!
// /routes/goods.js
const goods = [
{
goodsId: 4,
name: "상품 4",
thumbnailUrl:
"https://cdn.pixabay.com/photo/2016/09/07/02/11/frogs-1650657_1280.jpg",
category: "drink",
price: 0.1,
},
{
goodsId: 3,
name: "상품 3",
thumbnailUrl:
"https://cdn.pixabay.com/photo/2016/09/07/02/12/frogs-1650658_1280.jpg",
category: "drink",
price: 2.2,
},
{
goodsId: 2,
name: "상품 2",
thumbnailUrl:
"https://cdn.pixabay.com/photo/2014/08/26/19/19/wine-428316_1280.jpg",
category: "drink",
price: 0.11,
},
{
goodsId: 1,
name: "상품 1",
thumbnailUrl:
"https://cdn.pixabay.com/photo/2016/09/07/19/54/wines-1652455_1280.jpg",
category: "drink",
price: 6.2,
},
];
// 상품 전체 보기
router.get("/goods", (req,res)=> {
res.status(200).json({"상품":goods}) // "상품"(키)값을 없애고 밸류값인 goods만 써도됨
})
// 특정 상품 보기
router.get("/goods/:goodsID",(req,res)=> {
const {goodsID} = req.params;
let result = null; // 임시로 리절트 값에 아무것도 없는 널을 할당.
for(const good of goods){ // 반복문을 돌면서 good 이라는 임시 변수에 goods의 배열에 있던 요소 하나하나씩 대입.
if(Number(goodsID) === good.goodsId) // 만약 71번째에 정의했던 goodsID의 값이 반복문 변수 good의 goodsId의 값이 일치한다면?
result = good; // 리절트 값은 해당 good으로 변환.
}
// const [result] = goods.filter((good) => Number(goodsID) === good.goodsId)
// 이 위의 코드는 73번째줄~77번째줄과 동일함.
res.status(200).json({"디테일":result});
})
const Cart = require('../schemas/cart.js')
router.post('/goods/:goodsId/cart' , async (req,res) => {
const {goodsId} = req.params
const {quantity} = req.body
const existCarts = await Cart.find({goodsId: Number(goodsId) }); // 카트안에 담긴 아이디가 존재하는지 확인
if (existCarts.length) {
return res.status(400).json({success:false, errorMassage:"이미 장바구니에 해당하는 상품이 있습니다."})
}
await Cart.create({goodsId: Number(goodsId), quantity: quantity})
res.json({result: "success"})
})
router.put('/goods/:goodsId/cart', async (req,res) => {
const {goodsId} = req.params
const {quantity} = req.body
const existCarts = await Cart.find({goodsId})
if (quantity < 1) {
return res.status(400).json({success: "False!! 1미만의 수량은 입력할 수 없습니다!"})
}
// 정답 코드: 어째서 리턴을 맨 마지막을 뺀것일까?
// if (quantity < 1) {
// res.status(400).json({ errorMessage: "수량은 1 이상이어야 합니다." });
// return;
// }
if (existCarts.length) {
await Cart.updateOne(
{goodsId: goodsId}, // 여기선 찾고
{$set: {quantity:quantity}} // 여기서 바꾼다
// 해석하자면, goodsId가 goodsId인 값을 찾아서 set한다(수정한다) 어떻게?
// quantity를 quantity로 수정할 거다
)
}
res.status(200).json({success:true})
})
router.delete('/goods/:goodsId/cart', async (req,res) => {
const {goodsId} = req.params
const existCarts = await Cart.find({goodsId})
if (existCarts.length > 0){
await Cart.deleteOne({goodsId})
}
res.json({result: "success"})
})
const Goods = require("../schemas/goods")
router.post('/goods', async (req,res) => {
const {goodsId, name, thumbnailUrl, category, price, desc} = req.body;
const goods = await Goods.find({goodsId}); // goodsId는 고유값이기에 중복되어있는지 체크가 필요
// 또한 어웨잇을 쓰는이유는 데이터를 가지고 올건데 데이터를 가지고 오는 동안 다음 코드로 가지 않도록 동기적으로 처리할 수 있도록 어웨잇을 건다.
if(goods.length) { // goods.length했을때 goods 값이 있다는 말은 즉 위위위 줄에서 중복되는 값이 있다는 뜻이기에...
return res.status(400).json({success:false,errorMessage:"이미 존재하는 굿즈아이디..."})
}
const createdgoods = await Goods.create({goodsId,name,thumbnailUrl,category,price,desc})
res.json({goods:createdgoods})
})
module.exports = router;
routes/carts.js
// const express = require("express");
// // const cart = require("../schemas/cart");
// const Cart = require('../schemas/cart.js')
// const Goods = require('../schemas/goods.js')
// const router = express.Router();
// router.get("/carts", async(req,res) => {
// const carts = await Cart.find({}) // 사용자가 정의되지 않았기에 우선 모든 장바구니를 가져와 변수 carts에 담아둔다.
// // [
// // {goodsId, quantity}
// // ] 두가지의 데이터가 있음.
// const goodsIds = carts.map((cart) => {
// return cart.goodsId // 반복문을 돌면서 카트안에 있는 goodsId값만 가져오게 함
// })
// // 이제 goodsIds에 해당되는 굿즈를 가져와야함.
// const goods = await Goods.find({goodsId: goodsIds})
// // goodsId에 해당되는 값이 위에서 찾은 goodsIds와 일치하는 것들을 모두 가지고 와라!
// // 즉, goodsIds 변수 안에 존재하는 값일 때에만 조회해라!
// const results = carts.map((cart) => {
// return {
// "quantity": cart.quantity,
// "goods": goods.find((item) => item.goodsId === cart.goodsId),
// }
// })
// res.json({
// "carts": results
// })
// })
// module.exports = router;
// 위는 내가 쓴 코드
const express = require("express");
const Goods = require("../schemas/goods");
const Cart = require("../schemas/cart");
const router = express.Router();
router.get("/carts", async (req, res) => {
const carts = await Cart.find();
const goodsIds = carts.map((cart) => cart.goodsId);
const goods = await Goods.find({ goodsId: goodsIds });
const results = carts.map((cart) => {
return {
quantity: cart.quantity,
goods: goods.find((item) => item.goodsId === cart.goodsId)
};
});
res.json({
carts: results,
});
});
module.exports = router;