router메소드의 request handler만 따로 controller폴더에 파일을 생성해서 분리할수 있다. 마치 모듈처럼.
일반적인 웹 방식의 호출에서는 html 데이터를 반환하지만 브라우저가 아닌 다른 기기 (임베디드, 웹을 사용하지 않는 다른 소프트웨어/하드웨어 등) 에서는 html을 읽을 수 없다.
-> REST API: 모든 기기에서 호응 가능한 데이터만을 주고 받을 수 있게 제작한 API
router.get('/호출주소', (req, res, next) => {
~~~
return res.status(200).json({message: 'call success', result:result});
});
routes/post.js
router.post('/users', async (req, res, next) => {
try {
const userid = req.body.userid;
const job = req.body.job;
const user = new userSchema({
userid: userid,
job: job
});
const result = await user.save();
res.status(200).json({
result,
message: 'user saved'
});
} catch (error) {
console.log(error);
next(error);
}
});
Cross Origin Resource Sharing
: Fetch API()의 same-origin-policy를 넘어서 데이터를 전송할 수 있게 한다.
localhost:3000 <-> localhost:3000 : OK
localhost:4000 <-> localhost:3000 : Cors Error
에러명: Access to fetch at 'http://127.0.0.1:3000/expost/getlist'
from origin 'https://cdpn.io' has been blocked by CORS policy:
No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
해결방안1 :
app단에서 header를 설정하여 접근 제어를 허용해준다.
app.use((req, res, next) => {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Origin', 'GET, POST, PUT, PATCH, DELETE');
res.setHeader('Access-Control-Allow-Origin', 'Content-Type, Authorization');
});
해결방안2 :
npm i cors
app.js
const cors = require('cors');
app.use(cors({
origin: '*',
methods: ['GET', 'POST', 'DELETE', 'UPDATE', 'PUT', 'PATCH']
}));
models/blog.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const autoIncrement = require('mongoose-auto-increment');
// 블로그 글 제목,
// 블로그 본 글 내용.
//auto-increment.
autoIncrement.initialize(mongoose);
const blog = new Schema({
title: {
type:String,
required: true,
},
content: {
type:String,
required: true,
},
no: Number,
}, {
timestamps: true,
});
blog.plugin(autoIncrement.plugin, {
model: 'blog',
field: 'no',
startAt: 4,
increment: 1
});
const blogModel = mongoose.model('blog', blog);
module.exports = blogModel;
autoIncrement: 자동으로 숫자 매겨줌
원래는 npm i mongoose-auto-increment
인데 이렇게하면 에러난다.
그래서 다음명령어로 설치한다.
npm i mongoose-auto-increment --legacy-peer-deps
정보: https://jane-aeiou.tistory.com/79?category=1018076
그리고 autoIncrement를 사용할때는 무조건 initialize를 해야한다.
routes/blog.js
const express = require('express');
const router = express.Router();
const blogSchema = require('../models/blog');
router.get('/', async (req, res) => {
const result = await blogSchema.find({}).exec();
res.render('blog/blog', {content: result});
});
router.get('/write', (req, res) => {
res.render('blog/write');
});
router.post('/write', (req, res) => {
const title = req.body.title;
const content = req.body.content;
const blogText = new blogSchema({
title: title,
content: content,
});
blogText.save().then(result => {
console.log(result);
res.redirect('/blog');
}).catch(err => {
console.log(err);
next(err);
})
});
//localhost:3000/blog
module.exports = router;
mongoDB의 메소드를 사용할때는 exec()를 붙여줘야 한다.
정보: https://tesseractjh.tistory.com/166
그리고 .find메소드를 사용하면 반환값이 배열이다.
'/' get 메소드에서 ejs파일로 content를 넘겨주고 있는 모습이다.
req.body.title은 ejs의 name값이 title인 태그의 데이터이다.
views/blog/blog.ejs
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>Blog 실습</h1>
<br><br>
<a href="/blog/write">글쓰기</a>
<br><br>
<!-- 글 제목 -->
<p>글 내용들</p>
<% for(let i = 0; i<content.length; i++) {%>
<a href=""><%=content[i].title %></a>
<br><br>
<% } %>
</body>
</html>
content가 find의 반환값이므로 배열이라서 for문으로 전부 출력해주는것을 확인할 수 있다. 저렇게쓰는건 ejs의 문법이다.
views/blog/write.ejs
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h2>블로그 글쓰기</h2>
<form action="/blog/write" method="post">
<input type="text" name="title">
<textarea name="content" id="" cols="30" rows="10"></textarea>
<input type="submit" value="전송하기">
</form>
</body>
</html>
form action에 의해 form data가 localhost:3000/blog/write
로 전송된다.
app.js
const dayjs = require('dayjs');
app.locals.formatDate = (date) => {
return dayjs(date).format('YYYY-MM-DD HH:mm:ss');
}
if(res.ok)
가 true이려면
res.send('OK');
or res.end();
해준다.
await Post.updateOne({ shortId }, {
title,
content,
});
deleteOne
findOne