360前端星计划-Node.js 基础入门(下)

基于Node.js的Web开发

Web

const http = require('http');
const server = http.createServer((req, res) => {
  res.end('Hello World');
});
server.listen(3000);

Koa

const Koa = require('koa');
const app = new Koa();

// response
app.use(ctx => {
  ctx.body = 'Hello Koa';
});

app.listen(3000);
module.exports = class Application extends Emitter {
  ...
  listen() {
    debug('listen');
    const server = http.createServer(this.callback());
    return server.listen.apply(server, arguments);
  }

  use(fn) {
    this.middleware.push(fn);
    return this;
  }
  
  callback() {
    const fn = compose(this.middleware);
    
    if (!this.listeners('error').length) this.on('error', this.onerror);

    const handleRequest = (req, res) => {
      res.statusCode = 404;
      const ctx = this.createContext(req, res);
      const onerror = err => ctx.onerror(err);
      const handleResponse = () => respond(ctx);
      onFinished(res, onerror);
      return fn(ctx).then(handleResponse).catch(onerror);
    };

    return handleRequest;
  }
  
  createContext(req, res) {
    const context = Object.create(this.context);
    const request = context.request = Object.create(this.request);
    const response = context.response = Object.create(this.response);
    context.app = request.app = response.app = this;
    context.req = request.req = response.req = req;
    context.res = request.res = response.res = res;
    request.ctx = response.ctx = context;
    request.response = response;
    response.request = request;
    context.originalUrl = request.originalUrl = req.url;
    context.cookies = new Cookies(req, res, {
      keys: this.keys,
      secure: request.secure
    });
    request.ip = request.ips[0] || req.socket.remoteAddress || '';
    context.accept = request.accept = accepts(req);
    context.state = {};
    return context;
  }
}

Koa 无规范约束,不利于团队开发 ; 中间件繁多,质量参差不齐,选择困难

Think.js 类似.net API

├─src
│ ├─bootstrap
│ ├─config
│ │ ├─config.js
│ │ └─adapter.js
│ ├─controller
│ │ ├─index.js
│ ├─logic
│ │ ├─index.js
│ └─model
├─view
│ ├─index_index.html
└─www
│ └─static
│ ├─css
│ ├─img
│ └─js
├─development.js
├─production.js
├─package.json

// src/controller/index.js
export default class extends think.Controller {
  indexAction() {
    return this.display();
  }
}

// view/index_index.html
<h3>Hello World</h3>

安装 创建项目

$ thinkjs new todo
$ cd todo
$ npm install
simple-todo npm start
> simple-todo@1.0.0 start /Users/lizheming/Desktop/star-plan/simple-todo
> node development.js

API开发 Restful 风格

RESTful 接口规范

每个 API 都对应一种资源或资源集合
使用 HTTP Method 来表示对资源的动作
使用 HTTP Status Code 来表示资源操作结果

创建 API 文件

➜  simple-todo thinkjs controller -r ticket

   think-cli · Create: src/controller/rest.js
   think-cli · Create: src/controller/ticket.js
   think-cli · Create: src/logic/api/ticket.js

配置路由 src/config/router.js

基类自动生成 src/controller/rest.js

getAction
// src/controller/rest.js
async getAction() {
  let data;
  if (this.id) {
    const pk = this.modelInstance.pk;
    data = await this.modelInstance.where({ [pk]: this.id }).find();
    return this.success(data);
  }
  data = await this.modelInstance.select();
  return this.success(data);
}
其他方法类似

数据库配置

// src/config/adapter.js
exports.model = {
  type: 'mysql',
  common: {
    logConnect: isDev,
    logSql: isDev,
    logger: msg => think.logger.info(msg)
  },
  mysql: {
    handle: mysql,
    database: 'todo',
    prefix: '',
    encoding: 'utf8',
    host: '127.0.0.1',
    port: '',
    user: 'root',
    password: 'root',
    dateStrings: true
  }
};

http://127.0.0.1:8360/ticket
{
  "errno": 0,
  "errmsg": "",
  "data": [{
    "id": 1,
    "desc": "八点打扫房间",
    "status": 0,
    "createdAt": "2018-07-08 17:12:59",
    "updatedAt": "2018-07-08 17:13:14"
  }]
}

数据校验

// src/logic/ticket.js
module.exports = class extends think.Logic {
  getAction() {
    this.rules = {
      id: {
        int: true
      }
    };
  }
  deleteAction() {
    this.rules = {
      id: {
        int: true,
        required: true,
        method: 'get'
      }
    };
  }
  putAction() {
    this.rules = {
      id: {
        int: true,
        required: true,
        method: 'get'
      },
      status: {
        int: true,
        required: true
      },
      desc: {
        required: true
      }
    };
  }
  postAction() {
    this.rules = {
      desc: {
        required: true
      }
    };
  }
};

DELETE http://127.0.0.1:8360/ticket

{
  "errno": 1001,
  "errmsg": {
    "id": "id can not be blank"
  }
}

数据库操作

操作模型

src/model
const model = this.model(modeName);
根据模型名查找 src/model 下的模型文件
文件存在,实例化对应的模型类
文件不存在,实例化 think.Model 类
定义
// src/model/todo.js
module.exports = class TodoModel extends think.Model {
getList () {
// get list
}
}

Node.js调试

日志调试
断点调试
node --inspect
vscode
ndb
NodeJS 6.3+ 使用 node --inspect 参数启动可以在 Chrome 浏览器中调试,在 chrome://inspect 中可以发现你的项目并启动 devtool

Node 开发角色转换

前端

  • 跟浏览器打交道,兼容性问题
  • 组件化
  • 加载速度、JS 执行性能、渲染性能
  • 错误监控
  • XSS、CSRF 等安全漏洞

服务端

  • 数据库、Redis 等周边服务
  • 性能、内存泄露、CPU、机器管理
  • 服务监控、错误监控、流量监控、报警
  • SQL注入、目录遍历等安全漏洞
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容