Express

 

What is express?

a fast router module for nodejs 

Express特點

  • NodeJs 中最小又靈活的web框架
  • 使用人數最多的套件之一
  • 具備route以及middleware機制
  • 具備完善的request以及response方法
  • 效能快速
  • 有許多express的模組可以安裝使用
  • 具備繁體中文手冊(zhtw)

How use?

In your project

在你的專案裡面

$ npm install express --save

In global base on "express-generator"

$ npm install express-generator -g
$ express "your-project-name"

安裝express-generator

利用express-generator建立專案

安裝nodejs所需的模組套件

$ npm install 
$ npm run start

啟動專案

檔案結構

.
├── app.js
├── bin
│   └── www
├── package.json
├── public
│   ├── images
│   ├── javascripts
│   └── stylesheets
│       └── style.css
├── routes
│   ├── index.js
│   └── users.js
└── views
    ├── error.jade
    ├── index.jade
    └── layout.jade

all

.
├── app.js

app.js

express預設載入各個套件及各個檔案增加

以及error偵測處理

.
├── bin
│   └── www

bin/www

伺服器預設載入點,並且在此可以設定監聽port號以及在之後可以把websocket放在此檔案一起在同個port號做監聽

.
├── package.json

package.json

Nodejs Package Manager 的模組設定檔案

.
├── public
│   ├── images
│   ├── javascripts
│   └── stylesheets
│       └── style.css

public

放置給網頁使用者觀看的css,js,image,或是靜態檔案

.
├── routes
│   ├── index.js
│   └── users.js

routes

放置各個路由群組的目錄

.
└── views
    ├── error.jade
    ├── index.jade
    └── layout.jade

views

放置各個網頁的畫面(html)的地方,在express預設使用的是jade引擎

express預設載入模組介紹

var express = require('express')
var bodyParser = require('body-parser')

var app = express()

// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))

// parse application/json
app.use(bodyParser.json())

app.use(function (req, res) {
  res.setHeader('Content-Type', 'text/plain')
  res.write('you posted:\n')
  res.end(JSON.stringify(req.body, null, 2))
})
var express = require('express')
var bodyParser = require('body-parser')

var app = express()

// create application/json parser
var jsonParser = bodyParser.json()

// create application/x-www-form-urlencoded parser
var urlencodedParser = bodyParser.urlencoded({ 
  extended: false 
})

// POST /login gets urlencoded bodies
app.post('/login', urlencodedParser, function (req, res) {
  if (!req.body) return res.sendStatus(400)
  res.send('welcome, ' + req.body.username)
})

// POST /api/users gets JSON bodies
app.post('/api/users', jsonParser, function (req, res) {
  if (!req.body) return res.sendStatus(400)
  // create user in req.body
})

針對http body以及header中的各種作成物件模組化

var express      = require('express')
var cookieParser = require('cookie-parser')

var app = express()
app.use(cookieParser())

app.get('/', function(req, res) {
  console.log("Cookies: ", req.cookies)
})

app.listen(8080)

// curl command that sends an HTTP request with two cookies
// curl http://127.0.0.1:8080 --cookie "Cho=Kim;Greet=Hello"

針對http cookie做模組化以及物件化

var debug = require('debug');
var error = debug('app:error');

// by default stderr is used
error('goes to stderr!');

var log = debug('app:log');
// set this namespace to log via console.log
log.log = console.log.bind(console); // don't forget to bind to console!
log('goes to stdout');
error('still goes to stderr!');

// set all output to go via console.info
// overrides all per-namespace log settings
debug.log = console.info.bind(console);
error('now goes to stdout via console.info');
log('still goes to stdout, but via console.info now');

針對nodejs debug工具做更優化的處理

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Jade</title>
    <script type="text/javascript">
      if (foo) {
         bar(1 + 5)
      }
    </script>
  </head>
  <body>
    <h1>Jade - node template engine</h1>
    <div id="container" class="col">
      <p>You are amazing</p>
      <p>
        Jade is a terse and simple
        templating language with a
        strong focus on performance
        and powerful features.
      </p>
    </div>
  </body>
</html>

針對html所做的jade模板引擎

doctype html
html(lang="en")
  head
    title= pageTitle
    script(type='text/javascript').
      if (foo) {
         bar(1 + 5)
      }
  body
    h1 Jade - node template engine
    #container.col
      if youAreUsingJade
        p You are amazing
      else
        p Get on it!
      p.
        Jade is a terse and simple
        templating language with a
        strong focus on performance
        and powerful features.

針對express所做出來的log模組

var express = require('express')
var fs = require('fs')
var morgan = require('morgan')

var app = express()

// create a write stream (in append mode)
var accessLogStream = fs.createWriteStream(__dirname + '/access.log', {flags: 'a'})

// setup the logger
app.use(morgan('combined', {stream: accessLogStream}))

app.get('/', function (req, res) {
  res.send('hello, world!')
})

針對express所出來的server web favicon

(網頁左上角Logo)

var express = require('express');
var favicon = require('serve-favicon');

var app = express();
app.use(favicon(__dirname + '/public/favicon.ico'));

// Add your routes here, etc.

app.listen(3000);

create Get Method Of API by express 

透過get /可看到hello world文字

var router = require('express').Router();

router.get('/', function(req, res, next) {
  res.send('hello world!!');
});

module.exports = router;

透過get / 看到 html

var router = require('express').Router();

router.get('/', function(req, res, next) {
  res.render('examples');
});

module.exports = router;

create Post Method Of API by express 

透過post / 看到hello world文字

var router = require('express').Router();

router.get('/', function(req, res, next) {
  res.render('example');
});

router.post('/', function(req, res, next) {
  res.send('hello world');
});

module.exports = router;

request介紹

req.params

router.get('/request/params/:id', function(req, res, next) {
  res.send("my params id:" + req.params.id);
});

抓出路由名稱中變數的值

example :id

req.body

router.post('/request/body', function(req, res, next) {
  res.json(req.body);
});

抓出body的raw或是x-www-form-urlencode的key-value值

req.headers

router.post('/request/header', function(req, res, next) {
  res.json(req.headers);
});

抓出Client請求的header檔

req.query

router.post('/request/query', function(req, res, next) {
  res.json(req.query);
});

抓出路由器中的query變數

response介紹

res.setHeader

router.get('/response/setHeader', function(req, res, next) {
  res.setHeader('Content-Type', 'text/plain');
});

設定回應給使用者的header

res.write & res.end

router.get('/response/writeAndEnd', function(req, res, next) {
  res.write('hi client... \n');
  res.end('bye client...');
});
  

write:回應給使用者的文字

end:回應給使用者文字並結束

res.status & res.send

router.get('/response/statusAndSend', function(req, res, next) {
  res.status(404).send('statusCode400');
});

status:回應http status code給使用者

send:回應字串使用者

res.status & res.json

router.get('/response/statusAndJson', function(req, res, next) {
  var jsonObject = {
    a: 123,
    b: 456
  };
  res.status(404).json(jsonObject);
});

status:回應http status code給使用者

json:回應json給使用者

練習

利用get建立99乘法表

輸出格式應該為:

{
    x:7,
    y:3,
    data:[
        [1,2,3, 4, 5, 6, 7],
        [2,4,6, 8,10,12,14],
        [3,6,9,12,15,18,21]
    ];
}

輸入應該為

get /api/9x9?x=7&y=3

Answer

router.get('/9x9', function(req, res, next) {
  var x = req.query.x || 9;
  var y = req.query.y || 9;

  var result = {
    x: x,
    y: y,
    data: []
  };

  for (var i = 1; i <= y; i++) {
    result.data.push([]);
    for (var j = 1; j <= x; j++) {
      result.data[(i - 1)].push(i * j);
    }
  }

  res.json(result);
});
Made with Slides.com