[엘리스 sw 엔지니어 트랙] 28일차미들웨어, postman, mongoose

오경찬·2022년 5월 23일
0

수업 28일차

express의 꽃 미들웨어를 배워보고 다른 프로그램인 postman과 mongoose를 알아보자

이론

  • 미들웨어: 요청과 응답 사이에 처리되는 함수들
    postman: get/post/put/delete 같은 호출을 편하게 하기위한 도구
    데이터베이스: 데이터를 통합 관리하기 위한 개념
    mongodb: Nosql 데이터베이스의 대표 주자
    Nosql: 스키마가 없는것, 데이터를 유연하게 저장
    RDB: 테이블 간의 관계를 설정할 수 있음
    mongoose: Node.js와 MongoDB를 위한 ODM 라이브 러리, DB를 읽어와 객체화 해줌

미들웨어

컨베이어 벨트 위에 올라가있는 request에 무언가 악세사리를 붙이거나, 불량품이라면 밖으로 걷어내는 역할을 한다. 미들웨어는 express의 큰 장점 중 하나다. express 애플리케이션은 기본적으로 일련의 미들웨어 함수 호출이다.

미들웨어가 주로 쓰이는 상황

  1. 모든 요청에 대해 url이나 메소드를 알고자 할 때
  2. POST 요청 등에서 쓰이는 body(payload)를 쉽게 얻어내고자 할 때
  3. 모든 요청/응답에 CORS 헤더를 붙일 때
  4. 요청 헤더에 사용자 인증 정보가 담겨있는지 확인하고 싶을 때

node.js를 이용해 구현할 때마다 번거로운 작업을, 보다 손쉽게 해결해주는 역할을 한다.

2,3번은 express에서 흔히 사용되는 써드파티 미들웨어이다.

body-parser 미들웨어 - 2번

순수 node.js 코드를 이용할 때 HTTP body(payload)를 받아내기 위해서는 Buffer를 조합해 다소 복잡한 방식으로 body를 얻어내야하지만, 이를 쉽게 바꿔주는 역할을 하는 것이 body-parser 미들웨어 이다.

const bodyParser = require('body-parser')
const jsonParser = bodyParser.json()

// 생략
app.post('/api/users', jsonParser, function (req, res) {
  // req.body에는 JSON의 형태로 payload가 담겨져 있습니다.
})

cors 미들웨어 - 3번

순수 node.js 코드로 CORS 헤더를 붙이기 위해서는 writeHead 메소드 등을 이용하여 Access-Control-Allow-* 헤더를 정의해줘야 했다. OPTIONS 메소드에 대한 라우팅도 구현해줘야 했지만 이를 쉽게 해주는 역할이 cors 미들웨어 이다.

const cors = require('cors')

// 생략
app.use(cors()) // 모든 요청에 대해 CORS 허용
const cors = require('cors')

// 생략
// 특정 요청에 대해 CORS 허용
app.get('/products/:id', cors(), function (req, res, next) {
  res.json({msg: 'This is CORS-enabled for a Single Route'})
})

미들웨어 작동원리

모든 요청에 대해 url이나 메소드를 알고자 할 때 - 1번
가장 단순한 미들웨어는 logger이다. console.log와 같이 디버깅이나 서버 관리에 도움이 되기 위해 log를 찍어주는 역할을 합니다.

미들웨어 함수 안의 파라미터 순서대로 진행이 되는데, req,res는 요청/응답을 의미하고 next는 다음 컨베이어벨트로 넘기는 작업을 한다. 위 함수에서는 next()를 호출해서 다음 컨베이어 벨트로 넘길 뿐, 아무런 일을 하지 않고 있다.

이번엔 특정 endpoint가 아닌, 모든 요청에 대해서 미들웨어를 붙여보자. 이때에는 app.use라는 메소드를 이용한다. 아래 코드를 직접 실행하여. 모든 요청에 대해 LOGGED가 콘솔에 찍히는 것을 확인해야한다.

목표는 아래와같이 모든 요청에 대한 메소드와 url을 찍어야 한다.

const express = require('express');
const app = express();

const myLogger = function (req, res, next) {
  console.log('LOGGED'); 
  // 이 부분을 req, res 객체를 이용해 고치면, 모든 요청에 대한 로그를 찍을 수 있습니다.
  next();
};

app.use(myLogger);

app.get('/', function (req, res) {
  res.send('Hello World!');
});

app.listen(3000);

해당 Logging 부분은 추후 morgan 이나 winston 모듈을 이용해서 편리하게 사용할 수 있다. (라이브러리 설치)

요청 헤더에 사용자 인증 정보가 담겨있는지 확인하고 싶을 때 - 4번

HTTP요청에서 토큰(사용자인증을 위해 쓰는 것)이 있는지 여부를 판단하여, 이미 로그인한 사용자는 '성공' 아닌 경우 '에러'를 보내는 미들웨어이다.

app.use((req, res, next) => {
  // 토큰 있니? 없으면 받아줄 수 없어!
  if(req.headers.token){
    req.isLoggedIn = true;
    next()
  } else {
    res.status(400).send('invalid user')
  }
})

Postman

쉽게 RESTful api를 만들 수 있도록 도와주는 프로그램이다.

REST

Representational State Transfer의 약자로, 인터넷 브라우저에서 쓰이는 언어형식이다. 요청과 응답을 json형식으로 한다. 클라우드 서비스가 활성화되면서 뜨게 된 개념이다.RESTful api란

Postman을 쓰는 이유

front-end와 back-end의 작업 속도가 다를 때가 많다. 원래는 프론트가 반쯤 앞서나가야하는데, 실제로는 백쪽이 더 빨리 진도가 나가는 경우가 많다. 그럴때 back-end는 대강 페이지를 만들고 어떻게 데이터를 처리할지 로직을 짠다. Postman은 그럴때 json으로 정보를 뿌려줌으로써 back-end의 개발속도를 높일 수 있게 한다.

mongoose

MongoDB ODM 중 가장 유명한 라이브러리입니다.
데이터베이스 연결, 스키마 정의, 스키마에서 모델로 변환, 모델을 이용해 데이터를 다룸
프로미스와 콜백 사용가능

ODM : Object Document Mapping의 약자입니다. 객체와 문서를 1대 1로 매칭해줍니다. 즉, MongoDB에 있는 데이터를 NodeJS에서 Javscript 객체로 사용할 수 있도록 해줍니다.

연결

const mongoose = require("mongoose");

mongoose
  .connect("mongodb://127.0.0.1:27017/task-manager", {
    useNewUrlParser: true,
    useCreateIndex: true,
  })
  .then(() => {
    console.log("Connected to MongoDB");
  })
  .catch((err) => {
    console.log(err);
  });

task-manager라는 DB와 연결해줍니다. 없으면 생성해줍니다.

  • useNewUrlParser : Flag for using new URL string parser instead of current (deprecated) one.
  • useCreateIndex : If true, this connection will use createIndex() instead of ensureIndex() for automatic index builds via Model.init().

mongoose 부터는 Promise를 사용할 수 있습니다.

스키마 생성

const UserSchema = new mongoose.Schema({
  name: String,
  age: Number,
  saveDate: {
    type: Date,
    default: Date.now,
  },
});

MongoDB는 스키마가 없지만 Mongoose에서는 Schema를 정의해줄 수 있습니다. 컬렉션에 들어가는 문서 내부의 각 필드가 어떤 식으로 되어있는지 정의하는 객체라고 보면 됩니다.

모델생성

const User = mongoose.model("User", UserSchema);

모델은 스키마를 사용하여 만든 인스턴스로 데이터베이스에서 실제 작업을 처리할 수 있는 함수들을 지니고 있는 객체입니다.

User라고 썼지만 실제 데이터베이스에 가보면 컬렉션이름이 users라고 되어있습니다. 뭔가 잘못된게 아닌가 생각할 수 있겠지만 MongoDB에서 컬렉션이름을 만들때 구분자를 사용하지 않고 복수형태를 사용하는게 기본이기 때문에 자동으로 그렇게 저장된거라고 볼 수 있습니다.

객체생성

const me = new User({
  name: "Mike",
  age: 27,
});

새로운 객체를 생성해줍니다. 하나의 Document라고 볼 수 있겠네요.

저장

me.save()
  .then(() => {
    console.log(me);
  })
  .catch((err) => {
    console.log("Error : " + err);
  });

저장 해주시면 끝!

profile
코린이 입니당 :)

0개의 댓글