1.0.0 • Published 7 years ago

wubi v1.0.0

Weekly downloads
2
License
MIT
Repository
-
Last release
7 years ago

wubi

CircleCI codecov NodeVersion Dependencies DevDependencies Release License

基于 Koa 的面向未来的框架

为什么要用 Wubi 而不用 Koa ?

  1. Wubi 是对 Koa 进行封装扩展, 支持 Koa 所有中间件

  2. Wubi 整合了 koa-joi-router, 并提供了大量装饰器(需要 Babel 支持)用于定义路由和控制器. 它不是必须的, 如果你想使用它, 需要遵循 Wubi 控制器的书写要求, 使用 Wubi 提供的装饰器, 并通过 startRoute 方法启动.

    一个控制器例子如下:

    import {
      Controller,
      Validate,
      Joi,
      Get
    } from 'wubi'
    
    @Controller('/v1/problems', middleware1, middleware2)
    export default class Posts {
      @Get('/', middleware3, middleware4)
      @Validate({
        query: {
          offset: Joi.number().integer().min(0).default(0),
          limit: Joi.number().integer().min(0).max(50).default(10),
          sortby: Joi.string().valid('submitCount', 'passCount', 'id', 'percent').default('id'),
          order: Joi.string().valid('asc', 'desc').default('asc')
        }
      })
      async index (ctx, next) {
        console.log(123)
        const problems = await ctx.service.problems.list(ctx.query.offset, ctx.query.limit, ctx.query.sortby, ctx.query.order)
        ctx.ok(problems)
      }
    
      @Get('/:id')
      @Validate({
        params: {
          id: Joi.string().guid().required()
        }
      })
      async show (ctx, next) {
        const problem = await ctx.service.problems.show(ctx.params.id)
        ctx.ok(problem)
      }
    }

    除此之外, 你需要调用 Wubi 实例的 startRoute 方法.

    import Wubi from 'wubi'
    import wubiServiceLoader from 'wubi-service-loader'
    
    Wubi.inject(wubiServiceLoader())
    
    const app = new Wubi()
    
    app.startRoute() // 接受一个参数指定控制器所存放文件夹名, 默认为 'controllers'
    
    app.listen(8000)
    
    export default app
  3. Wubi 提供了 inject 方法, 通过该方法您可以自由的扩展 Koa 的 appctx 对象. 例如上面使用的 wubiServiceLoader 代码如下

    const path = require('path')
    const { requireDirectory } = require('toolkit')
    
    module.exports = (serviceDirName = 'service') => async function (ctx) {
      ctx.service = requireDirectory(`./${serviceDirName}/**/*.js`, {
        esm: true,
        construct: true,
        root: process.cwd()
      })[serviceDirName]
    }

    它的用途是把所有的在 service 文件夹中的 service 挂载到 ctx.service 上面. 之后你就可以像这样 ctx.service.problems.show 来调用.

    inject 方法类似 Koa 的 use 方法, 他们都是传入一个方法. inject 所传递的方法可以使用 appctx 中的任意一个参数, 他们会在框架内部通过依赖注入获得相应的实例.

  4. Wubi 是面向未来的框架. 虽然你可以在 Node 7.6 以上的版本使用, 但如果不使用 babel 你将无法使用内建路由以及一系列通过装饰器带来的诸多方便的写法.

  5. Wubi 还提供了 wubi-sequelize-loader, 通过使用它, 你可以如下定义一个 Model.

    export default class Discussion {
      static fields (DataTypes) {
        return {
          title: DataTypes.string(),
          content: DataTypes.text(),
          userId: DataTypes.uuid(),
          problemId: DataTypes.uuid()
        }
      }
    
      static random (Random) {
        return {
          title: Random.title(),
          content: Random.paragraph()
        }
      }
    
      static associate (User, Problem) {
        this.belongsTo(User, { as: 'user', foreignKey: 'userId' })
        this.belongsTo(Problem, { as: 'problem', foreignKey: 'problemId' })
      }
    }