0

基于服务器端 open api 3.0 文档自动生成客户端模型不会产生等效于服务器端 orm 父类。

我正在开发一个新的渡槽服务器,并希望从服务器端模型自动生成浏览器客户端模型。我创建了一个 LanguageLevel 模型类和一个 LanguageLesson 模型类,其中一个 LanguageLevel 有很多 LanguageLesson。我分别创建了两个对应的控制器和getAllLevels、createLanguageLevel和getAllLessons操作。然后我创建了迁移文件以及打开的 api 3.0 文档文件。我使用 open api generate 实用程序来创建客户端库。

这适用于 aqueduct CLI 和项目版本 3.1.0+1。以下结果与版本 3.0.2 相同。对于客户端模型生成,使用了 openapi-generator-cli-3.3.4。

服务器端

类 LanguageLevel 扩展 ManagedObject<_LanguageLevel> 实现 _LanguageLevel {}

类 _LanguageLevel {

@primaryKey
int pk;

@Column(unique: true)
int sequence;

ManagedSet<LanguageLesson> languageLessons;

}

类 LanguageLesson 扩展 ManagedObject<_LanguageLesson> 实现 _LanguageLesson {}

类_LanguageLesson {

@primaryKey
int pk;

@Column()
int sequence;

@Relate(#languageLessons)
LanguageLevel languageLevel;

}

使用命令打开api 3.0:渡槽文档

{ "openapi": "3.0.0", "info": { "title": "back_end", "description": "七个阿拉伯语服务器。", "version": "0.0.1" }, "servers": [{ "url": " http://localhost:8888假,“allowEmptyValue”:假,“模式”:{“类型”:“整数”}}],“响应”:{“200”:{“描述”:“成功响应。” } } } }, "/lessons/{id}": { "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type ": "字符串" } }] }, "/example": { "

注意 languageLevel 定义为仅具有“pk”属性的对象类型,LanguageLevel 定义为具有“pk”、“sequence”和“languageLessons”的对象类型。从规范中提取它们看起来像:

                "languageLevel": {
                    "title": "languageLevel",
                    "type": "object",
                    "properties": {
                        "pk": {
                            "type": "integer"
                        }
                    }
                }

        "LanguageLevel": {
            "title": "LanguageLevel",
            "type": "object",
            "properties": {
                "pk": {
                    "title": "pk",
                    "type": "integer",
                    "description": "This is the primary identifier for this object.\n",
                    "nullable": false
                },
                "sequence": {
                    "title": "sequence",
                    "type": "integer",
                    "description": "No two objects may have the same value for this field.\n",
                    "nullable": false
                },
                "languageLessons": {
                    "type": "array",
                    "items": {
                        "$ref": "#/components/schemas/LanguageLesson"
                    },
                    "nullable": true,
                    "readOnly": true
                }
            },
            "description": ""
        }

开放 API 生成的客户端模型(仅显示 LanguageLevel)

类语言级别 {

int pk = null;
LanguageLevel();

@override
String toString() {
  return 'LanguageLevel[pk=$pk, ]';
}

LanguageLevel.fromJson(Map<String, dynamic> json) {
    if (json == null) return;
    pk = json['pk'];
}

Map<String, dynamic> toJson() {
    return {
       'pk': pk
    };
}

static List<LanguageLevel> listFromJson(List<dynamic> json) {
    return json == null ? new List<LanguageLevel>() : json.map((value) => 
    new LanguageLevel.fromJson(value)).toList();
}

static Map<String, LanguageLevel> mapFromJson(Map<String, dynamic> json) {
    var map = new Map<String, LanguageLevel>();
    if (json != null && json.length > 0) {
        json.forEach((String key, dynamic value) => map[key] = new 
        LanguageLevel.fromJson(value));
    }
    return map;
}

}

除了所有必要的代码之外,它还创建了 LanguageLevel 和 LanguageLesson 模型类。LanguageLesson 模型看起来不错,因为它具有预期的属性和对 LanguageLevel 的引用。但是 LanguageLevel 仅具有服务器端模型的 @primarykey 等效项。所以现在没有办法从生成的代码中显示 LanguageLevel 对象。我希望在这个阶段能够做到这一点。

4

2 回答 2

0

使用这种格式真的很难阅读,但是模型在您的架构组件中正确定义。LanguageLesson 类型中的 languageLevel 属性由外键列支持。获取 LanguageLesson 时的默认行为将是只有一个填充了主键的对象。

如果您计划有一个端点,将完整的 LanguageLevel 对象与 LanguageLesson 连接起来,那么您需要通过覆盖 ResourceController 中用于文档生成的方法来覆盖该特定端点的 OpenAPI 响应。

于 2018-12-20T16:37:45.333 回答
0

根据 Open API Specification 3.0.2,我通过用 {"$ref": "#/components/schemas/LanguageLevel"} 替换“languageLevel”规范解决了这个问题。现在,当我针对规范文件运行 openapi-generate-cli 时,我得到了正确的类 LanguageLevel,如下所示:

类语言级别 {

int pk = null;
int sequence = null;

List<LanguageLesson> languageLessons = [];
LanguageLevel();

@override
String toString() {
    return 'LanguageLevel[pk=$pk, sequence=$sequence, languageLessons=$languageLessons, ]';
}

LanguageLevel.fromJson(Map<String, dynamic> json) {
    if (json == null) return;
    pk = json['pk'];
    sequence = json['sequence'];
    languageLessons = LanguageLesson.listFromJson(json['languageLessons']);
}

Map<String, dynamic> toJson() {
    return {
      'pk': pk,
      'sequence': sequence,
      'languageLessons': languageLessons
    };
}

static List<LanguageLevel> listFromJson(List<dynamic> json) {
    return json == null ? new List<LanguageLevel>() : json.map((value) => new LanguageLevel.fromJson(value)).toList();
}

static Map<String, LanguageLevel> mapFromJson(Map<String, dynamic> json) {
    var map = new Map<String, LanguageLevel>();
    if (json != null && json.length > 0) {
        json.forEach((String key, dynamic value) => map[key] = new LanguageLevel.fromJson(value));
    }
    return map;
}

}

我现在也拥有了 sequence 和 languageLessons 属性。

由于 Aqueduct 正在生成开放的 api 规范文件,我们可以肯定地说这是一个 Aqueduct 问题,在组件部分,它在子定义中创建不同的父定义,而不是将父属性引用到已经定义的父母。(注意:但是,它是将父类中的子数组属性引用到定义的子类。)

于 2018-12-22T11:02:36.173 回答