공항 리스트, 비행편 리스트, 예약 리스트를 GET, POST, PUT, DELETE 할 수 있는 서버를 만들어보자
app.js
const express = require('express'); // (1)
const cors = require('cors');
const app = express();
const port = 3001; // (2)
const flightRouter = require('./router/flightRouter'); // (3)
const bookRouter = require('./router/bookRouter');
const airportRouter = require('./router/airportRouter');
app.use(cors()); // (4)
app.use(express.json());
app.use('/flight', flightRouter); // (5)
app.use('/book', bookRouter);
app.use('/airport', airportRouter);
app.get('/', (req, res) => { // (6)
res.status(200).send('Welcome, States Airline!');
});
app.use((req, res, next) => { // (7)
res.status(404).send('Not Found!');
});
app.use((err, req, res, next) => { // (8)
console.error(err.stack);
res.status(500).send({
message: 'Internal Server Error',
stacktrace: err.toString()
});
});
app.listen(port, () => { // (9)
console.log(`[RUN] StatesAirline Server... | http://localhost:${port}`);
});
module.exports = app;
(1) 맨 위의 세 줄은 express를 사용하면서 그냥 고정적으로 쓰는 코드라고 생각하면 된다.
(2) port는 임의로 지정.
(3) 세 개의 라우터가 등장하는데, 이건 잠시 후에 설명하겠다.
(4) cors와 express.json을 모든 url에서 사용하겠다는 코드.
(5) 세 개의 라우터를 각각의 url에서 사용하겠다는 코드.
(6) localhost:3001/ 로 접속하면 'Welcome, States Airline!'이 출력된다.
(7) 지정되지 않은 경로로 접속하면 404 Not Found
(8) 500 에러도 자주 뜨던데 이거 뭔지 잘 모르겠다.
(9) 지정된 포트로 오는 요청을 항상 귀담아 듣겠소
Router
airportRouter.js
const { findAll } = require('../controller/airportController');
const express = require('express');
const router = express.Router(); // (1)
router.get('/', findAll); // (2)
module.exports = router;
(1) 라우터 기능을 사용하려면 입력해야 하는 코드
(2) localhost:3001/airport 로 접속하면 findAll 함수 작동(특정 엔드포인트를 지정해주는 것이 아니면 모든 비행편 보여준다는 뜻인 듯)
bookRouter.js
const {
findAll,
findByPhone,
findByPhoneAndFlightId,
create,
deleteByBookingId
} = require('../controller/bookController');
const express = require('express');
const router = express.Router();
router.get('/', findAll);
router.get('/:phone', findByPhone);
router.get('/:phone/:flight_uuid', findByPhoneAndFlightId);
router.post('/', create);
router.delete('/:booking_uuid', deleteByBookingId);
module.exports = router;
- GET 요청 3가지, POST 요청, DELETE 요청
flightRouter.js
const { findAll, findById, update } = require('../controller/flightController');
const express = require('express');
const router = express.Router();
router.get('/', findAll);
router.get('/:uuid', findById);
router.put('/:uuid', update);
module.exports = router;
- GET 요청 2가지, PUT 요청
Repository
airportList.js
module.exports = [
{
name: '제주',
code: 'CJU'
},
{
name: '인천',
code: 'ICN'
},
{
name: '부산',
code: 'PUS'
},
{
name: '광주',
code: 'KWJ'
},
{
name: '방콕',
code: 'BKK'
},
{
name: '세부',
code: 'CEB'
},
{
name: '하노이',
code: 'HAN'
},
{
name: '오사카',
code: 'KIX'
},
{
name: '하얼빈',
code: 'HRB'
},
{
name: '웨이하이',
code: 'WEH'
},
{
name: '홍콩',
code: 'HKG'
}
];
flightList.js
module.exports = [
{
uuid: 'af6fa55c-da65-47dd-af23-578fdba40bed',
departure: 'ICN',
destination: 'CJU',
departure_times: '2021-12-02T12:00:00',
arrival_times: '2021-12-03T12:00:00'
},
{
uuid: 'af6fa55c-da65-47dd-af23-578fdba40byd',
departure: 'ICN',
destination: 'PUS',
departure_times: '2021-12-03T12:00:00',
arrival_times: '2021-12-03T12:00:00'
},
{
uuid: 'af6fa55c-da65-47dd-af23-578fdba48bed',
departure: 'ICN',
destination: 'CJU',
departure_times: '2021-12-03T12:00:00',
arrival_times: '2021-12-04T12:00:00'
},
{
uuid: 'af6fa55c-da65-47dd-af23-578fdbr40bed',
departure: 'ICN',
destination: 'CJU',
departure_times: '2021-12-03T12:00:00',
arrival_times: '2021-12-04T12:00:00'
},
{
uuid: 'af6fa55c-da65-47dd-af23-578fd7a40bed',
departure: 'ICN',
destination: 'BKK',
departure_times: '2021-12-02T12:00:00',
arrival_times: '2021-12-03T12:00:00'
},
{
uuid: 'af6fa55c-da65-47dd-af23-578fdba40bod',
departure: 'ICN',
destination: 'CJU',
departure_times: '2021-12-02T12:00:00',
arrival_times: '2021-12-03T12:00:00'
},
{
uuid: 'af6fa55c-da65-47dd-af23-578fdba44bed',
departure: 'ICN',
destination: 'CJU',
departure_times: '2021-12-03T12:00:00',
arrival_times: '2021-12-03T12:00:00'
},
{
uuid: 'af6fa55c-da65-47dd-af23-578fdba42bed',
departure: 'CJU',
destination: 'ICN',
departure_times: '2021-12-03T12:00:00',
arrival_times: '2021-12-04T12:00:00'
},
{
uuid: 'af6fa55c-da65-47dd-af23-578fdba41bed',
departure: 'CJU',
destination: 'ICN',
departure_times: '2021-12-03T12:00:00',
arrival_times: '2021-12-03T12:00:00'
},
{
uuid: 'af6fa55c-da65-47dd-af23-578fdba99bed',
departure: 'CJU',
destination: 'ICN',
departure_times: '2021-12-03T12:00:00',
arrival_times: '2021-12-04T12:00:00'
},
{
uuid: 'af6fa55c-da65-47dd-af23-578fdba50bed',
departure: 'CJU',
destination: 'ICN',
departure_times: '2021-12-02T12:00:00',
arrival_times: '2021-12-03T12:00:00'
}
];
Controller
airportController
const airports = require('../repository/airportList');
module.exports = {
findAll: (req, res) => {
if (req.query.query !== undefined) {
const filteredAirports = airports.filter((airport) =>
airport.code.includes(req.query.query.toUpperCase())
);
return res.status(200).json(filteredAirports);
}
res.json(airports);
}
};
GET 요청 /airport?query={query}
을 수행한다.
GET 요청의 URI가 localhost:3001/airport?query=cju
라면
airports(공항 리스트 배열)
의 요소(객체) 중 code(키 값)
가 'CJU'인 것만 필터링해서 응답한다.
return res.status(200).json(filteredAirports);
이 부분은 그냥 GET 요청 공식이라고 생각하고 외워두자.
bookController.js
const { v4: uuid } = require('uuid');
let booking = [];
module.exports = {
findAll: (req, res) => {
return res.status(200).json(booking);
},
findByPhone: (req, res) => {
const { phone } = req.params;
if (req.params.phone !== undefined) {
const bookFiltered = booking.filter((el) =>
el.phone === req.params.phone
)
return res.status(200).json(bookFiltered);
}
},
findByPhoneAndFlightId: (req, res) => {
const { phone, flight_uuid } = req.params;
if (req.params.phone !== undefined && req.params.flight_uuid !== undefined) {
const phoneUuidFiltered = booking.filter((el) =>
el.phone === req.params.phone &&
el.flight_uuid === req.params.flight_uuid
)
return res.status(200).json(phoneUuidFiltered);
}
res.json(req.params);
},
create: (req, res) => {
const booking_uuid = uuid();
const { flight_uuid } = req.body;
const { name } = req.body;
const { phone } = req.body;
const newBook = {
"booking_uuid": booking_uuid,
"flight_uuid": flight_uuid,
"name": name,
"phone": phone,
}
booking.push(newBook);
res.status(201).json(booking);
},
deleteByBookingId: (req, res) => {
const index = booking.findIndex((el) => {
return el.booking_uuid === req.params.booking_uuid;
});
if(index === -1) return res.status(404).json('예약되지 않은 항공편입니다.');
const { booking_uuid } = booking[index];
booking.splice(index, 1);
return res.status(200).json({ booking_uuid });
}
};
너무 기니까 하나씩 뜯어서 볼게용
1.
findAll: (req, res) => res.status(200).json(booking)
그냥 예약 전체 목록 보여줘라
2.
findByPhone: (req, res) => {
const { phone } = req.params;
if (req.params.phone !== undefined) {
const bookFiltered = booking.filter((el) =>
el.phone === phone
)
return res.status(200).json(bookFiltered);
}
}
URI가 localhost:3001/book/010-1234-5678
일 때,
req.params
는 { phone: '010-1234-5678' }
이다. 왜 그럴까?
진짜 왜 그렇지?
왜긴 왜야 프론트에서 요청할 때 그렇게 했겠지..
예약 목록 중에서 phone(키 값)
이 변수 phone(req.params.phone)
과 같은 것만 필터링한다.
3.
create: (req, res) => {
const booking_uuid = uuid();
const { flight_uuid } = req.body;
const { name } = req.body;
const { phone } = req.body;
const newBook = {
"booking_uuid": booking_uuid,
"flight_uuid": flight_uuid,
"name": name,
"phone": phone,
}
booking.push(newBook);
res.status(201).json(booking);
}
예약 생성.
uuid()
는 임의의 id를 생성해주는 모듈이다.
newBook
이라는 새로운 객체를 만들어서 booking(예약 목록 배열)
에 push해준다.
4.
deleteByBookingId: (req, res) => {
const index = booking.findIndex((el) =>
el.booking_uuid === req.params.booking_uuid
);
if(index === -1) return res.status(404).json('예약되지 않은 항공편입니다.');
const { booking_uuid } = booking[index];
booking.splice(index, 1);
return res.status(200).json({ booking_uuid });
}
};
예약 삭제.
findIndex
메서드를 활용해서 예약 목록의 booking_uuid
중,
req.params.booking_uuid
와 같은 것의 인덱스를 찾는다.
그 인덱스의 booking_uuid
요소를 리턴한다.
flightController.js
const flights = require('../repository/flightList');
const fs = require('fs');
module.exports = {
findAll: (req, res) => {
const { departure_times, arrival_times, destination, departure } = req.query;
if(departure_times !== undefined && arrival_times !== undefined) {
const timesFiltered = flights.filter((el) => {
return (el.departure_times === departure_times &&
el.arrival_times === arrival_times)
})
return res.status(200).json(timesFiltered);
}
if(departure !== undefined && destination !== undefined) {
const locationFiltered = flights.filter((el) => {
return (el.departure === departure &&
el.destination === destination);
})
return res.status(200).json(locationFiltered);
}
return res.json(flights);
},
findById: (req, res) => {
const { uuid } = req.params;
// TODO:
if(req.params.uuid !== undefined) {
const uuidFiltered = flights.filter((el) =>
el.uuid === req.params.uuid
)
return res.status(200).json(uuidFiltered)
}
},
update: (req, res) => {
const { uuid } = req.params;
const bodyData = req.body;
let index;
if(uuid !== undefined){
index = flights.findIndex((el) => el.uuid === uuid);
console.log(index);
flights[index] = {
...flights[index],
...bodyData,
}
console.log(flights);
}
return res.status(201).json(flights[index]);
}
};
이것도 끊어서 한 번 볼까용?
1.
findAll: (req, res) => {
const { departure_times, arrival_times, destination, departure } = req.query;
if(departure_times !== undefined && arrival_times !== undefined) {
const timesFiltered = flights.filter((el) => {
return (el.departure_times === departure_times &&
el.arrival_times === arrival_times)
})
return res.status(200).json(timesFiltered);
}
if(departure !== undefined && destination !== undefined) {
const locationFiltered = flights.filter((el) => {
return (el.departure === departure &&
el.destination === destination);
})
return res.status(200).json(locationFiltered);
}
return res.json(flights);
}
위에서 계속 봐서 이제 좀 지겹죠?
하지만 우리는 계속 봐야 합니다 이것을
URI에 무엇이 실려오냐에 따라 두가지 경우로 나뉜다.
1) 출발 시간, 도착 시간이 포함되어 있을 때
비행편의 목록 중 자신의 departure_times와 arrival_times가 departure_times(req.query.departure_times), arrival_times(req.query.arrival_times)
와 같은 것을 필터링한다.
2) 출발지, 도착지가 포함되어 있을 때
비행편의 목록 중 자신의 departure, destination이 departure(req.query.departure), destination(req.query.destination)
와 같은 것을 필터링한다.
2.
findById: (req, res) => {
const { uuid } = req.params;
if(uuid !== undefined) {
const uuidFiltered = flights.filter((el) => el.uuid === uuid);
return res.status(200).json(uuidFiltered);
}
}
비행편의 목록 중 자신의 uuid가 uuid(req.params.uuid)
와 같은 것을 필터링한다.
3. PUT
update: (req, res) => {
const { uuid } = req.params;
const bodyData = req.body;
let index;
// 원본 배열이 수정되어야 한다
if(uuid !== undefined){
index = flights.findIndex((el) => el.uuid === uuid);
flights[index] = {
...flights[index],
...bodyData,
}
}
return res.status(201).json(flights[index]);
}
비행편의 목록 중 자신의 uuid가 <code>uuid(req.params.uuid)</code>와 같은 것을 찾아 그 인덱스를 저장한다.
비행편의 목록 중 그 인덱스를 가진 것을 수정한다. (스프레드 문법 이용. 뒤의 키 값이 앞의 것과 같다면 덮어 쓴다.)
'프론트엔드 개발 > Node.js' 카테고리의 다른 글
Node.js 이벤트, eventEmitter (0) | 2023.02.06 |
---|---|
Stream, Pipe (0) | 2023.02.06 |
Buffer (0) | 2023.02.06 |