TIL - express & middlewares

kyoungyeon·2022년 11월 13일
0

TIL

목록 보기
59/122

STATUS

제 인생에도 만점이 있을까요..? 이거 재시야..잊지마

아무튼 시작한 시험! 시간제한은 없지만
어제밤 부터 계속 붙잡고 있는 미들웨어!
오늘도,, 알바 끝나고 저녁 부터 다시 시작함.

//routes/user.js
const { Router } = require('express');

const router = Router();

const users = ['철수', '영희', '지은'];

router.get('/', (req, res, next) => {
  res.json(users);
});

router.get('/:name', (req, res, next) => {
  const { name } = req.params;

  res.json({
    id: users.indexOf(name),
    name,
  });
});
router.get('/users', (req, res, next) => {
  const { passWords } = req.query;
  res.json({
    id: users.indexOf(passWords),
    passWords,
  });
});

module.exports = router;
//index.js
// 지시사항을 참고하여 코드를 작성하세요.
const express = require('express');

const notesRouter = require('./routes/notes');
const usersRouter = require('./routes/users');
const logger = require('./middlewares/request-logger');
// const error500 = require('./middlewares/error-handler');
const error404 = require('./middlewares/not-found');
const errHandler = require('./middlewares/error-handler');

const app = express();

app.get('/', (err, req, res) => {
  throw new Error('Error!');
});

app.use('/notes', notesRouter);
app.use('/users', usersRouter);

app.use(logger);
app.use(error404);
app.use(errHandler);

app.listen(8080, () => {
  console.log('SERVER STARTED');
});

middlewares

//middlewares/require-logger.js
// 지시사항을 참고하여 코드를 작성하세요.

const logger = (req, res, next) => {
  console.log(req.method, req.path);
  next();
};

module.exports = logger;


//middlewares/password-required.js
// 지시사항을 참고하여 코드를 작성하세요.
const passwords = (req, res, next) => {
  let pwd = req.query;
  if (pwd.length === 0) {
    next(new Error('NotAuthorized');) 
    return;
  } 
  if(pwd === '12345678') {
    const passwd =req.get('password')
  }
  next();
};

module.exports = passwords;

//middlewares/error-handler.js
// 지시사항을 참고하여 코드를 작성하세요.
//오류 처리 미들웨어

const errHandler = (err, req, res, next) => {
  res.status(500).send({ error: err.message });
  next(err);
};

module.exports = errHandler;

//middlewares/not-found.js
// 지시사항을 참고하여 코드를 작성하세요.

//정의되지 않은 경로 미들웨어
const error404 = (req, res, next) => {
  res.status(404).send({ error: 'PageNotFound' });
  next(err);
};
module.exports = error404;

data

//notes.json
[
  { "title": "안녕하세요.", "content": "안녕히가세요." },
  { "title": "반갑습니다.", "content": "좋은 아침입니다." },
  { "title": "노트에요", "content": "읽을 수 있습니다." },
  { "title": "아무래도", "content": "좋습니다." }
]

지시사항

지시사항
모든 요청에 대해 method와 path를 기록하는 requestLogger 미들웨어를 작성하고 적용합니다.

미들웨어는 ./middlewares/request-logger.js 파일에 작성합니다.
요청을 기록하는 코드는 다음과 같습니다.
console.log(req.method, req.path);
Copy
/users 경로에 비밀번호를 확인하는 미들웨어를 작성하고 적용합니다.

미들웨어는 ./middlewares/password-required.js 파일에 작성합니다.
비밀번호는 쿼리로 전달됩니다.
비밀번호는 ‘12345678’ 입니다.
비밀번호가 없는경우 오류처리 미들웨어로 오류를 전달합니다.
전달되어야 하는 오류는 new Error('NotAuthorized') 입니다.
오류처리 미들웨어를 작성하고 적용합니다.

미들웨어는 ./middlewares/error-handler.js 파일에 작성합니다.
응답은 json으로 보냅니다.
응답 http status는 500입니다.
오류에 해당하는 응답은 다음과 같습니다.
{ error: err.message }
정의되지 않은 경로를 처리하는 미들웨어를 작성하고 적용합니다.

미들웨어는 ./middlewares/not-found.js 파일에 작성합니다.
응답은 json으로 보냅니다.
응답 http status는 404입니다.
응답은 다음과 같습니다.
{ error: 'PageNotFound' }

총점

  • status
  • router를 써야할지 , app 을 써야할지 ,
    • app 은 최상이 부모 폴더에서 해야하는게 원칙상 맞는데 미들웨어를 관심사 분리를 해서 파일 디렉토리 구조상 계속 헷갈림
    • module.exports 하면서 로직은 공식문서대로 짜놓긴 왜 오류 미들웨어는 통과가 안되는건지?
app.use('/경로이름', 라우터객체)
app.use(미들우에ㅓ1,미들웨어2);

//logger은 기록

// path params : user /:id ex) user/1
	:id를 경로로 취급한다
route handler > function(get,post.put,delete) 등에 적용된 미들웨어인데, path parameter를 사용할수 있다.
 const logger= (req,res,next) =>{
	console.log('request ${req.path}`};
	next(); //여기서 next가 다음 미들웨어 호출하는것임!
    
    // 다음 미들웨어
const auth = (req,res,next)=>{
	if (!isAdmin(req)){
	next(new Error('not authorized')); 
	return;	
	}
	next(); 
      }
      
 app.use(()=>{
	if(! (req)})
오류처리 미들웨어 (3)
app.use((err,req,res,rnext)=>{
 res.sned('Error occured!')
	})

// 오류처리 미들웨어 설정 예시
next( new Error(`member not ${memberType}`));

  • STATUS
    • 아니 근데 왜 안되냐고
    • 유저/:name 비밀번호는 아까 되다가 왜 또 안되는데

try 1

//index.js
const express = require('express');

const notesRouter = require('./routes/notes');
const usersRouter = require('./routes/users');
const logger = require('./middlewares/request-logger');
const passwords = require('./middlewares/password-required');
const error404 = require('./middlewares/not-found');
const errHandler = require('./middlewares/error-handler');

const app = express();

app.use('/notes', notesRouter);
app.use('/users', passwords, usersRouter);

app.use((err, req, res, next) => {
  throw new Error('Error!');
});
//password-requires.js
// 지시사항을 참고하여 코드를 작성하세요.
const passwords = (req, res, next) => {
  const { password } = req.query;
  //const pwd = req.get('password');
  if (password !== '12345678' || password.length < 1) {
    next(new Error('NotAuthorized'));
    return;
  }
  next();
};

module.exports = passwords;

//error-handelr.js
// 지시사항을 참고하여 코드를 작성하세요.
//오류 처리 미들웨어

const errHandler = (err, req, res, next) => {
  if (res.headersSent) {
    return next();
  }
  res.status(500).send({ error: err.message });
  //next();
};

module.exports = errHandler;

//routes/user.js

router.get('/users', (req, res, next) => {
  const { passwords } = req.query;
  res.json({
    passwords: users.indexOf(passwords),
    // passwords,
  });
});

err1

응답의 기록을 시작한 후에 오류가 있는 next()를 호출하는 경우(예: 응답을 클라이언트로 스트리밍하는 중에 오류가 발생하는 경우)

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
    at new NodeError (node:internal/errors:371:5)
    at ServerResponse.setHeader (node:_http_outgoing:576:11)
    at ServerResponse.header (/elice/node_modules/express/lib/response.js:767:10)
    at ServerResponse.send (/elice/node_modules/express/lib/response.js:170:12)
    at ServerResponse.json (/elice/node_modules/express/lib/response.js:267:15)
    at ServerResponse.send (/elice/node_modules/express/lib/response.js:158:21)
    at errHandler (/elice/project_file/middlewares/error-handler.js:8:19)
    at Layer.handle_error (/elice/node_modules/express/lib/router/layer.js:71:5)
    at trim_prefix (/elice/node_modules/express/lib/router/index.js:315:13)
    at /elice/node_modules/express/lib/router/index.js:284:7
GET /
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
    at new NodeError (node:internal/errors:371:5)
    at ServerResponse.setHeader (node:_http_outgoing:576:11)
    at ServerResponse.header (/elice/node_modules/express/lib/response.js:767:10)
    at ServerResponse.send (/elice/node_modules/express/lib/response.js:170:12)
    at ServerResponse.json (/elice/node_modules/express/lib/response.js:267:15)
    at ServerResponse.send (/elice/node_modules/express/lib/response.js:158:21)
    at errHandler (/elice/project_file/middlewares/error-handler.js:8:19)
    at Layer.handle_error (/elice/node_modules/express/lib/router/layer.js:71:5)
    at trim_prefix (/elice/node_modules/express/lib/router/index.js:315:13)
    at /elice/node_modules/express/lib/router/index.js:284:7

solv

express공식

  • 아래 함수 추가 하고
  • next는 한번만, 마지막에 선언할 것
function errorHandler(err, req, res, next) {
  if (res.headersSent) { //위 내용을  추가하면 됌.
    return next(err);	 // err 변수를 인식을 잘 못함 다음 미들웨어로 전달되게 그냥 삭제함
  }
  res.status(500);
  res.render('error', { error: err });
}
  • 결과는?

...😇

try 2

  • STATUS
    • 왜! 안될까! 생각해 보기로 함
    • 아무리 생각해도 오류처리 미들웨어 자체는 어찌 만든거 같은데
    • 뭔가 제대로 app 에서 못받고 있나..?
  • express_오류처리 미들웨어
//app.js
app.all('*', (req, res, next) => {
  throw new errHandler('Error!');
})
  • 결과는?

  • 와! 신난다 인식된다!

try3

  • STATUS
    • 아까 앱에서 코드를 변경해 본 것처럼 오류처리 로직자체는 잘 되는것 같다
    • 일반적인 오류 처리 미들웨어는 부모 컴포넌트인 index.js에서 app.get 해서 바로 해버리는데
    • error-hadnler.js 에서 > index.js로 전달받으려다보니
    • app. use 를 써야하는지, get을 써야하는지, all을 써야하는 지 모르겠음
//모든 오류를 처리하는(catch-all)” errorHandler 함수는 다음과 같이 구현될 수 있습니다.


function errorHandler(err, req, res, next) {
  res.status(500);
  res.render('error', { error: err });
};
  • render은 잘 모르기도 하고, 다른 오류처리 미들웨어 기능과 충돌나는 것 같아 패스.
    • 시험에선 모듈 export해서 써야하는 상황
    • index.js 에서 코드 하나하나 바꿔가며 시도한 결과 해결.

solv

app.all('/', (err, req, res, next) => {
  throw new errHandler();
});

// 2 방법 이것도 가능
//app.all('*', (err, req, res, next) => {
//  throw new errHandler();
// });

// 3 all 대신 get 써도 가능

 
app.use(logger);
app.use(error404);
app.use(errHandler);
app.listen(8080, () => {
  console.log('SERVER STARTED');
});

vs

app.all('*'....)
  • Problem:
    • 왜 작동하는지/ 작동 안되는지 모르겠다.
    • 지금은 어느 정도 이유가 짐작 됨.
    • app.use/ get 차이점
      Difference between app.use and app.get in express.js
      app.get vs use 차이점
    • app. get(path,) : 라우팅 , 정확한 req, 제공되어진 url(path) 에서만 app.get을 쓴다. app.get을 쓰면 app.use에 대한 호출이 되므로 서로 연관있음. 다만 get 호출에만 응답하므로 주의
    • app. use() : prefix of request라고 해서 호출 받아들이는 범위가 큼
      • / == /about == /usr/123 다 받아들인다고 함.
      • 특히 handler 미들웨어를 추가하고 싶을때! , 라우터 모듈러 쓰고 싶을때! 쓴다
    • app. all () : app.use 와 유사함 , 모든 http request에 쓸 수 있음. 주로 라우터 핸들링할때 추천된다!
app.use( "/book" , middleware);
// will match /book
// will match /book/author
// will match /book/subject

app.all( "/book" , handler);
// will match /book
// won't match /book/author   
// won't match /book/subject    

app.all( "/book/*" , handler);
// won't match /book        
// will match /book/author
// will match /book/subject

👏👏👏

nodesBestprc

app기타외 메소드

profile
🏠TECH & GOSSIP

0개의 댓글