컨베이어 벨트 위에 올라가있는 request에 무언가 악세사리를 붙이거나, 불량품이라면 밖으로 걷어내는 역할을 한다. 미들웨어는 express의 큰 장점 중 하나다. express 애플리케이션은 기본적으로 일련의 미들웨어 함수 호출이다.
node.js를 이용해 구현할 때마다 번거로운 작업을, 보다 손쉽게 해결해주는 역할을 한다.
2,3번은 express에서 흔히 사용되는 써드파티 미들웨어이다.
순수 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가 담겨져 있습니다.
})
순수 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 모듈을 이용해서 편리하게 사용할 수 있다. (라이브러리 설치)
HTTP요청에서 토큰(사용자인증을 위해 쓰는 것)이 있는지 여부를 판단하여, 이미 로그인한 사용자는 '성공' 아닌 경우 '에러'를 보내는 미들웨어이다.
app.use((req, res, next) => {
// 토큰 있니? 없으면 받아줄 수 없어!
if(req.headers.token){
req.isLoggedIn = true;
next()
} else {
res.status(400).send('invalid user')
}
})
쉽게 RESTful api를 만들 수 있도록 도와주는 프로그램이다.
Representational State Transfer의 약자로, 인터넷 브라우저에서 쓰이는 언어형식이다. 요청과 응답을 json형식으로 한다. 클라우드 서비스가 활성화되면서 뜨게 된 개념이다.RESTful api란
front-end와 back-end의 작업 속도가 다를 때가 많다. 원래는 프론트가 반쯤 앞서나가야하는데, 실제로는 백쪽이 더 빨리 진도가 나가는 경우가 많다. 그럴때 back-end는 대강 페이지를 만들고 어떻게 데이터를 처리할지 로직을 짠다. Postman은 그럴때 json으로 정보를 뿌려줌으로써 back-end의 개발속도를 높일 수 있게 한다.
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와 연결해줍니다. 없으면 생성해줍니다.
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);
});
저장 해주시면 끝!