1. Express의 REST API를 어떻게 개발하는지 알아봅니다.
2. Express 프레임워크에서 REST API를 개발해봅니다.
01. REST API 개발
◆ 상품 목록 조회 API
▷ 구현하려면
상품 목록 조회 API에서는 모든 상품(goods)이 한번에 전달 되어야합니다.
ex) GET 메소드를 이용해서 /goods 라는 주소로 요청을 보냈을 때, 모든 상품 목록이 응답(response)해서 json 포맷으로 상품 목록이 보여야 합니다.
이번 주차에서는 DB대신 routes 폴더에 goods.js 파일에서 아래의 상품 json 데이터를 저장합니다.
▷ 상품 예시 데이터 코드(/routes/goods.js 코드)
// /routes/goods.js
import express from 'express';
// Express.js의 라우터를 생성합니다.
const router = express.Router();
const goods = [
{
goodsId: 1,
name: '상품 1',
thumbnailUrl:
'https://cdn.pixabay.com/photo/2016/09/07/19/54/wines-1652455_1280.jpg',
category: 'drink',
price: 6.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: 3,
name: '상품 3',
thumbnailUrl:
'https://cdn.pixabay.com/photo/2016/09/07/02/12/frogs-1650658_1280.jpg',
category: 'drink',
price: 2.2,
},
{
goodsId: 4,
name: '상품 4',
thumbnailUrl:
'https://cdn.pixabay.com/photo/2016/09/07/02/11/frogs-1650657_1280.jpg',
category: 'drink',
price: 0.1,
},
];
/** 상품 목록 조회 **/
// localhost:3000/api/goods GET
router.get('/goods', (req, res) => {
return res.json({ goods: goods });
});
export default router;
◆ 상품 상세 조회 API
▷ 구현하려면
특정 상품의 상세 조회를 위해서 기존 상품 목록 주소 이후에 경로 매개변수(Path Parameter)로 상품 id(goodsId)로 특정 상품 상세 조회를 구현 해야합니다.
▷ 경로 매개변수(Path Parameter) :
Path Parameter 또는 Path Variable이라고 불립니다.
라우트 주소에서 사용되는 특수한 패턴 중 하나입니다. 이는 URL의 일부분으로, 언제든지 변경될 수 있는 값을 나타내기 위해 사용됩니다.
상품 목록 조회 API의 주소가 /goods 였다면 그뒤에 /:goodsId 라는 값을 추가해서 요청시 goodsId값을 받아올 수 있습니다.
이 값은 API 내에서 req.params 객체 안에서 해당하는 경로 매개변수의 이름(goodsId)으로 접근하여 얻을 수 있습니다.
req.prams.goodsId를 통해 goodsId파라미터 값을 얻을 수 있습니다.
// goods.js에 추가할 코드 입니다
/* 상품 상세 조회API
http://localhost:3000/api/goods/:goodsId/ */
router.get('/goods/:goodsId', (req, res) => {
// 1. 상품의 id 조회
// 2. 상품 id와 일치하는 데이터 찾기
// 3. 조회한 상품 정보르 Response로 Return 한다.
const goodsId = req.params.goodsId; // 1.
const findGoods = goods.find((oneGoods) =>oneGoods.goodsId === +goodsId) // 2.
return res.status(200).json({goods: findGoods}); // 3.
})
◆ 상품 등록 API
▷ 구현하려면
상품 등록 API에서는 클라이언트가 요청(Request)시 전달하는 상품의 정보(body data)를 서버로 전달받아야합니다.
상품 등록 API는 ‘데이터를 저장’하는 역할을 담당하므로, Http 메서드 중에서는 데이터를 생성하는 POST 메서드를 이용하여 구현해야합니다.
▷ POST 메서드 : 클라이언트가 서버로 보내는 데이터를 전송하기 위해 사용되는 메서드입니다. 이 데이터는 주로 서버의 리소스를 생성할 때 사용합니다.
▷ 구현하기에 앞서
POST 메서드에서 클라이언트가 전달한 데이터는 Express.js에서 `req.body`를 통해 접근할 수 있습니다.
`req.body`에 접근하려면 Body Parser 미들웨어를 사용해야 합니다.
Body Parser는 클라이언트가 전송한 데이터를 해석하여 `req.body` 객체로 변환해주어, 클라이언트 데이터를 쉽게 추출할 수 있도록 도와줍니다.
▷ Body Parser는 app.js파일에 추가하여, body에 접근이 가능하도록 설정합니다.
// app.js
// Express에서 req.body에 접근하여, body 데이터를 사용할 수 있도록 설정하는 미들웨어
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
전체 코드
// app.js
import express from 'express';
import goodsRouter from './routes/goods.js';
import newsRouter from './routes/news.js';
const app = express();
const PORT = 3000;
// Express에서 req.body에 접근하여, body 데이터를 사용할 수 있도록 설정하는 미들웨어
// json 형태로 서버에 body 데이터를 전달하면, req.body에 데이터를 변환하여 넣어줍니다.
// API 클라이언트를 사용 할 때 사용
app.use(express.json());
// form content type에서 body 데이터를 전달하면, req.body에 데이터를 변환하여 넣어줍니다.
// 프론트엔드 동료와 협업시 사용
app.use(express.urlencoded({ extended: true }));
// localhost:3000/api -> goodsRouter, newsRouter
app.use('/api', [goodsRouter, newsRouter]);
app.listen(PORT, () => {
console.log(PORT, '포트로 서버가 열렸어요!');
});
// /routes/goods.js
import express from 'express';
// Express.js의 라우터를 생성합니다.
const router = express.Router();
const goods = [
{
goodsId: 1,
name: '상품 1',
thumbnailUrl:
'https://cdn.pixabay.com/photo/2016/09/07/19/54/wines-1652455_1280.jpg',
category: 'drink',
price: 6.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: 3,
name: '상품 3',
thumbnailUrl:
'https://cdn.pixabay.com/photo/2016/09/07/02/12/frogs-1650658_1280.jpg',
category: 'drink',
price: 2.2,
},
{
goodsId: 4,
name: '상품 4',
thumbnailUrl:
'https://cdn.pixabay.com/photo/2016/09/07/02/11/frogs-1650657_1280.jpg',
category: 'drink',
price: 0.1,
},
];
/** 상품 목록 조회 **/
// localhost:3000/api/goods GET
router.get('/goods', (req, res) => {
return res.json({ goods: goods });
});
/* 상품 상세 조회API
http://localhost:3000/api/goods/:goodsId/ */
router.get('/goods/:goodsId', (req, res) => {
// 1. 상품의 id 조회
// 2. 상품 id와 일치하는 데이터 찾기
// 3. 조회한 상품 정보르 Response로 Return 한다.
const goodsId = req.params.goodsId; // 1.
const findGoods = goods.find((oneGoods) =>oneGoods.goodsId === +goodsId) // 2.
return res.status(200).json({goods: findGoods}); // 3.
})
/**상품 등록 API **/
// http://localhost:3000/api/goods/
router.post('/goods', (req, res) => {
// 1. name, thumbnailUrl, category, price를 req.body로 전달받는다.
// 2. 해당하는 데이터를바탕으로 상품을 등록한다.
// 3. 등록된 상품 데이터를 클라이언트에게 반환한다.
const name = req.body.name;
const thumbnailUrl = req.body.thumbnailUrl;
const category = req.body.category;
const price = req.body.price;
const goodsId = goods[goods.length - 1].goodsId + 1; // 현재 goodsId의 가장 큰 값 + 1
const goodsItem = {
goodsId: goodsId,
name: name,
thumbnailUrl: thumbnailUrl,
category: category,
price: price,
};
goods.push(goodsItem);
return res.status(201).json({ goods: goodsItem });
});
export default router;
▷ Insomnia로 상품등록 API 테스트
body데이터의 형식을 선택해 보낼 수 있습니다.
get을 post로 수정 > URL ' localhost:3000/api/goods' 기입 > 'Body'> 텍스트에 'Json' 선택> 적고 > Send 클릭
{ // text Json 칸에 붙이세요
"name": "상품 5",
"thumbnailUrl": "https://cdn.pixabay.com/photo/2016/07/26/16/16/wine-1543170_960_720.jpg",
"category": "drink",
"price": 100.3
}
◆ 상품 등록 API 리팩토링
리팩토링 : 코드를 간략하게 만들어 가독성을 높입니다.
전달받게되는 데이터(import api)가 많아질수록 코드가 복잡해지고 가독성이 떨어지게 될 것입니다.
▷ ‘객체 구조 분해 할당’ : JavaScript에서 제공하는 객체와 배열 같은 복잡한 데이터 타입을 다루기 위한 문법.
객체 내부의 Key와 일치하는 변수에 값을 할당할 수 있게됩니다.
/** 상품 등록 리팩토링 **/
// localhost:3000/api/goods POST
router.post('/goods', (req, res) => {
// 객체 구조 분해 할당 적용하기.
const { name, thumbnailUrl, category, price } = req.body;
const goodsId = goods[goods.length - 1].goodsId + 1; // 현재 goodsId의 가장 큰 값 + 1
// 객체 구조 분해 할당 적용하기.
const goodsItem = {
goodsId,
name,
thumbnailUrl,
category,
price,
};
goods.push(goodsItem);
return res.status(201).json({ goods: goodsItem });
});
리팩토링한 goods.js 코드
// /routes/goods.js
import express from 'express';
// Express.js의 라우터를 생성합니다.
const router = express.Router();
const goods = [
{
goodsId: 1,
name: '상품 1',
thumbnailUrl:
'https://cdn.pixabay.com/photo/2016/09/07/19/54/wines-1652455_1280.jpg',
category: 'drink',
price: 6.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: 3,
name: '상품 3',
thumbnailUrl:
'https://cdn.pixabay.com/photo/2016/09/07/02/12/frogs-1650658_1280.jpg',
category: 'drink',
price: 2.2,
},
{
goodsId: 4,
name: '상품 4',
thumbnailUrl:
'https://cdn.pixabay.com/photo/2016/09/07/02/11/frogs-1650657_1280.jpg',
category: 'drink',
price: 0.1,
},
];
/** 상품 목록 조회 **/
// localhost:3000/api/goods GET
router.get('/goods', (req, res) => {
return res.json({ goods: goods });
});
/* 상품 상세 조회API
http://localhost:3000/api/goods/:goodsId/ */
router.get('/goods/:goodsId', (req, res) => {
// 1. 상품의 id 조회
// 2. 상품 id와 일치하는 데이터 찾기
// 3. 조회한 상품 정보르 Response로 Return 한다.
const goodsId = req.params.goodsId; // 1.
const findGoods = goods.find((oneGoods) =>oneGoods.goodsId === +goodsId) // 2.
return res.status(200).json({goods: findGoods}); // 3.
})
/** 상품 등록 리팩토링 **/
// localhost:3000/api/goods POST
router.post('/goods', (req, res) => {
// 객체 구조 분해 할당 적용하기.
const { name, thumbnailUrl, category, price } = req.body;
const goodsId = goods[goods.length - 1].goodsId + 1; // 현재 goodsId의 가장 큰 값 + 1
// 객체 구조 분해 할당 적용하기.
const goodsItem = {
goodsId,
name,
thumbnailUrl,
category,
price,
};
goods.push(goodsItem);
return res.status(201).json({ goods: goodsItem });
});
export default router;
클라이언트가 전달한 파라미터를 한 줄로 간단하게 줄였습니다.
새로운 상품을 생성할 때 Key-Value를 각각 선언하는 것 대신 한 줄로 처리할 수 있게 되었습니다.
'내일배움 강의 > 강의- Node.js 입문, 숙련' 카테고리의 다른 글
입문 2주차 3 mongoose (1) | 2024.11.21 |
---|---|
입문 2주차 2 Studio 3T (1) | 2024.11.18 |
Node.js 입문주차 1주차 - 6_Request와 Response (0) | 2024.11.04 |
Node.js 입문주차 1주차 -4_ES6 Module 시스템 (0) | 2024.11.04 |
Node.js 입문주차 1주차 -3_Express.js 프레임워크 (0) | 2024.11.04 |