티스토리 뷰

[http 모듈로 웹서버 만들기]

REST  : get post put delete

받아오기 보내기 수정하기 삭제하기 구현

const http = require('http');
const fs = require('fs').promises;

const users = {};

//#req 클라이언트의 요청 들어옴# #res 서버가 클라이언트한테 반환할 것 #
const server = http.createServer(async (req, res) => {

  
  try{
    if(req.method === 'GET'){
      if(req.url ==='/'){
          const data = await fs.readFile('./restFront.html')//then의 파라미터값. await에 담긴다
          res.writeHead(200,{'Content-Type': 'text/html; charset=utf-8'})
          return res.end(data)// 리턴을 해야 분기처리가 끝난다
      } else if (req.url === '/about'){
          const data = await fs.readFile('./about.html')//then의 파라미터값. await에 담긴다
           res.writeHead(200,{'Content-Type': 'text/html; charset=utf-8'})
           return res.end(data)// 리턴을 해야 분기처리가 끝난다
      } else if (req.url ==='/users'){
        res.writeHead(200,{'Content-Type': 'application/json; charset=utf-8'})
        return res.end(JSON.stringify(users))
      }

      try{
        const data = await fs.readFile(`./${req.url}`)
        return res.end(data)
      }catch(err){
        console.error(err);
      }
    }
    else if (req.method === 'POST'){
      if(req.url === '/users'){
        let body = ''

        req.on('data',(data)=>{
          body += data 
        })
        return req.on('end',()=>{
          console.log('POST body:', body)
          const { name } = JSON.parse(body)
          const id = Date.now() //1245463453
          users[id] = name;
          console.log(users);
          res.writeHead(201,{'Content-Type': 'text/plain; charset=utf-8'})
          res.end('OK')
        })
      }
    } else if (req.method ==='PUT'){
      if(req.url.startsWith('/users/')){
        const key = req.url.split('/')[2]
        // console.log(key);
        let body = ''
        req.on('data',(data)=>{
          body += data
        })
        return req.on('end',()=>{
          console.log('put본문:',body);
          users[key]= JSON.parse(body).name
          res.writeHead(200,{'Content-Tyepe': 'text/plain; charset=utf-8'})
          res.end('ok')
        })
      }
    } else if (req.method === 'DELETE'){
      console.log(req.url);
      if(req.url.startsWith('/users/')){
        const key = req.url.split('/')[2]
        delete users[key]
        //res.writeHead(200,{'Content=Type': 'text/plain; charset=utf-8'})
        return res.end('ok')
      }
    }

  }catch(err){
    console.error(err);
    res.writeHead(500,{'Content-Type': 'text/plain; charset = utf-8'})
    res.end(err.message)
  }
})
server.listen(3002)

server.on('listening',()=>{
  console.log('3002번 포트에서 서버 대기중입니다!');
})
server.on('err',()=>{
  console.error(err);
})
  });

 

 

[EXPRESS 모듈]

http 모듈로 웹서버 만드는 게 불편해서 나온 프레임 워크 (익스프레스 내부에 http 모듈이 내장되어있으므로 서버의 역할할 수 있다.)

더 이상 REST api 메서드를 if로 구현하지 않아도 됨!

 

>>미들웨어 쓰는 2가지 방법 (next : 미들웨어 : 중간 처리)

//app.js

//파일 가져오기위해 path 모듈 사용한다.
const path = require('path')
const express = require('express')

const app = express() //익스프레스 호출

//앱가지고 set 매소드 실행 : 서버가 실행될 포트 설정 set : 데이터 저장
//나중에 get으로 가져올수 있음
app.set('port', 3000)

app.use((req,res,next)=>{ //미들웨어
  console.log('모든요청에서다시행됨');
  next()
})

//get
// app.use('/',(res,req,next)=>{
//   console.log('get/ 요청에서 실행됩니다');
//   next() // 미들웨어 next !!!!통과시킨다.
// })

// const midleware =() =>{
//   console.log('get/ 요청에서 실행됩니다');
//   next() // 미들웨어 next !!!!통과시킨다.
// }


//app(조소,라우터) get요청이 올때 어떤 동작을 할지 적는 부분
//req: 요청 xx 받아옴 // res:응답 00전송
//http에서는 res.write , res.end 사용했지만 res.send 만 사용하면 전송가능
app.get('/',(req,res,next)=>{ //주소 
  console.log('get/ 요청에서 실행됩니다');
  next() // 미들웨어 next !!!!통과시킨다.
},(req,res)=>{
  //res.send('Hello, express') 문자로 응답하는 대신
  throw new Error('error')
  //html 파일 만들어 그 파일을 열수있게 했다.
  res.sendFile(path.join(__dirname,'/index.html'))
})//get주소로 요청을 처리하겠따
app.use((err,req,res,next)=>{
  console.error(err);
  res.statu(500).send(err.message)
})


//listen 이벤트** 포트에 연결되면 로그 찍어준다.
const port = app.get('port')//포트를 불러온다.
app.listen(port,()=>{
console.log(port,'번 포트에서 서버 실행중 !');
})

 

 

[미들웨어]

미들웨어는 익스프레스의 핵심이다! 요청과 응답을 조작하여 기능을 추가하기도 나쁜 요청을 걸러내기도 한다.

app.use와 함께 사용된다.  요청과 응답 사이에 특별한 기능을 추가한다.(요청 -> morgan -> cookie parser -> 라우터 -> 에러처리 미들웨어 ->응답)

app.use(미들웨어) : 모든 요청에 실행됨

app.use('/abc', 미들웨어) : /abc 주소에서 미들웨어 실행

app.post('/abc', 미들웨어) : /abc/ 주소에서 POST 요청에서 미들웨어 실행

morgan? cookie parser?? 패키지 설치 -> 미들웨어 ex

const path = require('path')
const express = require('express')
const morgan = require('morgan')
const cookieParser = require('cookie-parser')
const session = require('cookie-parser')

const app = express()//익스프레스 호출

app.use(morgan('dev'))//로그정보 보여주는애 dev 써준다.combined 쓰면 더 자세히나옴
app.use('/',express.static(path.join(__dirname,'public')))
//(요청경로,실제경로)
//퍼블릭폴더에있는 모든 파일 접근가능.
//인터넷 주소에서 /뒤에 원하는 파일 이름 확장자까지 써주면 접근가능
//정적파일 이름 확장자까지 접근가능
app.use(express.json()) //들어온 데이터 처림 json요청 들어오면 ->json으로 그대로 담아줌 (자동으로 제이슨파싱)
app.use(express.urlencoded({extended : false}))
//app.use(cookieParser()): 쿠기 설정하는 옵션
app.use(session({
  resave : false,
  saveUninitialized : false,
  secret : process.env.COOKIE_SECRET,
  cookie:{
    httOnly:true,
    secure:false,
  },
  name : 'session-cookie'
}))

//앱가지고 set 매소드 실행
app.set('port', 3000)



app.get('/',(req,res)=>{
  res.send('Hello, express')
  //throw new Error('error')
  res.sendFile(path.join(__dirname,'/index.html'))
})//get주소로 요청을 처리하겠따
app.use((err,req,res,next)=>{
  console.error(err);
  res.statu(500).send(err.message)
})


const port = app.get('port')//포트를 불러온다.
app.listen(port,()=>{
console.log(port,'번 포트에서 서버 실행중 !');
})

 

[미들웨어 종류]

- body-parser 

 : 요청 받은것 파라미터 값을 해석해서 req,body 객체로 만들어주는 미들웨에

   보통 폼 데이터나 AJAX 요청의 데이터를 처리함. 하지만 이미지 영상 파일 데이터는 처리 못함 -> 뮬터 모듈 써야함

   익스프레스에 내장되어있음

   { name : 'sm' , book : 'abc' } 이렇게 생긴 json를 req.body에 넣어줄수 있는 거!

 

-cookie-parser

 : 요청에 동봉된 쿠키를 해석해 req,cookies 객체로 만든다. 쿠키 생성 관리

 

-express-session

 : 세션 관리용 미들웨어. 로그인 등의 이유로 세션을 구현하거나 특정 사용자를 위한 데이터를 임시적으로 저장해둘 때 유용 ! ///로그인 -> 쿠키 express session미들웨어를 통해 암호화 된것 

 

*req.data를 통해 현재 요청이 처리되는 동안 미들웨어 간에 데이터를 공유할 수 있다

 

- multer

: 이미지 동영상 등 .. 여러가지 파일들을 멀티파트 형식으로 업로드할 때 사용하는 미들웨어

ebctype -> multipart/form-data인 폼을 통해 업로드하는 데이터의 형식을 의미함.

//multilpart.html
<form action="/upload" method="post" enctype="multipart/form-data">
	<input type="file" name="image" />
    <input type="text" name="title" />
    <button type="submit">업로드</button>
</form>
const multer = require('multer')

const upload = multer({
	storage: multer.diskStorage({
    	destination(req, file, done) {
        	done(null, 'uploads/')
        },
        filename(req, file, done) {
        	const ext = path.extname(file.originalname)
            done(null, path.basename(file.originalname, ext) + Date.now() + ext)
        },
     }),
     limits: { fileSize: 5* 1024* 1024}
})

설정이 끝나면 

//upload 변수가 생긴다
app.post('/upload', upload.single(image), (req,res) => {
	console.log(req.file, req.body);
    res.send('ok');
})

//req.file
//{ fieldname: 'img', originalname: 'dd.png' ... size: 5337}

여러개의 파일 multiple , array

...

 

- router

: 주소별로 분리 처리하는 메서드 라우터 ***

//routes
const express = require('express');
const homeRouter = require('./home');
const reviewRouter = require('./review');
const regiRouter = require('./regi');

const router = express.Router();

/* GET home page. */
router.get('/', (req, res, next) => {
  res.render('index', { title: 'Express' });
});

  res.send('log test');
});

// RESTFull API
router.use('/home', homeRouter);
router.use('/review', reviewRouter);
router.use('/regi', regiRouter);

module.exports = router;
//app.js
const createError = require('http-errors');
const express = require('express');
const path = require('path');
const cookieParser = require('cookie-parser');
const dotenv = require('dotenv');
const cors = require('cors');
const corsConfig = require('./config/corsConfig.json');
const models = require('./models');
const logger = require('./lib/logger');
const bodyParser = require('body-parser');
const indexRouter = require('./routes/index');//****이 부분으로 라우터 연결

dotenv.config();

const NODE_ENV = process.env.NODE_ENV;


const app = express();

logger.info('app start');

// view engine setup
// views -> 사용하는 템플릿 엔진 이 있는 디렉토리 설정 
app.set('views', path.join(__dirname, 'views'));
// 뷰 엔진 설정 - express에서 사용할 템플릿 엔진을 설정합니다. ejs로 생성했기 때문에 ejs 지정
app.set('view engine', 'ejs');

app.use(cors(corsConfig)); // 해당 파일에 적힌 내용에 대해 교차통신 허용
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, 'public')));
app.use(cookieParser());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

// 라우터 연결*****************
app.use('/', indexRouter);


// catch 404 and forward to error handler
app.use(function (req, res, next) {
  next(createError(404));
});

// error handler
app.use(function (err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

// DB 연결 확인
models.sequelize.authenticate().then(() => {
  logger.info('DB connection success')

    // sequelize sync (다 지우고 싹 다시 table 생성)
    // models.sequelize.sync({force:true}).then(() => {
    // sequelize sync (table 생성)
    models.sequelize.sync().then(() => {
      logger.info('Sequelize sync success');
    }).catch((err) => {
      logger.error('Sequelize sync error', err);
    });
  }).catch((err) => {
    logger.error('DB Connection fail', err);
});

module.exports = app;

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함