Sequelize.js 로 게시글-댓글 API 설계 방법

Posted by Hide­
2018.07.18 15:59 Coding/Node.js

먼저 이전글에도 작성했지만 나는 ORM을 좋아하지 않는다.

사용에 대한 어려움이랄까.

단순하게 raw query가 더 편한 느낌이다.

아직까지는 복잡한 과정을 거치지 않아서 그런것 같긴한데 추후에 코드 리팩토링이나

쿼리문이 복잡해지는 경우가 발생하면 ORM의 이점을 느낄 수 있을라나.

튼, Node.js로 API서버를 구축하고 있는데 통신하는 모듈로 Sequelize.js를 이용하고 있다.

Django Rest framework를 사용할때는 또 그것만의 ORM문법을 배워서 사용했는데,

이젠 또 다시 문법을 공부해야한다.

심지어 document도 중구난방이라 배우기가 쉽진 않았다고 생각한다.

먼저 환경은 Node.js + Express + MySQL이다.

관계형 데이터베이스를 사용하고 있으므로 Sequelize의 Association 부분을 잘 살펴봐야 한다.

먼저 테이블의 구조는 다음과 같다.


[article]

- no(PK)

- subject

- content

- created_at

- updated_at


[comment]

- no(PK)

- content

- created_at

- updated_at

- article_no(FK to article)


심플하다. 단순히 이러한 구조로 되어있을 때 어떻게 해줘야 하는지에 대한 글을 작성하기 위함이라.

또한 두개의 테이블을 아래와 같이 관계를 맺어줬다.


Article.hasMany(Comment);
Comment.belongsTo(Article);


다음으로 article과 comment테이블에 몇개의 데이터를 삽입한 후 테스트를 진행한다.

먼저 다음과 같은 코드를 작성한다.


export const getArticle = (req, res) => {
Article.all()
.then(article => {
res.status(200).json({status: true, result: article});
})
.catch(err => {
res.status(500).json({status: false, result: "get article fail"});
})
}


작성된 모든 글이 잘 나올것이다.


{  
   "status":true,
   "result":[  
      {  
         "no":1,
         "content":"comment test",
         "created_at":"2018-07-18T05:00:45.000Z",
         "updated_at":"2018-07-18T05:00:45.000Z",
         "article_no":1
      }
   ]
}

아마 이러한 구조로 값이 나올 것이다.

하지만 아래처럼 게시글에 달린 모든 댓글도 같이 표현해주고 싶다.


{  
   "status":true,
   "result":[  
      {  
         "no":1,
         "content":"comment test",
         "created_at":"2018-07-18T05:00:45.000Z",
         "updated_at":"2018-07-18T05:00:45.000Z",
         "article_no":1,
         "comments": [
            // 관련 댓글
         ]
      }
   ]
}

위처럼 말이다.

sequelize 공식 문서(http://docs.sequelizejs.com/manual/tutorial/models-usage.html#eager-loading)를 읽어보면 Eager Loading이라는 것이 있다.

무슨 뜻인지는 모르겠고, 요약하자면 find()나 findAll()을 사용할 때 include옵션을 함께 줘서

관계가 설정된 테이블의 값을 끌어올 수 있다.

위에 작성했던 getArticle을 아래와 같이 바꿔준다.


export const getArticle = (req, res) => {
Article.findAll({
include: [
{ model: Comment}
]
})
.then(article => {
res.status(200).json({status: true, result: article});
})
.catch(err => {
res.status(500).json({status: false, result: "get article fail"});
})
}


findAll()로 바꿔줬고 include옵션에 Comment 모델을 넣어줬다.

위처럼 수정해준 후 값을 출력해보면,


 
   "status":true,
   "result":[  
      {  
         "no":1,
         "subject":"test",
         "content":"hihi",
         "created_at":"2018-07-18T05:40:52.000Z",
         "updated_at":"2018-07-18T05:40:52.000Z",
         "comments":[  
            {  
               "no":1,
               "content":"comment test",
               "created_at":"2018-07-18T05:40:58.000Z",
               "updated_at":"2018-07-18T05:40:58.000Z",
               "article_no":1
            }
         ]
      },
      {  
         "no":2,
         "subject":"asksakkas",
         "content":"hihiasd",
         "created_at":"2018-07-18T06:00:15.000Z",
         "updated_at":"2018-07-18T06:00:15.000Z",
         "comments":[  
            {  
               "no":3,
               "content":"aaaatest",
               "created_at":"2018-07-18T06:00:38.000Z",
               "updated_at":"2018-07-18T06:00:38.000Z",
               "article_no":2
            },
            {  
               "no":4,
               "content":"node",
               "created_at":"2018-07-18T06:00:59.000Z",
               "updated_at":"2018-07-18T06:00:59.000Z",
               "article_no":2
            }
         ]
      }
   ]
}


이렇게 원하는대로 comments라는 값이 추가되어 관련된 댓글을 모두 불러오는걸 확인할 수 있다.



다른 사람들이 많이 읽은 글
이 댓글을 비밀 댓글로

티스토리 툴바