1.改造koa route修饰注册
1.实现原理
- 1.通过实现扫描文件夹自动注册路由 /src/routes/user.ts
- 2.对应的user.ts类使用 @get @post 修饰方法,完成路由注册
const router = new KoaRouter()
export const get = (path:String) => {
return (target,property) => {
router['get'](path,target[property])
}
}
2.代码实现
import * as Koa from 'koa'
import * as bodify from 'koa-body';
import * as serve from 'koa-static';
import * as timing from 'koa-xtime';
import * as Router from 'koa-router';
import {load} from './utils/route-decorors'
const app = new Koa()
app.use(
bodify({
multipart:true,
strict:false
})
)
import {resolve} from 'path'
const router = load(resolve(__dirname, './routes'))
app.use(router.routes())
app.listen(3000 ,() => {
console.log('服务器启动成功。。')
})
import * as glob from 'glob';
import * as Koa from 'koa';
import * as KoaRouter from 'koa-router';
const router = new KoaRouter()
export const method = (router:KoaRouter) => methodName => (path:String) => {
return (target,property) => {
router[methodName](path,target[property])
}
}
const routeDecorotes = method(router)
export const get = routeDecorotes('get')
export const post = routeDecorotes('post')
export const load = (folder:String) :KoaRouter => {
const extname = '.{js,ts}'
glob.sync(require('path').join(folder, `./**/*${extname}`)).forEach((item) => require(item))
return router
}
import * as Koa from 'koa'
import {get,post} from '../utils/route-decorors'
const users = [{ name: 'tom', age: 20 }]
export default class User {
@get('/users')
public list(ctx: Koa.Context) {
ctx.body = {
ok: 1,
data : users
}
}
@post('/users')
public add(ctx: Koa.Context) {
users.push(ctx.request.body)
ctx.body = { ok: 1}
}
}
2.添加校验
type RouteOptions = {
prefix?: string;
middlewares?: Array<Koa.Middleware>
}
export const method = (router:KoaRouter) => methodName => (path:String,options: RouteOptions = {}) => {
return (target, property: string) => {
const middlewares = []
if (target.middlewares) {
middlewares.push(...target.middlewares)
}
middlewares.push(target[property])
const url = options.prefix ? options.prefix + path : path
router[methodName](url, ...middlewares)
}
}
export default class User {
@get('/users'
)
public list(ctx: Koa.Context) {
ctx.body = {
ok: 1,
data : users
}
}
@post('/users'
, {
middlewares: [
async function validation(ctx: Koa.Context, next: () => Promise<any>) {
const name = ctx.request.body.name
if (!name) {
throw "请输入用户名";
}
await next();
}
]
})
public add(ctx: Koa.Context) {
users.push(ctx.request.body)
ctx.body = { ok: 2}
}
}
3.添加类的全局校验
export const method = (router:KoaRouter) => methodName => (path:String,options: RouteOptions = {}) => {
return (target, property: string) => {
process.nextTick(() => {
const middlewares = []
if (options.middlewares) {
middlewares.push(...options.middlewares)
}
if (target.middlewares) {
middlewares.push(...target.middlewares)
}
middlewares.push(target[property])
const url = options.prefix ? options.prefix + path : path
router[methodName](url, ...middlewares)
})
}
}
export const middlewares = (middlewares: Koa.Middleware[]) => {
return function (target) {
target.prototype.middlewares = middlewares
}
}
4.数据层自动加载
npm i -s sequelize-typescript@0.6.11
npm i -s types/sequelize@4.28.9
import { Table, Column, Model, DataType } from 'sequelize-typescript';
@Table({modelName: 'users'})
export default class User extends Model<User> {
@Column({
primaryKey: true,
autoIncrement: true,
type: DataType.INTEGER,
})
public id: number;
@Column(DataType.CHAR)
public name: string;
}
import { Sequelize } from 'sequelize-typescript';
const database = new Sequelize({
port:3306,
database:'xxxx',
username:'admin',
host: '81.xxx.xx.x',
password:'xxxx',
dialect:'mysql',
modelPaths: [`${__dirname}/model`],
});
database.sync({force: true})
import modelUser from '../model/user'
export default class User {
@get('/users'
)
public async list(ctx: Koa.Context) {
const users = await model.findAll()
console.log("数据库查询内容",users);
ctx.body = {
ok: 1,
data : users
}
}
}
5.使用parameter 校验body
import * as Parameter from 'Parameter'
const validateRule = paramPart => rule => {
return function (target, name, descriptor) {
const oldValue = descriptor.value
descriptor.value = function () {
const ctx = arguments[0]
const p = new Parameter()
const data = ctx[paramPart]
const errors = p.validate(rule, data)
console.log('error',errors)
if (errors) throw new Error(JSON.stringify(errors))
return oldValue.apply(null, arguments);
}
return descriptor;
}
}
export const querystring = validateRule('query')
export default class User {
@get('/users' )
@querystring({
age: { type: 'int', required: false, max: 200, convertType: 'int' },
})
public async list(ctx: Koa.Context) {
ctx.body = { ok: 1, data: users }
console.log("数据库查询内容",users);
ctx.body = {
ok: 1,
data : users
}
}
}