4. 构建Node Web程序
1.HTTP服务器的基本知识
呈现一个HTTP请求
var http = require("http");
var server = http.createServer(function(req, res) {
  // 读取请求头 以及 设置响应头
  var body = "cool!";
  res.setHeader("Content-Length", body.length);
  res.setHeader("Content-Type", "text/plain");
  // 设置状态码
  res.statusCode = 302;
  // 处理请求
  // res.write(body)
  // res.end();
  res.end(body);
});
server.listen(3000);
- 添加和移除响应头的顺序可以随意,但一定要在调用res.write()或 res.end()之前。
- 在响应主体的第一部分写入之后,Node会刷新已经设定好的HTTP头。
2. 构建RESTful Web服务
1. 用POST请求创建资源
var http = require("http");
var server = http.createServer(function(req, res) {
  // 设置utf8后, 下面data就会给出字符串,而不是对象
  req.setEncoding('utf8')
  // 读取请求头 以及 设置响应头
  req.on("data", function(chunk) {
    console.log("parsed" + chunk);
  });
  req.on("end", function() {
    console.log("done parsing");
    res.end();
  });
});
server.listen(3000);
5. 存储Node程序中的数据
1. 无服务的数据存储
- 内存存储
- 弊端: 不能持久化
 
- 基于文件的存储
- 弊端: 单文件并发有问题.
 
2. 关系型数据库管理系统
关系型数据库,查询起来很容易, 开源软件也可以不花钱
- MySQL
- node-mysql 模块(https://github.com/felixge/node-mysql)
- npm install mysql
 
- PostgreSQL
- 轻量目录访问协议
- 通过安全服务应用程序接口
- 同步复制: 在每次数据操作后对复制进行验证,从而防止数据丢失
- npm install pg
 
3. NoSQL数据库
含义是 No SQL 或者 Not only SQL
- Redis
- 适合处理不需要长期访问的数据存储
- 数据存储于 RAM 中
- 数据存储有限, 但数据操作非常快
- npm install redis
 
- MongoDB
- 通用的 非关系型 数据库,
- npm install mongodb
 
- Mongoose
- 其可以顺畅地使用MongoDB
- 提供了一些实用的功能
 
6. Connect
其是一个框架, 使用中间件的模块化组件.
1. 搭建一个Connect程序
- 第三方模块需要安装. npm install connect
var connect = require('connect');
var app = connect();
app.listen(3000);
2. 工作机制
- 其中间件概念受到Ruby的Rack框架的启发.
- 小巧
- 自包含
- 可以在整个程序中重用
 
- 
next()在中间件里调用, 用回调函数,而不是从方法中返回, 是为了可以在中间件组件里运行异步逻辑.
var connect = require("connect");
function logger(req, res, next) {
  console.log("%s %s", req.method, req.url);
  next();
}
function hello(req, res) {
  res.setHeader("Content-Type", "text/plain");
  res.end("hello world!");
}
connect()
  .use(logger)
  .use(hello)
  .listen(3000);
3. 中间件的顺序很重要
如果前一个中间件,不调用next(), 命令链中的后续中间件都不会被调用.
4. 挂载中间件和服务器
可以根据挂载的路径前缀.选择性的调用中间件
var connect = require("connect");
connect()
  .use(logger)
  .use('/admin',restrice)
  .use('/admin',admin)
  .use(hello)
  .listen(3000);
function admin(req, res, next) {
  switch (req.url) {
    case "/":
      res.end("try /users");
      break;
    case "/users":
      res.setHeader("Content-Type", "application/json");
      res.end(JSON.stringify(["tobi", "loki", "jane"]));
      break;
  }
}
5. 创建可配置中间件
利用闭包, 返回可以配置的中间件
function setup(options) {
  // 设置逻辑
  
  return function (req, res, next) {
    // 中间件逻辑
  } 
}
app.use(setup({some:'options'}))
