참고: 2022 AI/SW 온라인 실무 교육 (2022aionline.elice.io)
✔️ MVC 패턴
MVC 패턴은 웹 서비스의 가장 대표적인 프로젝트 구성 패턴으로
프로젝트 기능들을 어떻게 분리할지에 대한 하나의 구성 방법이다.
Model - View - Controller 로 구조화되어있는 패턴이다.
1) Model
- 데이터에 접근하는 기능 또는 데이터 그 자체를 의미한다.
- 데이터의 읽기, 쓰기는 Model을 통해서만 이루어지도록 구성해야 한다.
2) View
- 데이터를 표현하는 기능으로 Controller에 의해 데이터를 전달받는다.
- 전달받은 데이터를 화면에 표현한다.
3) Controller
- Model을 통해 데이터에 접근한다.
- 처리 결과를 View로 전달하는 기능을 의미한다.
- 웹 서비스에서는 주로 라우팅 함수가 해당 기능을 수행한다.
Express.js에서는 Node.js의 모듈화를 이용해 MVC 패턴을 구현한다.
JSON API를 구현할 때 기본적으로 JSON을 처리하는 Node.js 이기 때문에
View를 생략할 수도 있다.
해당 과정에서는 JS의 Array 함수를 사용해 데이터를 처리하고
router와 route handler를 사용해 HTTP 요청과 응답 처리를 구현한다.
또한, 오류처리 middleware를 사용해 오류를 처리하고
정의되지 않은 라우팅에 대해서는 404 오류를 처리하는 것을 구현한다.
✔️ 메모 목록 구현하기
- models/note.js에서 JSON 객체를 생성
- exports.list를 통해 map으로 객체를 반환
- routes/notes.js에서는 Router 객체를 생성하여 루트 경로를 생성
- 루트 경로에서는 Note.list()를 통해 목록을 보여줌 (res.json)
✔️ 메모 상세 구현하기
- routes/notes.js의 router.get의 :id 파라미터를 통해 id 인자를 받음
- models/note.js에서 exports.get의 (id) 인자를 받아서 값을 받음
- id를 잘 받아서 note를 가져오면 res.json(note)로 반환하고,
오류가 난다면 next(e)를 하여 오류 처리 미들웨어로 구현
✔️ 메모 작성 구현하기
- routes/notes.js에서 router.post의 루트 경로에서 req.body에서
뽑아오는 title과 content를 Note.create 함수를 통해서 생성
- 이후 res.json(note)로 담아준 것을 models/note.js에 전달
- exports.create = (title, content) 인자를 통해서 값 전달받음
- id를 받아서 newNote 객체를 생성하여 id에 1을 더한 게시글을 생성하고
notes.push(newNote)로 푸시함
✔️ 메모 수정 구현하기
- routes/notes.js의 router.put의 :id 파라미터 인자로 받아온 게시글을 수정함
- id와 일치하면 Note.update(id, title, content)를 수행함
- models/note.js에서 exports.update에서 notes.findIndex()를 진행하여
인덱스를 확인하고 인덱스가 일치하면 note.title, note.content, notes[index] = note;
과정을 통해서 업데이트 하게됨
✔️ 메모 삭제 구현하기
- routes/notes.js의 router.delete의 :id 파라미터 인자로 받아온 게시글을 삭제함
- Note.delete(id)를 통해 해당하는 id 값을 지워줌
- models/note.js의 exports.delete에서 받은 id 인자값이 일지하게 되면
notes.filter()를 통해 해당하는 id의 게시글을 삭제하게 됨
✔️ JSON 데이터 처리 미들웨어 사용하기
express.js는 기본적으로 HTTP body에 전달되는 JSON 데이터를 처리하지
못하기 때문에 기본적으로 제공하는 express.json() 미들웨어를 사용하여
JSON 데이터를 사용할 수 있다.
✔️ 오류 처리 미들웨어 구현하기
가장 마지막 미들웨어로 res.status(500)을 설정해주고,
res.json의 result와 error 객체 값을 설정하여 모든 라우팅에 공통적인
오류처리 로직을 작성해준다.
또한, 정의되지 않은 라우팅에는 res.status(404)를 설정하여
result는 fail, error에는 Page Not Found 문자를 전달하여
설정된 경로가 없는 요청을 처리하는 Route Handler로 동작하게 한다.
✔️ 실습 일부분 구현하기
① 라우터의 request handler에 author 인자값 받기 (routes/notes.js)
router.post('/', (req, res, next) => {
const { title, content } = req.body;
const author = req.get('author');
const note = Note.create(title, content, author);
res.json(note);
});
해당 내용은 models/note.js에 인자로 추가되어 있는 author 값을 받기 위해서
req.get('author)를 활용해서 routes에 값을 받아주고 CRUD에서 해당 값을 받아준다.
router.put, router.delete에서도 동일하게 진행해주고,
Note.delete(id, author)를 추가해서 삭제에서도 값을 받아준다.
② GET /notes 요청에 search 쿼리 파라미터 전달 시 JSON 반환하기
router.get('/', (req, res, next) => {
const notes = Note.list();
res.json(notes);
});
router.get('/', (req, res, next) => {
const { search } = req.query;
if (search) {
const notes = Note.search(search);
res.json(notes);
return;
}
const notes = Note.list();
res.json(notes);
});
기존 위에 있던 코드블럭에서 아래 코드블럭으로 search 파라미터의
검색 시 JSON 객체 반환 로직이다. /notes?search=값 형태로 받기 위해서
req.query를 사용해 받을 파라미터를 입력하고 해당 값이 입력되면
res.json으로 화면에 notes 값을 JSON 객체로 뿌려준다.
③ auth.js 모듈의 auth 미들웨어에서 author 헤더 값이 admin인 경우와
password 헤더 값이 1234가 아닌 경우 오류처리 미들웨어로 오류 전달하기
module.exports = (req, res, next) => {
const author = req.get('author');
if (!author) {
next(new Error('No Author'));
return;
}
next();
};
module.exports = (req, res, next) => {
const author = req.get('author');
const password = req.get('password');
if (!author) {
next(new Error('No Author'));
return;
}
// admin 확인하기
if (author === 'admin') {
if (password != '1234') {
next(new Error('Invalid Admin Password'));
return;
}
}
next();
};
위의 기존 코드블럭에서 헤더에 새롭게 받을 password를 변수로 추가하고
if문을 구성해준다. 헤더의 author와 password가 각각 admin과 1234가 아닐 경우,
next() 인자를 통해 new Error 값을 전달해주면서 오류처리 미들웨어를 불러온다.
app.use((req, res, next) => {
res.status(404);
res.json({
result: 'fail',
error: `Page not found ${req.path}`,
});
});
app.use((err, req, res, next) => {
res.status(500);
res.json({
result: 'fail',
error: err.message,
});
});
참고로 해당 실습의 오류처리 미들웨어는 이처럼 구성되어 있다.
Node.js의 Express.js를 배우면서 간단히 공부해보았다.
예전에 사용해본적이 있고 react를 경험해봐서 코드가 수월하게 이해되었고,
MVC 패턴 및 REST API 가이드에 대해서 복습할 수 있었다.
화이팅 💪