npm.io
1.0.26 • Published 1 year ago

xiao-koa

Licence
MIT
Version
1.0.26
Deps
11
Size
1.2 MB
Vulns
2
Weekly
31

Xiao Koa

前端人快速开发后端服务的利器

文档网站  


介绍

基于Koa2的一款模仿SpringBoot装饰器风格框架

特点

  • 快速 极低配置开启一个后端服务

  • 轻量 不需要手动导入任何模块

  • 灵活 开放Koa的Use函数让框架极其灵活

  • 生态 后续将会出生态库,例如模仿Mybatis

安装

使用npm安装:

npm i xiao-koa

更新时间

2025/5/29:

修改拦截器的方式,不需要手动next()

新增响应拦截器

新增RequestParam,可以获得ctx.request里的参数,一般配合files使用 将run里的路由分离出来initRouter(),好做前置后置拦截。 新增setCORS跨域功能,使用的koa2-cors ​

2025/5/28:

新增 app.getRouters()

新增 run()的时候自动获得路径

新增@GetCtx,可以获得原生ctx

新增请求装饰器不写参数自动按方法名匹配地址

新增app.setResources(path.join(__dirname, 'resources'))

index.ts案例

import { Application, xiaoKoaApp } from "xiao-koa";

@Application
export default class TestApplication {
  main(app: xiaoKoaApp) {
    app.run(1234);
  }
}

application.yml案例

server:
  port: 1234

功能

export const Get = createRequestControllerDecorator('get')
export const Post = createRequestControllerDecorator('post')
export const Put = createRequestControllerDecorator('put')
export const Delete = createRequestControllerDecorator('delete')
export const Options = createRequestControllerDecorator('options')
export const Patch = createRequestControllerDecorator('patch')
export const Head = createRequestControllerDecorator('head')

如果属性值为空,则自动根据函数名进行生成路径
@Get() //不写或者为''都自动匹配
async getMessages() {
    // 这个路径就为/getMessages
 }

@Get('/')
async getMessages() {
    // 这个路径就为匹配Controller父路径
 }
export const PathVariable = createRequestParamsDecorator('PathVariable')
export const RequestHeader = createRequestParamsDecorator('RequestHeader')

@RequestMapping('/request/:id')
pathVariable(@PathVariable('id') userId: any) {
  return { msg: '演示PathVariable', userId }
}

@RequestMapping('/requestHeader')
requestHeader(@RequestHeader('token') tokenCode: string) {
  return { msg: '演示RequestBody', tokenCode }
}

@RequestMapping('/requestBody')
requestBody(@RequestBody user: any) {
  return { msg: '演示RequestBody', user }
}

@Post('/post')
post(@RequestParam('files') file: string) {
  console.log(321);
  return { msg: '这是Post请求' }
}

async sendMessage(@GetCtx('') ctx: any) {
    console.log(ctx.request.files);
}
@Controller('/demo') // 访问控制器
@Service(alias?: string)	// 服务控制器
@Configuration	// 配置文件控制器
// 使用上面的控制的模块可以注入
@Autowired
declare tokenInterceptor: TokenInterceptor
// 配置控制
import { Service, HandlerInterceptor, DefaultContext, DefaultState, Next, ParameterizedContext } from 'xiao-koa'

@Service()
export default class TokenInterceptor implements HandlerInterceptor {
  async preHandle(ctx: ParameterizedContext<DefaultState, DefaultContext, unknown>, next: Next) {
    if (ctx.request.header['token']) {
      await next()	//等待下一个中间件
    } else {
      throw { code: 403, error: '没有token' }
    }
  }
}


import { Autowired, Configuration, registryType, WebMvcConfigurer } from 'xiao-koa'
import TokenInterceptor from './TokenInterceptor'

@Configuration
export default class WebConfig2 implements WebMvcConfigurer {
  // 参数名必须是以方法TokenInterceptor开头小写进行命名,要不就是server('xx')起别名
    @Autowired
  declare tokenInterceptor: TokenInterceptor


  addInterceptors(registry: registryType) {
    registry.addInterceptor(this.tokenInterceptor)
  }

}

excludePathPatterns > addPathPatterns > addInterceptor
import serve from 'koa-static'
import path from 'path'
import { Application, xiaoKoaApp } from 'xiao-koa'

@Application
export default class DemoApplication {
  main(app: xiaoKoaApp) {
    console.log(path.join(__dirname,'./img'));


    app.use(serve(path.join(__dirname,'./img')))

    app.run()
  }
}

export declare class xiaoKoaApp {
    globalPrefix: string;
    dir: string;
    JsonStr: any;
    private routers;
    constructor(callerPath: string);
    run(prot?: number): Server;
    getRouters(): Promise<unknown>;
    use(fn: Middleware): void;
    mount(fn: Function): void;
    setGlobalPrefix(prefix: string): void;
    setResources(path: string, opts?: serve.Options): void;
}