npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@4a/koa-api-router

v0.1.3

Published

koa-api-router

Readme

koa-api-router

定义某种自定义规范,方便api开发,因为DEMO依赖Enum 所以接入过程会稍显复杂,实际使用起来比较爽
Enum
EnumCodeMessage

Install

npm i @4a/koa-api-router

Usage

const assert = require('@4a/enum/assert')
const router = require('@4a/koa-api-router').default()
const ResultMessage = require('@4a/enum-code-message')

router.append(resolver, {

    // ROOT表示根路由,等同于 /
    async get_ROOT(ctx, next) {
        const params = ctx.query

        // 参数合法性检查
        // 此处不通过会直接抛出ResultMessage关联异常
        // Response响应结果类似 { code: 400000, message: 'error message' }
        // 如果ctx.ResponseId有值,则Response响应结果类似:
        // { code: 400000, message: 'error message', ResponseId: '...' }
        assert.ok(params.token, ResultMessage.PermissionDenied)

        // 此处assert是@4a/enum模块下定制版的断言模块
        // @4a/enum/assert断言模块仅支持由@4a/Enum创建的静态枚举类型创建的EnumError异常
        // 当然也可以使用Nodejs官方提供的assert断言库,after方法稍加处理即可兼容
        assert.ok(params.token.length >= 6, ResultMessage.ErrorToken)

        assert.ok(params.email, ResultMessage.LossEmail)

        // 参数检查通过之后,暂存到ctx.state属性之下
        // 下游resolver会用到它
        ctx.state.params = params

        // 当然不仅仅是参数检查
        // 任何你需要预处理程式都可以在这里定义
        // 任意条件不通过,即可在此处抛出异常信息
        // 所有预处理通过之后,即可执行await next() 交由下游resolver进一步处理

        await next()
    },

    // 路由规则
    // {Method}_{RoutePath}_{RouteResolverKey}
    // 当 RoutePath == RouteResolverKey 时,RouteResolverKey可以省略
    // 因为路由规则使用下划线作为分隔符,所以路由规则关键字中不能再使用额外的下划线
    async 'get_app/:id_getApp'(ctx, next) {
        const params = ctx.params

        assert.ok(isNaN(params.id), ResultMessage.NotFound)

        ctx.state.params = params

        await next()

        // 可根据需要在此执行某些收尾工作
        // 接口响应异常收集、上报等通过程式建议放在after方法内
        // after方法下文有介绍
    },

    // 当 RoutePath == RouteResolverKey 时,RouteResolverKey可以省略
    async get_login(ctx, next) {
        await next()
    }
})

resolver

// 下游 Resolver
class HomeResolver {

    ROOT(ctx) {
        // 此时 ctx.state.params 是可信的

        ctx.body = ctx.state.params
    }

    getApp(ctx) {
        ctx.body = ctx.state.params
    }

    login(ctx) {
        console.log(ctx.state.params)
        ctx.body = 'ok'
    }
}

After Response

Router实现了一个after方法,用于处理通用异常,实现如下:

/**
 * router通用后处理函数
 * @param {Error?} err 
 * @param {Koa.Context} ctx Koa上下文
 */
function after(err, ctx) {
    if (err) {
        // DEBUG环境变量开启Koa-api-router即可显示此日志
        // eg: DEBUG=Koa-api-router npm run dev
        debug('Error:', err)

        // 兼容处理由@4a/Enum创建的静态枚举类型创建的EnumError异常
        // 可自定义Error子类,只要自定义的Error实例实现了Encode方法,即可被兼容处理
        if (err.Encode && typeof err.Encode === 'function') {
            return ctx.body = err.Encode({ ResponseId: ctx.ResponseId })
        }
        ctx.body = {
            // 当error实例携带有魔改版的code,也可以被兼容处理
            // 理论上来说所有可预见异常都应该在ResultMessage枚举实例中进行枚举
            // 超出预期的异常code值应该是500xxx,这里默认值是500000
            code: isNaN(err.code) ? 500000 : err.code,
            message: err.message,
            ResponseId: ctx.ResponseId,
        }
    }
    // 此处可收集异常响应,或执行异常响应上报等操作
    else if (!ctx.body || ctx.body.code !== 0) {
        debug('Exception Response:', ctx.body)
    }
}

如果需要自定义异常处理,可以重写此方法,重写after示例

class CustomRouter extends Router {

    after(err, ctx) {
        // ... your code
    }
}