SlideShare a Scribd company logo
Startup JavaScript
8. NPM & Express.JS
THINKER TO MAKER
x
Node 모듈 관리
THINKER TO MAKER
Node Package Manager
NPM
Node.JS 에서 사용 가능한 모듈들을 패키지 화 하여 모아 놓은 것
일일이 개발하지 않고 누군가 만들어 올린 모듈을 다운로드 받아 사용
NPM 사용법
NPM 을 이용하여 Express 모듈을 설치 해 줌
샘플 및 연동 패키지의 쉬운 설치를 위해 express-generator 도 설치 필요
기능 명령 예제
기본 도움말 $ npm help $ npm ?
상세 도움말 (명령어) $ npm -l $ npm -l
명령 별 도움말 $ npm [명령어] -h $ npm install -h
설치 목록 보기 $ npm list $ npm ls
설치 로컬 $ npm install [모듈명] $ npm install crypto
로컬 (운영 정보 저장) $ npm install [모듈명] --save $ npm install crypto --save
글로벌 $ npm install [모듈명] -g $ npm install crypto –g
글로벌 (운영 정보 저장) $ npm install [모듈명] -g --save $ npm install crypto –g --save
업데이트 로컬 업데이트 $ npm update [모듈명] $ npm update crypto
글로벌 업데이트 $ npm update [모듈명] -g $ npm update crypto –g
삭제 로컬 삭제 $ npm uninstall [모듈명] $ npm uninstall crypto
글로벌 삭제 $ npm update [모듈명] –g $ npm update crypto –g
모듈 로딩 구조
모듈 호출 시 기본적으로 자기 자신의 디렉토리를 탐색
자기 자신의 디렉토리가 없는 경우, 부모 -> 환경변수 지정 디렉토리 탐색
프로그램 파일과 같은
디렉토리에서 검색 시작
노드 기본
모듈 인가?
모듈 반환
현재 디렉토리의 node_modules
디렉토리에 모듈이 있는가?
부모 디렉토리로 이동 시도
부모 디렉토리가
있는가?
모듈이 NODE_MODULES 환경
변수에 명시된 디렉토리에 있는가?
예외 발생
Y
Y
N
N
N
N
Y
Y
사용자 정의 모듈 생성/사용
단일 사용자 모듈을 정의하여 사용할 때는 module.exports 를 이용 하나,
모듈 내에 여러 함수와 기능을 포함할 때는 exports 를 이용 하여 생성
var module = require('./module1');
module();
// module1.js
module.exports = function(){
var msg = 'Hello World';
console.log(msg);
}
var module = require('./module2');
console.log(module.msg);
console.log(module.sum(2,4));
console.log(module.avg(2,4));
// module2.js
exports.sum = function(a, b){
return a+b;
}
exports.avg = function(a, b){
return (a + b) / 2;
}
exports.msg = 'Hello Module!';
module.exports 를 이용한 모듈 생성/사용 형태
exports 를 이용한 모듈 생성/사용 형태
Express.JS
THINKER TO MAKER
Web App Framework
Express.JS
Node.JS 를 위한 가장 인기 있는 웹 어플리케이션 프레임워크
웹 페이지를 위한 서버 및 웹 기반 어플리케이션 개발에 쓰임
웹,모바일 어플리케이션을 위한 견고한 구성
Web Application
쉽고 빠른 API 구성을 위한 HTTP 기능 및 미들웨어
유용한 API
기본 웹 기능을 위한 최소화된 레이어 제��
Performance
인기있는 많은 프레임워크가 Express 기반 임
관련 Framework
Express 설치
NPM 을 이용하여 Express 모듈을 설치 해 줌
샘플 및 연동 패키지의 쉬운 설치를 위해 express-generator 도 설치 필요
$ npm install express
Express 설치
$ npm install –g express-generator
Express-Generator 설치 및 샘플 생성
$ express myApp
$ cd myApp
프로젝트 이동 및 연계 패키지 설치
myApp$ npm install
myApp$ npm start
샘플 프로젝트 구동
Hello Server with Express.JS
// express 호출
var express = require('express');
// 서버 생성
var app = express();
app.set('port', process.env.PORT || 3000);
// 접속 처리
app.get('/', function(req, res){
res.type('text/plain');
res.send('Hello World!!!');
});
// 서버 구동
app.listen(app.get('port'), function(){
console.log('Server Started!');
});
HTTP 모듈을 대체하여, Express.JS 로 간단한 웹 서버 구축 가능
서버 구동 후 127.0.0.1:3000 주소를 입력하여 결과 확인
Express.JS with HTML/CSS/JS
// express 호출
var express = require('express');
var path = require('path');
// 서버 생성
var app = express();
app.set('port', process.env.PORT || 3000);
// 리소스 접근 경로 설정
app.use(express.static(path.join(__dirname,
'/public')));
// 접속 처리
app.get('/', function(req, res){
res.sendFile(__dirname +
'/index.html');
});
// 서버 구동
app.listen(app.get('port'), function(){
console.log('Server Started!');
});
sendfile 을 이용하여, 웹 페이지가 보여지도록 설정 가능
HTML, JS, CSS 등의 리소스에 접근이 가능하도록 public 설정 추가
<html>
<head>
<title>Hello World!</title>
<link rel='stylesheet' href='index.css'>
<script src='index.js'></script>
</head>
<body>
Hello Express.JS!
</body>
</html>
body { background-color : yellow; }
window.onload = function(){
alert('Hello Express.JS!');
}
Index.html
Index.css
Index.js
server.js
미들웨어
THINKER TO MAKER
middleware
미들웨어
일반적으로 next 라는 변수의 함수로 표시되며, 요청(req), 응답(res) 을 처리.
또한 요청/응답 주기에서 다음 미들웨어에 대한 접근 권한을 가짐
미들웨어 함수가 적용되는 HTTP메소드
미들웨어가 적용되는 경로(라우트)
미들웨어 함수
미들웨어 함수의 콜백 인수(일반적으로 next라 사용)
HTTP 응답 인수 (일반적으로 response의 res라 사용)
HTTP 요청 인수(일반적으로 reques의 req라 사용)
모든 코드를 실행
미들웨어 함수의 기능
요청 및 응답 객체에 대한 변경
요청-응답 주기 종료 스택 내의 다음 미들웨어 호출
3rd party 미들웨어
JSON처리 및 압축, 쿠키 등 웹 서버 운용에 필요한 다양한 모듈을 3rd party
형태로 제공함. 필요한 모듈을 설치하여 사용 가능.
주요 미들웨어 설명
body-parser POST 전달 데이터의 JSON 화 처리
compression 응답 값을 압축하여 전송
connect-timeout 타임아웃 처리
cookie-parser 쿠키 사용을 위한 미들웨어
cookie-session 쿠키 세션 처리를 위한 미들웨어
errorhandler 오류 처리용 미들웨어
express-session 서버의 세션 처리용 미들웨어
method-override 파일을 옥텟 스트림의 형태로 전송
morgan 로그 기록 용 미들웨어
passport 인증을 위한 express 미들웨어 모듈
serve-favicon 파비콘 표시용 미들웨어
multer multipart/form-data 처리용 (파일 업로드) 미들웨어
사용자 정의 미들웨어
일반적으로 제공되는 third-party 미들웨어를 사용 함
필요 시, 사용자가 직접 미들웨어를 작성하여 사용할 수 있음
var express = require('express');
var app = express();
app.set('port', process.env.PORT || 3000);
var getTime = function(req, res, next){
req.currentTime = Date.now();
next(); // 다음 미들웨어 실행 - 반드시 있어야 함
}
var logger = function(req, res, next){
console.log(req.currentTime, 'Requested!');
next();
}
// 사용자 미들웨어 등록, 이 순서대로 사전 수행 됨
app.use(getTime);
app.use(logger);
app.get('/', function(req, res){
res.send('Hello World!');
});
app.listen(app.get('port'), function(){
console.log('Server Started!');
});
var express = require('express');
var app = express();
app.set('port', process.env.PORT || 3000);
app.get('/', function(req, res){
res.send('Hello World!');
});
// 사용자 정의 404 페이지
// 이 경우는 app 관련 미들웨어 선언이 종료 된 후.
// 마지막에 위치 함
app.use(function(req, res, next){
res.type('text/plain');
res.status(404);
res.send('404 - Not Found');
});
app.listen(app.get('port'), function(){
console.log('Server Started!');
});
오류 처리 미들웨어
일반 미들웨어와 달리 인자 값을 4개로 지정(err, req, res, next)하여 작성.
다른 app.use()및 라우트 호출을 정의 한 후 마지막에 선언 되어야 함.
//...
// 상황에 따라 에러 처리를 세분화 할 수 있음
app.use(logError);
app.use(clientError);
app.use(errorHandler);
function logError(err, req, res, next){
console.error(err.stack);
next(err);
}
// 명시적으로 특수한 경우 오류 처리
function clientError(err, req, res, next){
if(req.xhr){
res.status(500).send({ error : 'Specific Error!'});
} else {
next(err);
}
}
// 모든 오류를 처리 (catch-all)
function errorHandler(err, req, res, next){
res.status(500);
res.send({ error : err.message });
}
//..
var express = require('express');
var app = express();
app.set('port', process.env.PORT || 3000);
app.get('/', function(req, res){
res.send('Hello World!');
});
app.get('/error', function(req, res, next){
var err = new Error('Error!');
err.status = 404;
//err.message = 'Error Occured!';
//console.log('here1');
next(err);
});
// 모든 호출 마지막에 선언해야 함
app.use(function(err, req, res, next){
console.error(Date.now());
console.error(err.stack);
res.status(err.status);
res.send(err.message);
});
app.listen(app.get('port'), function(){
console.log('Server Started!');
});
라우터
THINKER TO MAKER
GET, POST, PUT, DELETE
라우팅
애플리케이션이 접근할 End-Point 정의(URI) 및 응답 방식을 뜻함
하나 이상의 핸들러 함수를 가지며, 라우트가 일치 할 때 실행 됨
App 은 express 의 인스턴스 임
app.METHOD(PATH, HANDLER)
METHOD 는 HTTP 요청 메소드
PATH 는 서버의 실행 경로
HANDLER 는 라우트 일치 시 실행되는 함수
메소드 설명
GET 읽기(Read) 용도로 활용
POST 생성(Create) 용도로 활용
PUT 수정(Update) 용도로 활용
DEL 삭제(Delete) 용도로 활용
HTTP REQUEST
Middleware / app.use(‘…’)
cookieParser, bodyParser
Logger, authentication
Route Handler / app.get(‘…’)
req.params, req.query, req,body …
render, sendFile
HTTP RESPONSE
/test/123/getEdit…
Render HTML page
기본 라우팅 (1/2)
CRUD 와 메소드를 1:1로 매핑하여 많이 사용 (RESTful API)
App 객체에 get, post, put, delete 를 지정하여 간단하게 사용 가능
// 데이터 가져��기
app.get('/data', function(req, res){
console.log(data);
res.json({ result : true, data : data });
});
// 데이터 생성하기
app.post('/data', function(req, res){
data.push(req.body.data);
res.json({ result : true });
});
// 데이터 수정하기
app.put('/data', function(req, res){
data[data.length - 1] = req.body.data;
res.json({ result : true });
});
// 데이터 삭제하기
app.delete('/data', function(req, res){
data.shift();
res.json({ result : true });
});
// 서버 구동
app.listen(app.get('port'), function(){
console.log('Server Started!');
});
// server2.js
// express 호출
var express = require('express');
var path = require('path');
var bodyParser = require('body-parser');
var app = express();
app.set('port', process.env.PORT || 3000);
app.use(express.static(path.join(__dirname,
'/public')));
// http 요청 body 를 json 데이터 화 함
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
var data = ['Test1'];
// 접속 처리
app.get('/', function(req, res){
res.sendFile(__dirname + '/index2.html');
});
// 공통 처리 부분
app.all('/data', function(req, res, next){
console.log('Check Input');
console.log(req.body);
next();
});
기본 라우팅 (2/2)
Client 에서 post 와 get 의 경우 jQuery 에서 간략화 된 함수 제공.
Delete 와 Put 의 경우는 ajax 함수를 이용하여 구현해야 함
$('#post').click(function(){
var data = Math.round((Math.random() * (10-1)) + 1);
$.post('/data',{ data : data }, function(data){
alert('Post completed!');
});
});
$('#put').click(function(){
var data = Math.round((Math.random() * (10-1)) + 1);
$.ajax({
type : 'put',
url : '/data',
data : { data : data },
success : function(data){
alert('Updated!');
}
});
});
$('#delete').click(function(){
$.ajax({
type : 'delete',
url : '/data',
success : function(data){
alert('Deleted!');
}
});
});
});
<!– index2.html -->
<html>
<head>
<title>Hello World!</title>
<script src='https://code.jquery.com/jquery-
3.1.1.min.js'></script>
<script src='index2.js'></script>
</head>
<body>
<button id='get'>GET</button>
<button id='post'>POST</button>
<button id='put'>PUT</button>
<button id='delete'>DELETE</button>
<p id='text'></p>
</body>
</html>
// index2.js
$(function(){
$('#get').click(function(){
$.get('/data', function(data){
$('#text').text(JSON.stringify(data.data));
});
});
요청 변수
요청 변수는 req 객체에 담고 있어, 필요한 데이터를 가져올 수 있음
Body 부분의 데이터를 가지고 오기 위해선 body-parser 미들웨어가 필수임
메소드 설명
req.params 이름 붙은 라우트 매개 변수 값을 담고 있는 배열
req.query GET 매개변수(QueryString) 값을 담고 있는 객체
req.body POST 매개변수 값을 담고 있는 객체
req.route 현재 일치하는 라우트 정보
req.ip 클라이언트의 IP 주소
req.path Protocol, Host, Port, Querystring을 제외한 요청 경로
req.host 클라이언트의 호스트 이름
req.url Protocol, Host, Port, Querystring과 요청 경로
응답 메소드
응답 객체에 대한 메소드(res)는 클라이언트에 응답을 전송 및 요청 가능
라우터 핸들러 후 반드시 호출되어야 함 (없으면, 정지 상태로 대기)
메소드 설명
res.download() 파일이 다운로드되도록 처리 함
res.end() 응답 프로세스를 종료
res.json() JSON 응답을 전송
res.jsonp() JSONP 지원을 통해 JSON 응답을 전송
res.redirect() 요청의 경로를 재 지정
res.render() 뷰 템플릿을 렌더링
res.send() 다양한 유형의 응답을 전송
res.sendFile() 파일을 옥텟 스트림의 형태로 전송
res.sendStatus() 응답 코드를 설정 후 문자열로 표현한 응답 본문을 전송
라우팅 응용 1
app.route() 를 이용하면 동일한 경로에 대하여 체인 형으로 사용 가능
모듈 식으로 구성되어 중복과 오타를 줄일 수 있음
// 데이터 가져오기
app.route('/data')
.get('/data', function(req, res){
console.log(data);
res.json({ result : true, data : data });
})
.post('/data', function(req, res){
data.push(req.body.data);
res.json({ result : true });
})
.put('/data', function(req, res){
data[data.length - 1] = req.body.data;
res.json({ result : true });
})
.delete('/data', function(req, res){
data.shift();
res.json({ result : true });
});
// server3.js
// express 호출
var express = require('express');
var path = require('path');
var bodyParser = require('body-parser');
var app = express();
app.set('port', process.env.PORT || 3000);
app.use(express.static(path.join(__dirname,
'/public')));
// http 요청 body 를 json 데이터 화 함 - middleware
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
var data = ['Test1'];
// 접속 처리
app.get('/', function(req, res){
res.sendFile(__dirname + '/index2.html');
});
// 서버 구동
app.listen(app.get('port'), function(){
console.log('Server Started!');
});
라우팅 응용 2
Path 형태의 값을 받아 상황에 맞게 처리할 수 있는 방법을 지원.
또한 정규 표현식으로 접속 경로 지정이 가능.
// server5.js – 정규 표현식 형태
// express 호출
var express = require('express');
var app = express();
app.set('port', process.env.PORT || 3000);
// 접속 처리
app.get('/', function(req, res){
res.send('Hello World2');
});
// 정규 표현식 형태로 사용
app.get(/abc/, function(req, res){
res.send('/abc/');
});
app.get(/.*fly$/, function(req, res){
res.send('/.*fly$/');
});
// 서버 구동
app.listen(app.get('port'), function(){
console.log('Server Started!');
});
// server4.js – Path
// express 호출
var express = require('express');
var app = express();
app.set('port', process.env.PORT || 3000);
// 접속 처리
app.get('/', function(req, res){
res.send('Hello World1');
});
// params 형태로 값 가져 오기
app.get('/test/:id', function(req, res){
res.send(req.params.id);
});
app.get('/test/:id/:project', function(req, res){
res.send(req.params.id + ' / ' +req.params.project);
});
// 서버 구동
app.listen(app.get('port'), function(){
console.log('Server Started!');
});
고급 라우팅
express.Router 를 이용하여 모듈식 라우팅 핸들러를 작성 할 수 있음
Router 는 라우팅 미들웨어 시스템으로, 미니 앱(mini app) 이라 불림
// route_data.js
var express = require('express');
var router = express.Router();
var data = ['Test1'];
router.get('/', function(req, res){
console.log(data);
res.json({ result : true, data : data });
});
router.post('/', function(req, res){
data.push(req.body.data);
res.json({ result : true });
});
router.put('/', function(req, res){
data[data.length - 1] = req.body.data;
res.json({ result : true });
});
router.delete('/', function(req, res){
data.shift();
res.json({ result : true });
});
// 외부 참조 모듈로 생성
module.exports = router;
// server4.js
var express = require('express');
var path = require('path');
var bodyParser = require('body-parser');
// 외부 라우트 설정 파일 사용
var route_data = require('./route_data');
var app = express();
app.set('port', process.env.PORT || 3000);
app.use(express.static(path.join(__dirname,
'/public')));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
// 특정 경로에 라우터 사용
app.use('/data', route_data);
// 접속 처리
app.get('/', function(req, res){
res.sendFile(__dirname + '/index2.html');
});
// 서버 구동
app.listen(app.get('port'), function(){
console.log('Server Started!');
});
W www.circul.us G group.circul.us
S social.circul.us C cafe.circul.us
CONTACT.US circulus@circul.us
THINKER TO MAKER
ANY
QUESTION?
x

More Related Content

Startup JavaScript 8 - NPM, Express.JS

  • 1. Startup JavaScript 8. NPM & Express.JS THINKER TO MAKER x
  • 2. Node 모듈 관리 THINKER TO MAKER Node Package Manager
  • 3. NPM Node.JS 에서 사용 가능한 모듈들을 패키지 화 하여 모아 놓은 것 일일이 개발하지 않고 누군가 만들어 올린 모듈을 다운로드 받아 사용
  • 4. NPM 사용법 NPM 을 이용하여 Express 모듈을 설치 해 줌 샘플 및 연동 패키지의 쉬운 설치를 위해 express-generator 도 설치 필요 기능 명령 예제 기본 도움말 $ npm help $ npm ? 상세 도움말 (명령어) $ npm -l $ npm -l 명령 별 도움말 $ npm [명령어] -h $ npm install -h 설치 목록 보기 $ npm list $ npm ls 설치 로컬 $ npm install [모듈명] $ npm install crypto 로컬 (운영 정보 저장) $ npm install [모듈명] --save $ npm install crypto --save 글로벌 $ npm install [모듈명] -g $ npm install crypto –g 글로벌 (운영 정보 저장) $ npm install [모듈명] -g --save $ npm install crypto –g --save 업데이트 로컬 업데이트 $ npm update [모듈명] $ npm update crypto 글로벌 업데이트 $ npm update [모듈명] -g $ npm update crypto –g 삭제 로컬 ���제 $ npm uninstall [모듈명] $ npm uninstall crypto 글로벌 삭제 $ npm update [모듈명] –g $ npm update crypto –g
  • 5. 모듈 로딩 구조 모듈 호출 시 기본적으로 자기 자신의 디렉토리를 탐색 자기 자신의 디렉토리가 없는 경우, 부모 -> 환경변수 지정 디렉토리 탐색 프로그램 파일과 같은 디렉토리에서 검색 시작 노드 기본 모듈 인가? 모듈 반환 현재 디렉토리의 node_modules 디렉토리에 모듈이 있는가? 부모 디렉토리로 이동 시도 부모 디렉토리가 있는가? 모듈이 NODE_MODULES 환경 변수에 명시된 디렉토리에 있는가? 예외 발생 Y Y N N N N Y Y
  • 6. 사용자 정의 모듈 생성/사용 단일 사용자 모듈을 정의하여 사용할 때는 module.exports 를 이용 하나, 모듈 내에 여러 함수와 기능을 포함할 때는 exports 를 이용 하여 생성 var module = require('./module1'); module(); // module1.js module.exports = function(){ var msg = 'Hello World'; console.log(msg); } var module = require('./module2'); console.log(module.msg); console.log(module.sum(2,4)); console.log(module.avg(2,4)); // module2.js exports.sum = function(a, b){ return a+b; } exports.avg = function(a, b){ return (a + b) / 2; } exports.msg = 'Hello Module!'; module.exports 를 이용한 모듈 생성/사용 형태 exports 를 이용한 모듈 생성/사용 형태
  • 8. Express.JS Node.JS 를 위한 가장 인기 있는 웹 어플리케이션 프레임워크 웹 페이지를 위한 서버 및 웹 기반 어플리케이션 개발에 쓰임 웹,모바일 어플리케이션을 위한 견고한 구성 Web Application 쉽고 빠른 API 구성을 위한 HTTP 기능 및 미들웨어 유용한 API 기본 웹 기능을 위한 최소화된 레이어 제공 Performance 인기있는 많은 프레임워크가 Express 기반 임 관련 Framework
  • 9. Express 설치 NPM 을 이용하여 Express 모듈을 설치 해 줌 샘플 및 연동 패키지의 쉬운 설치를 위해 express-generator 도 설치 필요 $ npm install express Express 설치 $ npm install –g express-generator Express-Generator 설치 및 샘플 생성 $ express myApp $ cd myApp 프로젝트 이동 및 연계 패키지 설치 myApp$ npm install myApp$ npm start 샘플 프로젝트 구동
  • 10. Hello Server with Express.JS // express 호출 var express = require('express'); // 서버 생성 var app = express(); app.set('port', process.env.PORT || 3000); // 접속 처리 app.get('/', function(req, res){ res.type('text/plain'); res.send('Hello World!!!'); }); // 서버 구동 app.listen(app.get('port'), function(){ console.log('Server Started!'); }); HTTP 모듈을 대체하여, Express.JS 로 간단한 웹 서버 구축 가능 서버 구동 후 127.0.0.1:3000 주소를 입력하여 결과 확인
  • 11. Express.JS with HTML/CSS/JS // express 호출 var express = require('express'); var path = require('path'); // 서버 생성 var app = express(); app.set('port', process.env.PORT || 3000); // 리소스 접근 경로 설정 app.use(express.static(path.join(__dirname, '/public'))); // 접속 처리 app.get('/', function(req, res){ res.sendFile(__dirname + '/index.html'); }); // 서버 구동 app.listen(app.get('port'), function(){ console.log('Server Started!'); }); sendfile 을 이용하여, 웹 페이지가 보여지도록 설정 가능 HTML, JS, CSS 등의 리소스에 접근이 가능하도록 public 설정 추가 <html> <head> <title>Hello World!</title> <link rel='stylesheet' href='index.css'> <script src='index.js'></script> </head> <body> Hello Express.JS! </body> </html> body { background-color : yellow; } window.onload = function(){ alert('Hello Express.JS!'); } Index.html Index.css Index.js server.js
  • 13. 미들웨어 일반적으로 next 라는 변수의 함수로 표시되며, 요청(req), 응답(res) 을 처리. 또한 요청/응답 주기에서 다음 미들웨어에 대한 접근 권한을 가짐 미들웨어 함수가 적용되는 HTTP메소드 미들웨어가 적용되는 경로(라우트) 미들웨어 함수 미들웨어 함수의 콜백 인수(일반적으로 next라 사용) HTTP 응답 인수 (일반적으로 response의 res라 사용) HTTP 요청 인수(일반적으로 reques의 req라 사용) 모든 코드를 실행 미들웨어 함수의 기능 요청 및 응답 객체에 대한 변경 요청-응답 주기 종료 스택 내의 다음 미들웨어 호출
  • 14. 3rd party 미들웨어 JSON처리 및 압축, 쿠키 등 웹 서버 운용에 필요한 다양한 모듈을 3rd party 형태로 제공함. 필요한 모듈을 설치하여 사용 가능. 주요 미들웨어 설명 body-parser POST 전달 데이터의 JSON 화 처리 compression 응답 값을 압축하여 전송 connect-timeout 타임아웃 처리 cookie-parser 쿠키 사용을 위한 미들웨어 cookie-session 쿠키 세션 처리를 위한 미들웨어 errorhandler 오류 처리용 미들웨어 express-session 서버의 세션 처리용 미들웨어 method-override 파일을 옥텟 스트림의 형태로 전송 morgan 로그 기록 용 미들웨어 passport 인증을 위한 express 미들웨어 모듈 serve-favicon 파비콘 표시용 미들웨어 multer multipart/form-data 처리용 (파일 업로드) 미들웨어
  • 15. 사용자 정의 미들웨어 일반적으로 제공되는 third-party 미들웨어를 사용 함 필요 시, 사용자가 직접 미들웨어를 작성하여 사용할 수 있음 var express = require('express'); var app = express(); app.set('port', process.env.PORT || 3000); var getTime = function(req, res, next){ req.currentTime = Date.now(); next(); // 다음 미들웨어 실행 - 반드시 있어야 함 } var logger = function(req, res, next){ console.log(req.currentTime, 'Requested!'); next(); } // 사용자 미들웨어 등록, 이 순서대로 사전 수행 됨 app.use(getTime); app.use(logger); app.get('/', function(req, res){ res.send('Hello World!'); }); app.listen(app.get('port'), function(){ console.log('Server Started!'); }); var express = require('express'); var app = express(); app.set('port', process.env.PORT || 3000); app.get('/', function(req, res){ res.send('Hello World!'); }); // 사용자 정의 404 페이지 // 이 경우는 app 관련 미들웨어 선언이 종료 된 후. // 마지막에 위치 함 app.use(function(req, res, next){ res.type('text/plain'); res.status(404); res.send('404 - Not Found'); }); app.listen(app.get('port'), function(){ console.log('Server Started!'); });
  • 16. 오류 처리 미들웨어 일반 미들웨어와 달리 인자 값을 4개로 지정(err, req, res, next)하여 작성. 다른 app.use()및 라우트 호출을 정의 한 후 마지막에 선언 되어야 함. //... // 상황에 따라 에러 처리를 세분화 할 수 있음 app.use(logError); app.use(clientError); app.use(errorHandler); function logError(err, req, res, next){ console.error(err.stack); next(err); } // 명시적으로 특수한 경우 오류 처리 function clientError(err, req, res, next){ if(req.xhr){ res.status(500).send({ error : 'Specific Error!'}); } else { next(err); } } // 모든 오류를 처리 (catch-all) function errorHandler(err, req, res, next){ res.status(500); res.send({ error : err.message }); } //.. var express = require('express'); var app = express(); app.set('port', process.env.PORT || 3000); app.get('/', function(req, res){ res.send('Hello World!'); }); app.get('/error', function(req, res, next){ var err = new Error('Error!'); err.status = 404; //err.message = 'Error Occured!'; //console.log('here1'); next(err); }); // 모든 호출 마지막에 선언해야 함 app.use(function(err, req, res, next){ console.error(Date.now()); console.error(err.stack); res.status(err.status); res.send(err.message); }); app.listen(app.get('port'), function(){ console.log('Server Started!'); });
  • 17. 라우터 THINKER TO MAKER GET, POST, PUT, DELETE
  • 18. 라우팅 애플리케이션이 접근할 End-Point 정의(URI) 및 응답 방식을 뜻함 하나 이상의 핸들러 함수를 가지며, 라우트가 일치 할 때 실행 됨 App 은 express 의 인스턴스 임 app.METHOD(PATH, HANDLER) METHOD 는 HTTP 요청 메소드 PATH 는 서버의 실행 경로 HANDLER 는 라우트 일치 시 실행되는 함수 메소드 설명 GET 읽기(Read) 용도로 활용 POST 생성(Create) 용도로 활용 PUT 수정(Update) 용도로 활용 DEL 삭제(Delete) 용도로 활용 HTTP REQUEST Middleware / app.use(‘…’) cookieParser, bodyParser Logger, authentication Route Handler / app.get(‘…’) req.params, req.query, req,body … render, sendFile HTTP RESPONSE /test/123/getEdit… Render HTML page
  • 19. 기본 라우팅 (1/2) CRUD 와 메소드를 1:1로 매핑하여 많이 사용 (RESTful API) App 객체에 get, post, put, delete 를 지정하여 간단하게 사용 가능 // 데이터 가져오기 app.get('/data', function(req, res){ console.log(data); res.json({ result : true, data : data }); }); // 데이터 생성하기 app.post('/data', function(req, res){ data.push(req.body.data); res.json({ result : true }); }); // 데이터 수정하기 app.put('/data', function(req, res){ data[data.length - 1] = req.body.data; res.json({ result : true }); }); // 데이터 삭제하기 app.delete('/data', function(req, res){ data.shift(); res.json({ result : true }); }); // 서버 구동 app.listen(app.get('port'), function(){ console.log('Server Started!'); }); // server2.js // express 호출 var express = require('express'); var path = require('path'); var bodyParser = require('body-parser'); var app = express(); app.set('port', process.env.PORT || 3000); app.use(express.static(path.join(__dirname, '/public'))); // http 요청 body 를 json 데이터 화 함 app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false })); var data = ['Test1']; // 접속 처리 app.get('/', function(req, res){ res.sendFile(__dirname + '/index2.html'); }); // 공통 처리 부분 app.all('/data', function(req, res, next){ console.log('Check Input'); console.log(req.body); next(); });
  • 20. 기본 라우팅 (2/2) Client 에서 post 와 get 의 경우 jQuery 에서 간략화 된 함수 제공. Delete 와 Put 의 경우는 ajax 함수를 이용하여 구현해야 함 $('#post').click(function(){ var data = Math.round((Math.random() * (10-1)) + 1); $.post('/data',{ data : data }, function(data){ alert('Post completed!'); }); }); $('#put').click(function(){ var data = Math.round((Math.random() * (10-1)) + 1); $.ajax({ type : 'put', url : '/data', data : { data : data }, success : function(data){ alert('Updated!'); } }); }); $('#delete').click(function(){ $.ajax({ type : 'delete', url : '/data', success : function(data){ alert('Deleted!'); } }); }); }); <!– index2.html --> <html> <head> <title>Hello World!</title> <script src='https://code.jquery.com/jquery- 3.1.1.min.js'></script> <script src='index2.js'></script> </head> <body> <button id='get'>GET</button> <button id='post'>POST</button> <button id='put'>PUT</button> <button id='delete'>DELETE</button> <p id='text'></p> </body> </html> // index2.js $(function(){ $('#get').click(function(){ $.get('/data', function(data){ $('#text').text(JSON.stringify(data.data)); }); });
  • 21. 요청 변수 요청 변수는 req 객체에 담고 있어, 필요한 데이터를 가져올 수 있음 Body 부분의 데이터를 가지고 오기 위해선 body-parser 미들웨어가 필수임 메소드 설명 req.params 이름 붙은 라우트 매개 변수 값을 담고 있는 배열 req.query GET 매개변수(QueryString) 값을 담고 있는 객체 req.body POST 매개변수 값을 담고 있는 객체 req.route 현재 일치하는 라우트 정보 req.ip 클라이언트의 IP 주소 req.path Protocol, Host, Port, Querystring을 제외한 요청 경로 req.host 클라이언트의 호스트 이름 req.url Protocol, Host, Port, Querystring과 요청 경로
  • 22. 응답 메소드 응답 객체에 대한 메소드(res)는 클라이언트에 응답을 전송 및 요청 가능 라우터 핸들러 후 반드시 호출되어야 함 (없으면, 정지 상태로 대기) 메소드 설명 res.download() 파일이 다운로드되도록 처리 함 res.end() 응답 프로세스를 종료 res.json() JSON 응답을 전송 res.jsonp() JSONP 지원을 통해 JSON 응답을 전송 res.redirect() 요청의 경로를 재 지정 res.render() 뷰 템플릿을 렌더링 res.send() 다양한 유형의 응답을 전송 res.sendFile() 파일을 옥텟 스트림의 형태로 전송 res.sendStatus() 응답 코드를 설정 후 문자열로 표현한 응답 본문을 전송
  • 23. 라우팅 응용 1 app.route() 를 이용하면 동일한 경로에 대하여 체인 형으로 사용 가능 모듈 식으로 구성되어 중복과 오타를 줄일 수 있음 // 데이터 가져오기 app.route('/data') .get('/data', function(req, res){ console.log(data); res.json({ result : true, data : data }); }) .post('/data', function(req, res){ data.push(req.body.data); res.json({ result : true }); }) .put('/data', function(req, res){ data[data.length - 1] = req.body.data; res.json({ result : true }); }) .delete('/data', function(req, res){ data.shift(); res.json({ result : true }); }); // server3.js // express 호출 var express = require('express'); var path = require('path'); var bodyParser = require('body-parser'); var app = express(); app.set('port', process.env.PORT || 3000); app.use(express.static(path.join(__dirname, '/public'))); // http 요청 body 를 json 데이터 화 함 - middleware app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false })); var data = ['Test1']; // 접속 처리 app.get('/', function(req, res){ res.sendFile(__dirname + '/index2.html'); }); // 서버 구동 app.listen(app.get('port'), function(){ console.log('Server Started!'); });
  • 24. 라우팅 응용 2 Path 형태의 값을 받아 상황에 맞게 처리할 수 있는 방법을 지원. 또한 정규 표현식으로 접속 경로 지정이 가능. // server5.js – 정규 표현식 형태 // express 호출 var express = require('express'); var app = express(); app.set('port', process.env.PORT || 3000); // 접속 처리 app.get('/', function(req, res){ res.send('Hello World2'); }); // 정규 표현식 형태로 사용 app.get(/abc/, function(req, res){ res.send('/abc/'); }); app.get(/.*fly$/, function(req, res){ res.send('/.*fly$/'); }); // 서버 구동 app.listen(app.get('port'), function(){ console.log('Server Started!'); }); // server4.js – Path // express 호출 var express = require('express'); var app = express(); app.set('port', process.env.PORT || 3000); // 접속 처리 app.get('/', function(req, res){ res.send('Hello World1'); }); // params 형태로 값 가져 오기 app.get('/test/:id', function(req, res){ res.send(req.params.id); }); app.get('/test/:id/:project', function(req, res){ res.send(req.params.id + ' / ' +req.params.project); }); // 서버 구동 app.listen(app.get('port'), function(){ console.log('Server Started!'); });
  • 25. 고급 라우팅 express.Router 를 이용하여 모듈식 라우팅 핸들러를 작성 할 수 있음 Router 는 라우팅 미들웨어 시스템으로, 미니 앱(mini app) 이라 불림 // route_data.js var express = require('express'); var router = express.Router(); var data = ['Test1']; router.get('/', function(req, res){ console.log(data); res.json({ result : true, data : data }); }); router.post('/', function(req, res){ data.push(req.body.data); res.json({ result : true }); }); router.put('/', function(req, res){ data[data.length - 1] = req.body.data; res.json({ result : true }); }); router.delete('/', function(req, res){ data.shift(); res.json({ result : true }); }); // 외부 참조 모듈로 생성 module.exports = router; // server4.js var express = require('express'); var path = require('path'); var bodyParser = require('body-parser'); // 외부 라우트 설정 파일 사용 var route_data = require('./route_data'); var app = express(); app.set('port', process.env.PORT || 3000); app.use(express.static(path.join(__dirname, '/public'))); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false })); // 특정 경로에 라우터 사용 app.use('/data', route_data); // 접속 처리 app.get('/', function(req, res){ res.sendFile(__dirname + '/index2.html'); }); // 서버 구동 app.listen(app.get('port'), function(){ console.log('Server Started!'); });
  • 26. W www.circul.us G group.circul.us S social.circul.us C cafe.circul.us CONTACT.US circulus@circul.us THINKER TO MAKER ANY QUESTION? x

Editor's Notes

  1. Circulus 팀 박종건입니다. 위 사진은 작년 창조경제박람회때 포스터 운반하던 파이보의 모습입니다. 파이보와 함께 펼쳐가는 미래를 이야기 하겠습니다.