egg-controller icon indicating copy to clipboard operation
egg-controller copied to clipboard

这库很好用,在使用中,有一些感受和建议

Open vfasky opened this issue 5 years ago • 3 comments

在生成 open API 上

  • 希望使用 typescript-json-schema 这样 response,requestBody 都能通过 interface 去生成
  • FromQuery | FromBody 等目前只能定义别名,希望添加一个 SchemaObject 参数,去完善参数定义

如果有了 json schema, 参数验证是不是可以基于 schema 定义,再加一些自定义设置,如 min maxlength 就可以生成了呢?

我结合了 typescript-json-schema,做了一些尝试

import * as TJS from 'typescript-json-schema'
import { SchemaObject } from 'openapi3-ts'

import * as path from 'path'

const program = TJS.programFromConfig(
    path.join(__dirname, 'tsconfig.json')
)

const tsSchema = TJS.buildGenerator(program, {
    required: true
})

export function get(name: string) {
    const schema = ((tsSchema && tsSchema.getSchemaForSymbol(name, true)) ||
        {}) as SchemaObject

    if (schema.$schema) {
        delete schema.$schema
    }

    let components: {
        [schema: string]: SchemaObject
    } = {}

    if (schema.definitions) {
        components = JSON.parse(
            JSON.stringify(schema.definitions).replace(
                /\#\/definitions\//g,
                '#/components/schemas/'
            )
        )
        delete schema.definitions

        const data = JSON.stringify(schema).replace(
            /\#\/definitions\//g,
            '#/components/schemas/'
        )

        return {
            schema: JSON.parse(data),
            components
        }
    }

    return {
        schema,
        components
    }
}

export function getOpenAPIRes(name: string) {
    const { schema, components } = get(name)

    return {
        response: schema,
        components
    }
}

export function getOpenAPI(reqName: string, resName: string) {
    const req = get(reqName)
    const res = get(resName)

    return {
        response: res.schema,
        requestBody: req.schema,
        components: {
            ...req.components,
            ...res.components
        }
    }
}

使用

export default class ActionsController extends Controller {
    @route({
        schemas: {
            ...getOpenAPIRes('API.ResponseActions')
        }
    })
    public async index(){}
}

另外,requestBody 还是 TODO 状态,如果完成了,这库生成 swagger 真的是非常棒

vfasky avatar Sep 26 '19 11:09 vfasky

想法不错,不过还是感觉从 TypeScript 代码出发比较自然,声明式编程为主,校验 & 增强信息部分可以融合 class-validator 这种方案。

目前我这里的实践,返回值类型可以通过 TypeScript 编译插件解析类型信息,生成对应的 OAS 3.0 数据,后续计划将入参一并处理,生成 OAS 不需要手写代码,缺点是需要在编译时做处理,添加插件。

https://github.com/zhang740/egg-controller/tree/master/lib/transformer

zhang740 avatar Sep 30 '19 17:09 zhang740

hi, 有 TypeScript 编译插件的配置文档或相关信息吗?

vfasky avatar Dec 18 '19 07:12 vfasky

@vfasky 在 lib/transformer/ttsc.js ,可以配合 ttypescript 配置到编译插件,目前以支持解析入参,简单的方式,使用 ttypescript 的 ttsc 替代 tsc,在 tsconfig.json 中配置 plugins:

{
  "compilerOptions": {
     ...
    "plugins": [
      {
        "transform": "egg-controller/lib/transformer/ttsc.js"
      }
    ]
  }
}

zhang740 avatar Dec 29 '19 05:12 zhang740