엘리스 31일차 월요일 실시간강의 CRUD 블로그

치즈말랑이·2022년 5월 16일
0

엘리스

목록 보기
32/47
post-thumbnail

박두현님 강의

Controller

router메소드의 request handler만 따로 controller폴더에 파일을 생성해서 분리할수 있다. 마치 모듈처럼.

REST API

일반적인 웹 방식의 호출에서는 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);
    }
});
  • res.status('상태코드 입력')을 통해 통신 상태를 응답해준다.

CORS

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로 전송된다.

코치님 강의

date format 변경

app.js

const dayjs = require('dayjs');

app.locals.formatDate = (date) => {
  return dayjs(date).format('YYYY-MM-DD HH:mm:ss');
}

res.ok

if(res.ok) 가 true이려면
res.send('OK'); or res.end(); 해준다.

수정

await Post.updateOne({ shortId }, {
      title,
        content,
    });

삭제

deleteOne

찾기

findOne

profile
공부일기

0개의 댓글