03-nodeJS 中 Restful 架构实现

03-nodeJS 中 Restful 架构实现

1、什么是 restful

Restful:表述性状态转移(框架的原则和约束条件)主要用于客户端和服务器交互类的软件。基于这个风格设计的软件会更简洁,更有层次,实现缓存机制。这是一种URL的设计风格(路由风格)。

Restful:通俗的说,用什么样的方式写路由。常见的URL风格:静态 news/ids/1 利于SEO优化;动态 news?id=1 不利于SEO(后面的查询参数)原来是通过HTTP请求的内容判断具体的业务逻辑(增删改查)restful通过HTTP请求的类型(get post delete)判断业务逻辑。同一个资源使用同一个URL,具体操作根据请求的方法实现。

传统的URL http://127.0.0.1:user/delete/id 这样的URL中含有增删改查字样描述性的URL,和 HTTP 设计理念不符合。因为 HTTP 请求接口或者地址的时候完全没有必要去描述(HTTP本身没有语义)。

restful:面向资源(user)对于同一个资源,都在一个URL下操作,根据判断HTTP的请求的类型决定做不同的事情。HTTP 不同的请求类型(GET POST PUT DELETE)对应不同的数据库操作(增删改查)。

Node顶层路由:一个路由不一定对应一个界面(一个Html文件)http处理函数(路由风格)架构和业务层已经脱离关系了,架构是通用的解决方案。

2、原生实现 Restful

原生NodeJS实现服务

原生实现 Restful

npm install -D mysql body-parser
npm install co-mysql md5-node

Index.js

const http = require('http');
const mysql = require('mysql');
const co = require('co-mysql');
const md5 = require('md5-node');

let db = mysql.createPool({
  host: 'localhost',
  user: 'root',
  password: 'root',
  database: 'user',
});
let conn = co(db);

// 同一个URL下实现不同的操作
const app = http.createServer((req, res) => {
  if (req.method === "POST") {
    if (req.url === './user') {
      // res.end(JSON.stringify({
      //   message: 'POST操作',
      //   status: 200
      // }))
      let arr = [];
      req.on('data', (data) => {
        arr.push(data);
      })
      req.on('end', async () => {
        let buffer = Buffer.concat(arr);
        let { username, password } = JSON.parse(buffer.toString());
        let data = await conn.query(`select user from admin where user = '${username}'`);
        console.log(data);
        // 如果从数据库中检索到,返回已经注册
        if (data.length >= 1) {
          res.end(JSON.stringify({
            "statue": 200,
            "message": "用户名已经注册"
          }));
        } else {
          // 如果从数据库中没有检索到,直接写入数据库
          password = md5(password);
          let sql = `insert into admin (user,password) values ('${username}', '${password}')`;
          await conn.query(sql);
          res.end(JSON.stringify({
            'status': 200,
            'message': '注册成功'
          }));
        }
      });
    }
  } else if (req.method === "GET") {
    if (req.url === './user') {
      // res.end(JSON.stringify({
      //   message: 'GET操作',
      //   status: 200
      // }))
      let sql = 'select id, user, password from admin';
      let data = await conn.query(sql);
      res.end(JSON.stringify(data));
    }
  }
}).listen(3000);

REST client 配置 .http

@url = http://localhost:3000
@type = Content-Type: application/json

GET {{url}}/user HTTP/1.1

POST {{url}}/user HTTP/1.1
{{type}}

{
    "username": "admin",
    "password": 123456
}

3、框架实现 RestFul

express实现服务:改写了异步请求和回调函数,使用 generator 实现异步操作

Demo 01 Express 实现

使用 NodeJS 的 express 创建一个案例

npm init
npm install -D express
touch app.js
nodemon app.js# nodemon 是自动更新的node(类似于热启动)

app.js

const express = require('express');
const app = express();

app.get('/user', (req, res) => {
  res.send('test page');
});

app.listen(3000);

URL 定位资源,HTTP描述操作

顶层路由设计:不需要有物理文件去映射路由

Demo02

Express 实现 restful

const express = require('express');
const http = require('http');
const mysql = require('mysql');
const co = require('co-mysql');
const md5 = require('md5-node');
const bodyparse = require('body-parser')

const app = express();

let db = mysql.createPool({
  host: 'localhost',
  user: 'admin',
  password: 'root',
  database: 'test-user',
});

let conn = co(db);

app.use(bodyparse.urlencoded({
  extended: true
}));

app.use(bodyparse.json());

app.post('/user', async (req, res) => {
  let { user, password } = req.body;
  let data = await conn.query(`select user from admin where user = '${username}'`);
    if (data.length >= 1) {
    res.send(JSON.stringify({
      'status': 200,
      'message': '用户名已经注册'
    }))
  } else {
    password = md5(password);
    let sql = `insert into admin (user,password) values ('${username}','${password}')`;
    await conn.query(sql);
    res.end(JSON.stringify({
      'status': 200,
      'message': '注册成功'
    }));
  }
});

app.get('/user/:id', (req, res) => {
  res.send(req.params.id);
  // 到数据库中查询(sql)
});

app.listen(3000);

demo03

koa 实现 restful

koa:async await

config.js

module.exports = {
  host: 'localhost',
  user: 'root',
  password: 'root',
  database: 'user',
};

Databases.js

const mysql = require('mysql');
const co = require('co-mysql');
const config = require('../config');

const { host, user, password, database } = config;
let db = mysql.createPool({
  host,
  user,
  password,
  database,
});

module.exports = co(db);

index.js

const Router = require('koa-router');
const md5 = require('md5-node');
const router = new Router();

router.get('/user', async ctx => {
  ctx.body = 'main page';
});

app.js

const Koa = require('koa');
const Router = require('koa-router');
const body = require('koa-bodyparser');

const app = new Koa();
const router = new Router();
app.context.db = require('./libs/databases');
app.context.config = config;

app.use(body());
router.user('/api', require('./router'));

app.use(router.routes());
app.listen(3000);
Rabbit.js 的定位是一个超轻量的快速开发框架。Light and Fast。你甚至很快就可以理解它的底层实现(也许只需要5分钟)。Rabbit.js本身的代码量并不大,这得益于很多NodeJS开源库的支持,通过 一些有效的组合,成为这样一个简单而清晰的开发框架。 Rabbit.js 能够提供一个清晰的开发思路,让你的应用逻辑清晰并且足够结构化,但是同时又不会增加你的开发复杂度,相反,复杂度被降低,因为在逻辑分层的过程对很多操作做了封装,你要做的就是关注自己需要关注的逻辑代码,而不用关心框架本身。 Rabbit.js 是一个依靠约定和封装进行工作的框架,秉承约定大于配置的快速开发理念,高度自动化,提高开发效率。不过可能因此降低了一些灵活性,但是本框架的定位决定 其使用场景,Rabbit.js比较适合于小型项目或者个人项目,得益于其快速开发的特点,可以快速搭建restfull的网络服务。 特色 清晰的应用分层,可以帮助您构建大型的应用,具体见章节“分层” 约定大于配置,基本无需配置,即可开始开发之旅。 约定大于配置,团队合作写出来的应用代码基本一致,方便统一代码风格。 应用的restful的route完全根据目录结构自动生成,无需自己声明和指定。 controller和view之间拥有自动映射,你在controller里无需指定渲染的view路径。 分层之间不采用跳路径方式应用,而是根据名字寻找,无需关心自己和别的分层得js得目录结构关系。 将controller层,service层,model层做了抽象封装,大部分通用逻辑都已经默认添加,极大的减少代码量。 对model层做了特别封装,同时支持sql和mongodb,写法完全一样。 model层封装成了promise的写法,让你的数据操作更清晰简介。 功能插件系统,开发,常用的服务器功能一句话引入,例如用户系统,无需开发。 默认为您配置了一个可用的express服务器。 clone下来,查看文档,立马开始您的开发之旅。 标签:Rabbit  Web框架
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值