오늘은 DataBase를 Object처럼 사용할 수 있는, ORM(Object Relational Mapping)을 구현하는 Sequelize 실습을 진행했다. 오전까지 혼자 진행하고 오후부터 모여서 같이 진행했다. 같이 진행해도 시간을 아슬아슬하게 채울 정도로 빡빡한 과정이었다. 역대급으로 피곤한 스프린트였다. 단어 그대로 전력질주 후 기진맥진한 상태에서 작성하는 글이라 내가 뭘 썼는지도 모르겠다. 그리고 게더타운 스터디의 집단지성이 빛을 발한 날이기도 했다.
첫번째로 비동기, 테스트 케이스에 맞춘 MVC 구성이 어색했다. 테스트케이스를 먼저 확인하고 진행했으면 불필요한 파일, 폴더 추가생성과 이름변경을 생략할 수 있었다. routes 디렉토리 아래에 link 디렉토리를 만들고 index.js 파일을 만드는 구성이 어색했다. 그리고 routes 파일 최하단에 module.exports = router
구문이 빠져서 미들웨어 체인이 끊어지는 에러가 발생했다.
// app.js
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use('/', indexRouter);
app.use('/links', linksRouter);
// routes/links.js
const express = require('express');
const linksController = require('../controllers/links/index.js');
const router = express.Router();
/* GET links listing. */
router.post('/', linksController.post);
router.get('/', linksController.get);
router.get('/:id', linksController.getId);
// ! exports 빼먹어서 에러났다.
module.exports = router;
두번째로 Sequelize DB 생성방법이 어색했다. sequilize-cli로 models 디렉토리 하단에 파일을 생성하고 수정한 다음 migrate
로 실제 데이터베이스를 생성한다.
# npx sequelize-cli model:generate --name urls --attributes url:string,title:string,visits:integer
New model was created at /Users/seunghoon/Codestates/Section3/im-sprint-shortly-mvc/models/urls.js .
New migration was created at /Users/seunghoon/Codestates/Section3/im-sprint-shortly-mvc/migrations/20211018052422-create-urls.js .
// 적용과 되돌리기로 스키마 변경 수행
# npx sequelize-cli db:migrate
# npx sequelize-cli db:migrate:undo
컬럼에 속성을 부여할 때 init 항목에서 옵션을 추가해줬다. 외래키를 지정할 경우 associate
메소드가 활용된다.
'use strict';
const { Model } = require('sequelize');
module.exports = (sequelize, DataTypes) => {
class url extends Model {
/**
* Helper method for defining associations.
* This method is not a part of Sequelize lifecycle.
* The `models/index` file will call this method automatically.
*/
static associate(models) {
// define association here
}
}
url.init(
{
url: DataTypes.STRING,
title: DataTypes.STRING,
visits: { type: DataTypes.INTEGER, defaultValue: 0 },
},
{
sequelize,
modelName: 'url',
}
);
return url;
};
세번째로 Request
모듈 사용법이 어색했다. 다른건... 그러려니 해도 cb, 콜백함수 처리가 햇갈렸다. 이건 기본기가 부족한 것이다. 내가 설명하면서도 깔끔하게 설명하기가 힘들었다. 복습이 필요하다.
exports.getUrlTitle = (url, cb) => {
request(url, function (err, res, html) {
if (err) {
console.log('Error reading url heading: ', err);
return cb(err);
} else {
const tag = /<title>(.*)<\/title>/;
const match = html.match(tag);
console.log(match.length)
const title = match ? match[1] : url;
return cb(err, title);
}
});
};
...
// TODO: Request 호출
module.exports = {
post: (req, res) => {
const validUrl = utils.isValidUrl(req.body.url);
// ! Callback 함수 처리 부분이 중요
utils.getUrlTitle(validUrl[0], (err, title) => {
if (err) throw err;
else {
return db.url
.create({
url: validUrl[0],
title: title,
visits: 1,
})
.then(el => res.status(201).send(el));
}
});
},