换种方式去写node API
文章目录
- 搭建node 环境
- 通过babel 搭建node环境
- 通过 typeScirpt搭建环境
- 通过装饰器改造路由
搭建node 环境
通过babel 搭建node环境
npm install --save-dev babel-register
npm install --save-dev babel-plugin-transform-decorators-legacy
//支持装饰器语法
npm install --save-dev babel-preset-stage-3
//
npm install --save-dev babel-preset-env
// 我们可以使用babel-preset-env这个插件,它会自动检测当前node版本,只转码node不支持的语法,非常方便
npm install --save babel-polyfill
// babel转码时不能识别一些全局对象的API,例如Object.assign,使用它可以解决这个问题
根目录新建start.js文件
//start.js
require('babel-register')({// "presets": [// "stage-3",// ["env",{// "targets":{// "node":'current'// }// }]// ],"plugins":['transform-decorators-legacy']
})
require('babel-polyfill');
require('./test.js');
根目录新建test.js文件
//test.js
const router = conf => (target, key, desc) => {console.log(conf, target, key, desc, '----')
}
const post = path => {console.log('path', path);return router({path,});
}
class UserController {@post('login')login() {}
}
const a = async () => {console.log('await test a')return await 1;}
console.log(a(),'await ');
node start.js //启动项目
通过 typeScirpt搭建环境
根目录新建tsconfig.json
{"compilerOptions": {"declaration": false,"emitDecoratorMetadata": true,"experimentalDecorators": true,"lib": ["es2015","es2016","es2017","es2018","esnext",],"module": "commonjs","moduleResolution": "node","noImplicitThis": false,"noImplicitReturns": true,"outDir": "dist","sourceMap": false,"strict": true,"target": "es2015",},"exclude": ["node_modules","dist"]
}
npm -g typscript //ts 全局安装
修改package.json
"scripts": {"template":"tsc","start":"node dist/test.js"
}
npm run template //编译ts
npm run start //启动项目
通过装饰器改造路由
对路由封装
import Router from 'koa-router'
import glob from 'glob'
import { resolve } from 'path';
import _ from 'lodash';
/*** 以键值对存放路由信息* key {* target //存放路由前缀* method 请求方法* path 请求路由* }* value 存放被装饰器过后的方法* */
export let routersMap = new Map();
export const symbolPrefix = Symbol('prefix');
export const isArray = v => _.isArray(v) ? v : [v]
//给路径添加前缀 /
export const normalizePath = path => path.startsWith('/') ? path : `/${path}`;export default class Route {constructor(app, apiPath) {this.app = app;//实例路由this.router = new Router();this.apiPath = apiPath;}//init() {//引入所有路由文件glob.sync(resolve(this.apiPath, './*.js')).forEach(require);// this.router.get('/', async (ctx) => {// ctx.body = 'hello world';// })//挂载路由for (let [conf, controller] of routersMap) {const controllers = isArray(controller);let prefixPath = conf.target[symbolPrefix];if (prefixPath) prefixPath = normalizePath(prefixPath);const routerPath = prefixPath + conf.path;this.router[conf.method](routerPath,...controllers);}this.app.use(this.router.routes());this.app.use(this.router.allowedMethods());}
}export const router = conf => (target, key, desc) => {conf.path = normalizePath(conf.path)routersMap.set({target: target,...conf}, target[key])
}
// controller装饰器
export const controller = path => target => target.prototype[symbolPrefix] = pathexport const get = path => router({method: 'get',path: path
})export const post = path => router({method: 'post',path: path
})export const put = path => router({method: 'put',path: path
})export const del = path => router({method: 'delete',path: path
})
新建routersm目录
//routers/user
import { controller, put, del, post, get, required } from '../decorator/router'
import config from '../config'
import {resError, resSuccess} from '../utils/resHandle'
@controller(`${config.APP.ROOT_PATH}/user`)
export class userController{//获取用户信息@get('/:id')async getUserInfo(ctx){resSuccess({ctx,message:'获取用户信息',result:ctx.params})}//登录@post('login') async Login(ctx,next){const {username,password}=ctx.request.body;try {resSuccess({ctx,message:'login success'})} catch (error) {resError({ ctx, message: "login Error!" })}}//退出async LoginOut(ctx,next){}
}
信息反馈的封装
//对请求响应统一处理
export const resError = ({ ctx, message = '请求失败', err = null }) => {ctx.body = { code: 0, message, debug: err }
}export const resSuccess = ({ ctx, message = '请求成功', result = null }) => {ctx.body = { code: 1, message, result }
}
新建启动文件和主文件
//start.js
const { resolve } = require('path')
//用于支持 es6语法
require('babel-register')({'presets': ['stage-3',["latest-node", { "target": "current" }]],'plugins': ['transform-decorators-legacy']
})require('babel-polyfill')
require('./app')//app.js
import Koa from 'koa'
import config from './config'
import Route from './decorator/router'
import { resolve } from 'path';
const app = new Koa();//使用中间件
//引用路由
const router = new Route(app, resolve(__dirname, './routers'))
//初始化路由
router.init();
//启动服务
app.listen(config.APP.PORT, () => {console.log(`node-koa api run port at ${config.APP.PORT}`);
})
关于配置文件
const APP = {ROOT_PATH: '/api',LIMIT: 10,PORT: 3009
}
export default{APP
}
本文来自对 naice-blog-koa 学习仅供参考。
换种方式去写node API相关推荐
- 换种方式去分页(转)
为什么要换种方式分页,一个字:太慢了 分页要传入的参数,1:页号,2:行数 分页要取到的数据, 1:总行数,2:单页数据 http://www.cnblogs.com/mikedeng ...
- 技术人生感悟之陈果:如果你累了,就换一种方式去生活
复旦大学教授陈果在<好的孤独>中说:"换一种看法,便是换一种活法." 世间的活法有千万种,总会有一种是适合我们的. 人生苦短,如果你觉得累了,不如就换一种活法. 1.一 ...
- 避免回调地狱的解决方案 async/await:用同步的方式去写异步代码
文章目录 前言 一.引入异步编程 二.常见处理异步编程的几种方式 1.Generator函数 2.Promise函数 3.async/await 总结 前言 这篇文章主要给大家分享一下,自己关于异步编 ...
- 【Java基础】IO流概述分类、字节流写数据、字节流写数据的三种方式及写数据的两个小问题
目录 一.IO流概述和分类 二.字节流写数据 三.字节流写数据的三种方式 四.字节流写数据的两个小问题 一.IO流概述和分类 IO流介绍: ● IO:输入/输出(Input/Output) ● 流:是 ...
- 换一种方式去思考--microsoft for win server03
微软的东西被很多人鄙视. 原因是蔽塞,但大部分是无奈. 域环境下实现的强大功能是其他系统所不能比拟的. 沿用这样的战略思路.只要小盖开心,可以让全球的MS系统计算机组建成微软计算机群的大军. 这也是 ...
- 【第21期】以实际项目作驱动,换种方式学Java
Java作为OOP(面向对象编程)的集大成者,融合了其他语言的诸多优点,让开发者体验到了函数式编程的精妙及强大之处. 随着这几年开源社区的蓬勃发展,越来越多的组件.框架.方案如雨后春笋般涌现,现代工程 ...
- 企业拜年,今年可以换种方式了
就在刚刚,老板一脸严肃的走到我身边 在他沉默的3秒钟里,我有种不详的预感 努力工作了一年 老板不会通知我年终奖泡汤了吧,呜呜 "小白,你擅长策划,春节你觉得用什么方式与用户互动比较好?&qu ...
- 奥睿科硬盘柜linux下识别,云盘不靠谱?是时候换种方式解决存储问题了 — 奥睿科 多盘位硬盘柜阵列柜评测...
如今不管是电脑还是其他数码设备(手机等),性能都得到飞跃发展,一部高清电影动不动就是10G.20G,而一部3A游戏大作更有可能高达40G~50G.一般电脑.手机.平板的容量已经不能适应这类需求,这就需 ...
- linux换桌面窗口管理器,Awesome 窗口管理器——换种方式使用星际译王
星际译王被广泛使用的两个功能应该是划词翻译和手动输入翻译.由于星际译王缺少划词功能的开关快捷键,导致每次划词功能使用结束后,必须手动关闭此功能. 否则在 vim 视图模式下选择文本的时候会弹出不需要的 ...
最新文章
- Spring Cloud构建微服务架构:分布式配置中心(加密解密)
- HDU - 6661 Acesrc and String Theory (后缀数组)
- git 移动分支指针_理解git 中的HEAD指针branch指针
- servlet如何使用session把用户的手机号修改_SpringBoot源码学习系列之嵌入式Servlet容器...
- 如何在dorado中自定义导出
- 如何动态确认每个输入的值都符合设定域
- java实例成员与类成员区别_Java之实例成员与类成员
- 【优化算法】天牛须搜索优化粒子群算法【含Matlab源码 1256期】
- (Django开发)免费HTML模板资源集合
- PCL库实时显示点云流
- MySQL实战第二十二讲-MySQL有哪些“饮鸩止渴”提高性能的方法?
- 基于mindwave脑电波进行疲劳检测算法的设计(5)
- NYOJ_1273_宣传墙
- 支付宝沙箱测试手机网站支付,提示商户合作协议已到期,无法继续使用
- TM4C123GXL驱动安装
- VRRPv2和VRRPv3对比区别
- 转:python各种库
- 【QPSK中频】基于FPGA的QPSK中频信号产生模块verilog设计
- TPFanControl.ini
- oracle 分页公式