nodejs express

24
Nodejs 프프프프프 6. 프프 프 프프프프프 프프프프프 프프프프프 프프프 프프프 프프프 프프프 프프프 ( [email protected] ) 1

Upload: hyosung-jeon

Post on 25-Dec-2014

1.980 views

Category:

Documents


8 download

DESCRIPTION

 

TRANSCRIPT

Page 1: Nodejs express

1

Nodejs 프로그래밍

6. 경량 웹 프레임워크 익스프레스

아키텍트를 꿈꾸는 사람들 오전반 스터디

전효성 ( [email protected] )

Page 2: Nodejs express

2

이번 발표에서 다룰 내용1. Express 프로젝트 셋팅2. app.js 소스 살펴보기3. Jade 뷰 템플릿 엔진4. 폼 전송 웹사이트 예제5. 데이터베이스 연동6. 비동기 패턴의 의존성 문제

Page 3: Nodejs express

3

1. Express 프로젝트 셋팅아래의 명령어를 순차적으로 입력합니다 .$ npm install express -g$ express simpleweb$ cd simpleweb$ npm install$ npm install express jade

Page 4: Nodejs express

4

Simpleweb 웹페이지 server-side 구성• node_modules

– 해당 웹프로젝트에서 사용하는 모듈들이 위치함 .

• Public– 정적 리소스 파일 저장 ( css, 이미지 등 )

• Route– url 에 따라 호출될 함수를 모아두는 디렉토리 .

• Views– 클라이언트에 보여줄 화면의 템플릿이 위치함 .

• App.js– main() 함수 개념

• Package.json– npm 으로 설치하면 여기에 설치된 모듈의 정보 ( 버전 ) 가 들어간다 .

Page 5: Nodejs express

5

2. app.js 소스 살펴보기// 모듈 종속성var express = require('express') , routes = require('./routes');

var app = module.exports = express.createServer();

// configurationapp.configure( function() { app.set('views', __dirname + '/views'); app.set('view engine', 'jade');

app.use(express.bodyParser()); app.use(express.methodOverride()); app.use(app.router); app.use(express.static(__dirname + '/public'));});

app.configure('development', function(){ app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));});

app.configure('production', function(){ app.use(express.errorHandler());});

Page 6: Nodejs express

6

2. app.js 소스 살펴보기// 모듈 종속성var express = require('express') , routes = require('./routes');

var app = module.exports = express.createServer();

// configurationapp.configure( function() { app.set('views', __dirname + '/views'); app.set('view engine', 'jade');

app.use(express.bodyParser()); app.use(express.methodOverride()); app.use(app.router); app.use(express.static(__dirname + '/public'));});

app.configure('development', function(){ app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));});

app.configure('production', function(){ app.use(express.errorHandler());});

현재 파일의 절대 경로

Page 7: Nodejs express

7

2. app.js 소스 살펴보기// 모듈 종속성var express = require('express') , routes = require('./routes');

var app = module.exports = express.createServer();

// configurationapp.configure( function() { app.set('views', __dirname + '/views'); app.set('view engine', 'jade');

app.use(express.bodyParser()); app.use(express.methodOverride()); app.use(app.router); app.use(express.static(__dirname + '/public'));});

app.configure('development', function(){ app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));});

app.configure('production', function(){ app.use(express.errorHandler());});

• View template 엔진과 view tempalte 위치 지정 • app.set() 특정 키에 값을 지정

Page 8: Nodejs express

8

2. app.js 소스 살펴보기// 모듈 종속성var express = require('express') , routes = require('./routes');

var app = module.exports = express.createServer();

// configurationapp.configure( function() { app.set('views', __dirname + '/views'); app.set('view engine', 'jade');

app.use(express.bodyParser()); app.use(express.methodOverride()); app.use(app.router); app.use(express.static(__dirname + '/public'));});

app.configure('development', function(){ app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));});

app.configure('production', function(){ app.use(express.errorHandler());});

• View template 엔진과 view tempalte 위치 지정 • app.set() 특정 키에 값을 지정

• app.use() 사용할 미들웨어 결정• express.static 리소스파일 위치 지정• express.bodyParser() application/x-www-

form-urlencoded 나 application/json 의 바디를 파싱하여 req.body 변수에 할당

Page 9: Nodejs express

9

2. app.js 소스 살펴보기// 모듈 종속성var express = require('express') , routes = require('./routes');

var app = module.exports = express.createServer();

// configurationapp.configure( function() { app.set('views', __dirname + '/views'); app.set('view engine', 'jade');

app.use(express.bodyParser()); app.use(express.methodOverride()); app.use(app.router); app.use(express.static(__dirname + '/public'));});

app.configure('development', function(){ app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));});

app.configure('production', function(){ app.use(express.errorHandler());});

• app.router 요청 url 을 라우팅한다 .

예 , http://localhost:3000/id에 따라 페이지를 다르게 구성하고 싶을 경우

Page 10: Nodejs express

10

2. app.js 소스 살펴보기// 모듈 종속성var express = require('express') , routes = require('./routes');

var app = module.exports = express.createServer();

// configurationapp.configure( function() { app.set('views', __dirname + '/views'); app.set('view engine', 'jade');

app.use(express.bodyParser()); app.use(express.methodOverride()); app.use(app.router); app.use(express.static(__dirname + '/public'));});

app.configure('development', function(){ app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));});

app.configure('production', function(){ app.use(express.errorHandler());});

• express.methodOverride()• <input> 태그의 method 를 오버라이드하여

브라우저에서 지원 못하는 PUT, DELETE 를 처리

HTTP 명령어 클라이언트의 의도GET 서버에서 정보를 얻어온다 .

POST 정보를 서버에 보낸다 .

PUT 기존에 존재하는 정보를 갱신한다 .

DELETE 특정 항목을 제거한다 ?!• 참고 : http://code.google.com/intl/ko-KR/apis/gdata/docs/2.0/basics.html

Page 11: Nodejs express

11

2. app.js 소스 살펴보기// 모듈 종속성var express = require('express') , routes = require('./routes');

var app = module.exports = express.createServer();

// configurationapp.configure( function() { app.set('views', __dirname + '/views'); app.set('view engine', 'jade');

app.use(express.bodyParser()); app.use(express.methodOverride()); app.use(app.router); app.use(express.static(__dirname + '/public'));});

app.configure('development', function(){ app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));});

app.configure('production', function(){ app.use(express.errorHandler());});

개발 중일때 stack trace 출력

실 서비스시 error 를 출력하지 않음

Page 12: Nodejs express

12

2. app.js 소스 살펴보기// Routes – HTTP 명령어 ( get, put, post, delete ) 에 대한 이벤트 핸들러 연결app.get('/', routes.index);

// 3000 번 포트 오픈app.listen(3000);

// 서버 콘솔에 메시지 출력console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env);

/* * GET home page. */

exports.index = function(req, res){ res.render('index', { title: 'Express' })};

simpleweb/route/index.js

Page 13: Nodejs express

13

3. Jade 뷰 템플릿 엔진

Page 14: Nodejs express

14채수원님 블로그 : http://blog.doortts.com/223

Page 15: Nodejs express

15

HTML Jade 도 가능합니다 .

http://html2jade.aaron-powell.com/

Page 16: Nodejs express

16

4. 폼 전송 웹사이트 예제app.js route/index.js

views./layout.jade

views./join-form.jadeviews./join-result.jadeviews./index.jade

exports.index = function(req, res){ res.render('index', { title: 'Express' })};

exports.form = function(req,res) {

res.render('join-form', { title: 'Express' });};

exports.join = function(req,res) {

res.render('join-result', {username: req.body.name,useremail: req.body.email,title: 'Express'

});};

app.get('/', routes.index);app.get('/join', routes.form);app.post('/join', routes.join)

Page 17: Nodejs express

17

5. 데이터베이스 연동 - mysql

repository.jsinsertUser: function(user,res) { ... }, hasNameAndEmail: function(user, res) { client.query( 'SELECT * FROM ' + TABLE + 'WHERE name = ? OR email = ?' , [user.name, user.email] , function(err, results, fields) { if (err) { throw err; } if( results.length > 0 ) { res.render('join-fail', { title: 'Express' } ); } else { mysqlUtil.insertUser( user, res ); } });}

route/index.jsvar repo = require( ‘../repository’ );

exports.index = function(req, res){ …

exports.join = function(req,res) { // repo.insertUser( req.body, res ); repo. hasNameAndEmail( req.body, res ); };

설치 및 테이블 생성// install$ npm install mysql

// TABLE 생성CREATE TABLE members (name VARCHAR(20), email VARCHAR(30));

Page 18: Nodejs express

18

5. 데이터베이스 연동 - mongodb

외부 인터페이스

DB 접근 로직

가시화 로직

Repository.js

코드구조

뷰 렌더링 / DB 접근 로직을 분리하자 .

Page 19: Nodejs express

19

6. 비동기 패턴의 의존성 문제

• 비동기로 수행된다 수행시점을 알 수 없다 .• 해당 시점에 실행될 함수를 function pa-

rameter 로 전달

var result = db.query(‘SELECT …’ ); // 동기 방식 function call

db.query(‘SELECT … ‘, 처리하는 함수 ) // 비동기 방식 function call

Page 20: Nodejs express

20

6. 비동기 패턴의 의존성 문제 – 해결책

방법 1. callback 을 이용하여 의존성 분리// a.jsvar b = require( './b' );b.funcA( function( err, result1 ) { b.funcB( result1, function( err, result2 ) { //result 를 사용하는 코드 : 렌더링 로직 });});

// b.jsvar B = module.exports = { funcA: function( callback ) { db.query( 'SELECT ... ', callback ); }, funcB: function( callbck ) { db.query( 'SELECT ... ', callback ); }}

Page 21: Nodejs express

21

6. 비동기 패턴의 의존성 문제 – 해결책

방법 2. event 를 이용하여 의존성 분리// b.js

var EventEmitter = require('events').EventEmitter;

var B = module.exports = { funcA: function() { var evt = new EventEmitter(); db.query( 'SELECT ... ', function( err,result ) { evt.emit('end', err, result ); }); return evt; }, funcA: function() { var evt = new EventEmitter(); db.query( 'SELECT ... ', function( err,result ) { evt.emit('end', err, result ); }); return evt; }}

// a.jsvar b = require( './b' );var resultA = b.funcA();

resultA.on( 'end', function( err, result ) { var resultB = b.funcB(result); resultB.om( 'end', function( err, result ) { //result 사용하는코드 });});

Page 22: Nodejs express

22

6. 비동기 패턴의 의존성 문제 – 해결책

비동기 호출 순서를 보장하는 방법func repeater(i){ if( i < length ) { requestAsyncWork ( function() { repeater(i+1) } ) }}

repeater(0)

• 0 번 요청 끝 1 번 요청 1 번 요청 끝 2 번 요청 …• 결국 동기와 동일한 방식을 비동기로 구현한 것 .

Page 23: Nodejs express

23

7. 정리• 웹서버 생성– express.createServer()

• 서버 설정– express.createServer().configure( callback )– Callback 에서 express.createServer().set() 과 ex-

press.createServer().use() 사용• GET/POST 의 라우팅– express.createServer().get()– express.createServer().post()

• HTML 노가다 하지 말고 jade 로 작성하자 .– 디자이너와 소통이 어려울수도 있음 .

Page 24: Nodejs express

24

Express 에 대한 자세한 설명은 생략한다 .

http://firejune.io/express/guide를 참조 한다 .

질문 받겠습니다 .