import Post from '../../models/post';

/* 포스트 작성
POST /api/posts
{ title, body }
*/
export const write = async ctx => {
  const { title, body, tags } = ctx.request.body;
  const post = new Post({
    title,
    body,
    tags,
  });
  try {
    await post.save();
    ctx.body = post;
  } catch (e) {
    ctx.throw(500, e);
  }
};

/* 포스트 목록 조회
GET /api/posts
*/
export const list = async ctx => {
  try {
    const posts = await Post.find().exec();
    ctx.body = posts;
  } catch (e) {
    ctx.throw(500, e);
  }
};

/* 특정 포스트 조회
GET /api/posts/:id
*/

export const read = async ctx => {
  const { id } = ctx.params;
  try {
    const post = await Post.findById(id).exec();
    if (!post) {
      ctx.status = 404; // Not Found
      return;
    }
    ctx.body = post;
  } catch (e) {
    ctx.throw(500, e);
  }
};

/* 특정 포스트 제거
DELETE /api/posts/:id
*/
export const remove = async ctx => {
  const { id } = ctx.params;
  try {
    await Post.findByIdAndRemove(id).exec();
    ctx.status = 204; // No Content
  } catch (e) {
    ctx.throw(500, e);
  }
};

/* 포스트 수정 (특정 필드 변경)
PATCH /api/posts/:id
{ title, body }
*/
export const update = async ctx => {
  const { id } = ctx.params;
  try {
    const post = await Post.findByIdAndUpdate(id, ctx.request.body, {
      // false: 업데이트 이전의 데이터 반환
      // true:  업데이트된 데이터를 반환
      new: true,
    }).exec();
    if (!post) {
      ctx.status = 404;
      return;
    }
    ctx.body = post;
  } catch (e) {
    ctx.throw(500, e);
  }
}; 

  • 설치를 하면 위처럼 새로운 connection을 생성할 수 있다.
  • connection에 mongodb://localhost:27017과 같이 입력하면 database의 리스트를 확인 가능하다
  • connection string format

  • 스키마는 컬렉션에 들어가는 문서 내부의 각 필드
  • 모델은 스키마를 사용하여 만드는 인스턴스
    • 데이터베이스에서 실제 작업을 처리하는 함수들을 지니고 있는 객체

schema와 모델 생성

  • schema와 모델에 관련한 코드는 src/models에서 관리
  • 제목, 내용, 태그, 작성일
  • Schemamongoose의 모듈을 사용
  • 아래와 같이 AuthorSchema의 경우 BookSchema의 일부로도 정의가 가능하다.
import mongoose from 'mongoose';

const { Schema } = mongoose;

const AuthorSchema = new Schema({
  name: String,
  email: String,
});

const BookSchema = new Schema({
  title: String,
  description: String,
  authors: [AuthorSchema],
  meta: {
    likes: Number,
  },
  extra: Schema.Types.Mixed,
});

const PostSchema = new Schema({
  title: String,
  body: String,
  tags: [String],
  publishedDate: {
    type: Date,
    default: Date.now,
  },
});

const Post = mongoose.model('Post', PostSchema); // schema name(=posts), schema obj, <custom collection name>
export default Post;
  • mongodb에서는 model의 파라미터 첫번째로 Post를 넘기는데 컬렉션을 생성할때 @+s로 생성
  • 만약 내가 정의하고 싶은 컬렉션의 이름이 있다면 3번째 파라미터로 custom_collection_name을 넘기면 된다.

mongoose

  • mongoose는 node.js 환경에서 사용하는 라이브러리
  • ODM (Object Data Modeling)

dotenv

  • 환경변수들을 파일에 넣고 사용할 수 있게 하는 개발 도구
  • mongoose를 사용해서 id/password를 스크립트에 작성하지 않고 환경병수로 관리.env
yarn add mongoose dotenv

ROOT에 .env 파일 생성

PORT=4000
MONGO_URI=mongodb://localhost:27017/<database>

src/index.js

require('dotenv').config();
(...)
const { PORT } = process.env;
(...)
const port = PORT || 4000;
app.listen(port, () => {
  console.log('Listening to port %s', port);
});
  • 만약 nodedemon으로 자동 재시작을 하고 있다면, .env의 파일을 변경해도 재시작을 하지 않으니 수동으로 재시작

mongoose로 서버와 데이터베이스 연결


(...) 
const { PORT, MONGO_URI } = process.env;
(...)

 mongoose
  .connect(MONGO_URI, { useNewUrlParser: true, useFindAndModify: false })
  .then(() => {
    console.log('Connected to MongoDB');
  })
  .catch(e => {
    console.error(e);
  });
  • 화면에 Connected to MongoDB가 출력되면 연결 완료.
  • RDBMS
    • 스키마가 고정
    • 확장성 (scale out이 아닌 scale up을 해야 한다)
    • 복잡한 조건으로 데이터 필터링 ACID 특성을 지키는데는 유리
      • 원자성(Atomicity), 일관성(Consistency), 고립성(Isolation), 지속성(Durability)
  • NoSQL
    • mongoDB
    • 유동적인 스키마
      • 데이터의 구조가 자주 변경이 있을때 유리
    • scale out 이 가능

MongoDB

  • _id는 시간, 머신 아이디, 프로세스아이디, 순차번호로 고유함 보장
  • 문서가 들어있는 곳을 컬렉션 (RDBMS는 테이블)
  • 서버 > 데이터베이스 > 컬렉션 > 문서
  • 문서 하나에 최대 16MB만큼 데이터를 넣을 수 있음
  • 서브다큐먼트에서 용량을 초과할 가능성이 있다면 컬렉션을 분리하자

설치

$ brew update
$ brew tap mongodb/brew
$ brew install mongodb-community@4.2
$ brew services start mongodb-community@4.2
$ mongo

로그 확인

/usr/local/var/log/mongodb/mongo.log

PORT

+ Recent posts