基于服务器端打开的api 3.0文档自动生成客户端模型不会产生与服务器端orm父类等效的结果。
我正在开发新的渡槽服务器,并希望从服务器端模型自动生成浏览器客户端模型。我创建了一个LanguageLevel模型类和一个LanguageLesson模型类,其中LanguageLevel有许多LanguageLesson。我分别创建了两个相应的控制器和getAllLevels,createLanguageLevel和getAllLessons操作。然后,我创建了迁移文件以及打开的api 3.0文档文件。我使用了开放式api生成实用程序来创建客户端库。
这是针对渡槽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”, “信息”:{ “ title”:“ back_end”, “ description”:“七个阿拉伯语服务器。”, “版本”:“ 0.0.1” }, “服务器”:[{ “ url”:“ http://localhost:8888” }], “路径”:{ “ /级别”:{ “参数”:[], “获取”:{ “标签”:[“级别”], “ operationId”:“ getAllLevels”, “参数”:[{ “ name”:“ sequence”, “ in”:“查询”, “必填”:false, “ allowEmptyValue”:否, “模式”:{ “ type”:“整数” } }], “响应”:{ “ 200”:{ “ description”:“成功响应。” } } }, “帖子”:{ “标签”:[“级别”], “ operationId”:“ createLanguageLevel”, “参数”:[], “ requestBody”:{ “必填”:是, “内容”:{ “ application / json”:{ “模式”:{ “ $ ref”:“#/ components / schemas / LanguageLevel” } } } }, “响应”:{ “ 200”:{ “ description”:“成功响应。” } } } }, “ / levels / {sequence}”:{ “参数”:[{ “ name”:“ sequence”, “ in”:“路径”, “必填”:是, “模式”:{ “ type”:“字符串” } }] }, “ /课程”:{ “参数”:[], “获取”:{ “标签”:[“经验”], “ operationId”:“ getAllLessons”, “参数”:[{ “ name”:“ id”, “ in”:“查询”, “必填”:false, “ allowEmptyValue”:否, “模式”:{ “ type”:“整数” } }], “响应”:{ “ 200”:{ “ description”:“成功响应。” } } } }, “ /课程/ {id}”:{ “参数”:[{ “ name”:“ id”, “ in”:“路径”, “必填”:是, “模式”:{ “ type”:“字符串” } }] }, “ / example”:{ “参数”:[] } }, “组件”: { “方案”:{ “ LanguageLesson”:{ “ title”:“ LanguageLesson”, “ type”:“对象”, “属性”:{ “ pk”:{ “ title”:“ pk”, “ type”:“整数”, “ description”:“这是该对象的主要标识符。\ n”, “可为空”:false }, “顺序”: { “ title”:“ sequence”, “ type”:“整数”, “可为空”:false }, “ languageLevel”:{ “ title”:“ languageLevel”, “ type”:“对象”, “属性”:{ “ pk”:{ “ type”:“整数” } } } }, “说明”:“” }, “ LanguageLevel”:{ “ title”:“ LanguageLevel”, “ type”:“对象”, “属性”:{ “ pk”:{ “ title”:“ pk”, “ type”:“整数”, “ description”:“这是该对象的主要标识符。\ n”, “可为空”:false }, “顺序”: { “ title”:“ sequence”, “ type”:“整数”, “ description”:“该字段的两个对象都不能具有相同的值。\ n”, “可为空”:false }, “ languageLessons”:{ “ type”:“ array”, “项目”:{ “ $ ref”:“#/ components / schemas / LanguageLesson” }, “ nullable”:是的, “ readOnly”:是 } }, “说明”:“” } }, “响应”:{}, “参数”:{}, “ requestBodies”:{}, “标题”:{}, “ securitySchemes”:{}, “回调”:{} } }
请注意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": ""
}
Open API生成的客户端模型(仅显示LanguageLevel)
类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对象。我希望在这一阶段能够做到这一点。
答案 0 :(得分:0)
使用这种格式确实很难阅读,但是模型是在架构组件中正确定义的。 LanguageLesson类型中的languageLevel属性由外键列支持。当您获取LanguageLesson时,默认行为是只填充主键的对象。
如果您打算在端点上将整个LanguageLevel对象与LanguageLesson结合在一起,则需要通过重写ResourceController中用于生成文档的方法来覆盖该特定端点的OpenAPI响应。
答案 1 :(得分:0)
我已按照Open API规范3.0.2的要求,用{“ $ ref”:“#/ components / schemas / LanguageLevel”}替换了“ languageLevel”规范,从而解决了该问题。现在,当我对规范文件运行openapi-generate-cli时,将获得正确的类LanguageLevel,如下所示:
类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属性。
由于打开的api规范文件是由Aqueduct生成的,因此我们可以放心地说这是Aqueduct的问题,在组件部分中,它将在子定义中创建另一个父定义,而不是将parent属性引用到已经定义的父级。 (注意:但是,它将父类中的子数组属性引用到已定义的子项。)