내일할일, Todo-List 프로젝트 (Node.js, MySQL)
간단한 To-Do List로 시작
친구가 자바 서블릿 기반의 TodoList 웹을 만드는 것을 보고, MySQL과 NodeJS를 활용하면 새로고침 없는 TodoList를 만들 수 있을 것 같아서 바로 진행에 돌입했다. 하지만 노드를 완벽히 공부하지 않고 접근하다 보니 진입장벽이 꽤 높았다. 프론트엔드와 백엔드의 자연스러운 연결이 관건이었다. 이번 TodoList의 핵심은 "새로고침은 없어야 한다"였다.그렇게 적당한 이름을 짓고 시작할까 하다가 "내일 할 일"이라는 노래의 제목이 마음에 들었고 개발에 돌입했다.
디자인부터 대충 잡아보자
기본적인 틀은 위 사진과 같다. 일 추가하기 버튼을 누르면 hide 속성의 할일 등록 div 개체가 inline-block 개체로 바뀌고, 화면 중간에서 보이게 된다. 위 과정에서 HTML과 CSS의 기본적인 이해가 필요했다.
SQL에 넣을 할 일에 대한 데이터는 일의 제목, 누가 하는지, 우선 순위 3가지이다. form을 만들어 post 방식으로 노드와 연동할 수 있게 만들었다.
하나씩 기능 구현해보기
이제 만들어야 하는 동작은 할일 등록을 통해 일을 추가하면 첫번째 "할 일" 밑에 새로고침 없이 추가되고, 각각의 할 일마다 옆 칸(하고 있는 일, 한 일)으로 이동할 수 있게 화살표를 역시나 새로고침 없이 옮길 수 있어야 한다는 것이었다. 마지막으로 한 일로 들어가면 해당 할 일 데이터를 삭제할 수 있게 하고 싶었다.정리하면 "일 추가하기", "한 일 옮기기", "끝난 일 삭제하기"를 새로고침 없이 구현하는 것. 그리고 이 모든 것은 SQL의 데이터와 연동해야 한다는 것.
몽고DB를 사용할지 MySQL을 사용할지 고민하다가 빠른 속도보다는 저장과 view가 안정적인(내가 보기에 편한) 관계형 DB가 나을 것 같아서 간단하게 MySQL을 사용하기로 했다.
구현 중 가장 어려웠던 것은 일을 추가하면 대체 어떻게 할 일에 일이 들어갈 지였다. appendChild 메소드를 사용하려고 했는데 그렇게 하면 각각의 node 개체에 대한 처리가 매우 힘들어질 것 같고, css를 일관되게 설정하기에도 문제가 많았다. 한참의 고민 끝에 Table을 사용하기로 했다. ejs와 table을 사용한다면 다이나믹한 웹을 만들 수 있을 것 같았다.
할 일 페이지의 테이블 부분만 보면
<table>
<% doneList.forEach(function(item, index){ %>
<tr>
<td class="t_title" colspan="2"><%= item.title %></td>
</tr>
<tr>
<td class="t_detail">작성 <%= item.day %>, <%= item.who %>, <%= item.rank %>순위</td>
<td class="t_del" onclick="location.href = '/process/deltodo/<%= item.id %>'">
×
</td>
</tr>
<% }); %>
</table>
| cs |
Node에서 HTML로 ejs를 렌더링할 때 각각의 todolist 데이터를 파라미터로 보내고, forEach 메소드를 이용하여 각각 옵션(할 일, 한 일, 하고 있는 일)마다 일의 개수에 맞게 테이블을 정의하면 되는 것이었다.
MySQL에서 mytodo DB를 만든 후 todo에 릴레이션을 넣는다. 한 일, 할 일은 status 컬럼의 숫자로 구분하고, 작성일은 노드에서 오늘 날짜로 sql에 삽입한다.
sql과 노드를 연동하는 과정에서 구글링을 1000페이지는 한 것 같다..
먼저 가장 핵심이 되는 MainPage 라우터이다. 왜 가장 핵심이나면 어떠한 데이터의 변경이 있을 때마다 노드의 라우터는 마지막에 main으로 redirect한다. 가장 간단하고, 새로고침 없는 능동적인 페이지를 만드는 아이디어였다.
fs.readFile('./public/index.html', 'utf8', function (error, data) {
if (error) {
console.dir(error);
} else {
mySqlClient.query('SELECT * FROM `todo` WHERE `userid` = ? ORDER BY `rank` ASC, `id` ASC;', [logined_userid], function (error, rows) {
if (error) {
console.log('error : ', error.message);
return;
} else {
var rows_todo = [],
rows_doing = [],
rows_done = [];
var todo_sign = 0,
doing_sign = 0,
done_sign = 0;
for (var i = 0; i < rows.length; i++) {
if (rows[i].status == 1) {
rows_todo[todo_sign] = rows[i];
todo_sign++;
} else if (rows[i].status == 2) {
rows_doing[doing_sign] = rows[i];
doing_sign++;
} else if (rows[i].status == 3) {
rows_done[done_sign] = rows[i];
done_sign++;
}
}
console.log('데이터 성공적 분류함');
res.send(ejs.render(data, {
todoList: rows_todo,
doingList: rows_doing,
doneList: rows_done
}));
return true;
}
});
}
})
| cs |
status 컬럼의 숫자에 따라 할 일, 하고 있는 일, 한 일을 구분하여 각각의 객체에 저장하고 그 데이터를 ejs 렌더링 데이터로 넣어주었다. 이렇게 하면 쓸데 없는 데이터를 미리 선언하지 않아도 갯수에 맞게 능동적으로 선언되어 렌더링되기 때문에 효율적이라고 생각했다.
이렇게 간단한
먼저 그럴듯한 메인 로그인 페이지를 만들고,
그럴듯한 회원가입 페이지도 만든다.
디자인은 영어로 무난하게 하려고 하다가 서비스 이름이 "내일 할 일"인데 thank you라고 하면 역설적인 것 같아서 아름다운 한글을 사용하려 노력했다.
생각해보니 회원가입은 그냥 막 시키면 아이디가 꼬여버려 엄청난 문제가 발생할 것이고, 검증하는 함수가 필요했다.
//회원가입 검증 함수 for 라우터
var checkReg = function (id, pw, pw2, name) {
if (pw != pw2) {
return '비밀번호가 다릅니다.';
} else if (pw.length < 4) {
return '비밀번호를 4자 이상 입력하세요.';
} else if (id.length < 4) {
return '아이디를 4자 이상 입력하세요.';
} else if (name.length < 2) {
return '이름을 2자 이상 입력하세요.';
}
return 1;
}
| cs |
이렇게 기본적인 회원가입에 대한 데이터를 검증하는 함수를 라우터를 통해 거쳐갈 수 있게 작성했고, 아이디 중복 확인은 (이 경우가 가장 까다로웠다)
//회원가입 검증 함수에서 통과되면
//아이디 중복 검사
mySqlClient.query('select userid from user where userid = ?', [paramId], function (error, row) {
if (row.length > 0) {
fs.readFile('./public/register.html', 'utf8', function (error, data) {
res.send(ejs.render(data, {
focus: 'userid',
reginfo: '중복된 아이디입니다.',
username: paramName,
userid: paramId,
regroute: paramReg
}));
});
return true;
} else { ...
| cs |
이렇게 userid에 대한 row가 0보다 크면 중복된 아이디가 있다는 것이기 때문에 row 개체의 길이가 0보다 크지 않은 경우 회원가입을 진행했다. 원래 이 코드를 검증 함수에 넣고 싶었는데 비동기식으로 코드가 넘어가다 보니 계속 꼬여버려서 회원가입 라우터에 추가할 수 밖에 없었다.
회원가입하면 이렇게 user 테이블에 데이터가 저장된다. user 테이블의 userid와 todo 테이블의 userid를 key로 참조시키면 todo 테이블에 임의의 데이터가 저장되는 등의 할 일 데이터가 꼬일 일은 없다.
그럴듯한 할 일 메모 애플리케이션 "내일 할 일" 제작이 끝났다. 완성된 프로젝트 폴더는 github에 올려두었다. sql, nodejs를 공부한 지 얼마 안 된 분들은 도움이 되리라 믿는다.
Repository: https://github.com/zinirun/Tomorrow-ToDo
댓글 없음: