我已经定义了自定义 Mustache 模板,通过在自定义 Codegen 生成器中扩展 AbstractJavaCodegen 类来生成 Java 应用程序。
我的目标是生成一个自定义的ServiceImpl.java文件,并根据操作Id在方法主体中包含条件逻辑。
操作Id可以是以下之一:“createOrder”、“patchOrder”、“deleteOrder”、“retrieveOrder”或“listOrder”。在swagger规范中定义(所有上述操作Id都存在于swagger json中) .
我希望包含每个操作对应的逻辑,而跳过其他操作的不相关逻辑。
例如,这是我的模板的结构:
{{#operations}}
public class {{classname}}ServiceImpl implements {{classname}}Service {
{{#operation}}
@Override
public ResponseEntity<{{>returnTypes}}> {{operationId}}({{#allParams}}{{>optionalDataType}} {{paramName}}{{^-last}}, {{/-last}}{{/allParams}}) {
{{#create-operation}}
// Logic for createOrder operation and skip other operation's logic
{{/create-operation}}
{{#patch-operation}}
// Logic for patchOrder operation and skip other operation's logic
{{/patch-operation}}
{{#delete-operation}}
// Logic for deleteOrder operation and skip other operation's logic
{{/delete-operation}}
{{#retrieve-operation}}
// Logic for retrieveOrder operation and skip other operation's logic
{{/retrieve-operation}}
{{#list-operation}}
// Logic for listOrder operation and skip other operation's logic
{{/list-operation}}
return new ResponseEntity<>(HttpStatus.OK);
}
{{/operation}}
这可以使用 Mustache 模板中的条件逻辑来实现吗?特别是确保基于操作 ID 的每个方法只包含相关的操作逻辑?
如果没有,我们有没有办法使用自定义 Codegen 来做到这一点?
我尝试了什么?
我尝试在将数据传递到 Mustache 模板之前对其进行预处理,但它没有按照我期望的方式工作。
输出:
它重复了所有方法中所有操作的逻辑,这不符合我的要求。
我猜测输入到模板中的数据大致类似于以下 JSON(ish) 表示形式。为了演示目的,我简化了一些细节。
{
operations: [{
operation: {
returnTypes: 'ProductOrder',
operationId: 'createProductOrder',
allParams: [{
dataType: 'ProductOrderCreate',
paramName: 'productOrder',
'-last': true,
}],
},
}, {
operation: {
returnTypes: 'Void',
operationId: 'deleteProductOrder',
allParams: [{
dataType: 'String',
paramName: 'id',
'-last': true,
}],
},
}, {
operation: {
returnTypes: 'List<ProductOrder>',
operationId: 'listProductOrder',
allParams: [{
dataType: 'String',
paramName: 'fields',
'-last': false,
}, {
dataType: 'Integer',
paramName: 'offset',
'-last': false,
}, {
dataType: 'Integer',
paramName: 'limit',
'-last': true,
}],
},
}, {
operation: {
returnTypes: 'ProductOrder',
operationId: 'patchProductOrder',
allParams: [{
dataType: 'String',
paramName: 'id',
'-last': false,
}, {
dataType: 'ProductOrderUpdate',
paramName: 'productOrder',
'-last': true,
}],
},
}, {
operation: {
returnTypes: 'ProductOrder',
operationId: 'retrieveProductOrder',
allParams: [{
dataType: 'String',
paramName: 'id',
'-last': false,
}, {
dataType: 'String',
paramName: 'fields',
'-last': true,
}],
},
}],
}
在数据预处理尝试中,您循环遍历
operations
并调用 additionalProperties.put
以便添加 create-operation
等属性。我不知道 OpenAPI Generator,但我怀疑此方法会在输入数据的根部插入属性。因此,在第一次迭代之后,您的输入数据看起来像这样(假装 operations
也位于根):
{
operations: [{
operation: {
operationId: 'createProductOrder',
// ...
},
}, {
// ...
}],
'create-operation': true,
}
循环完成后,它将如下所示:
{
operations: [{
operation: {
operationId: 'createProductOrder',
// ...
},
}, {
// ...
}],
'create-operation': true,
'delete-operation': true,
'list-operation': true,
'patch-operation': true,
'retrieve-operation': true,
}
如果将以下保存状态复制粘贴到 Mustache Playground 的加载/存储框中,然后按渲染按钮,您将看到这确实产生了您所得到的结果:
{"data":{"text":"{\n operations: [{\n operation: {\n returnTypes: 'ProductOrder',\n operationId: 'createProductOrder',\n allParams: [{\n dataType: 'ProductOrderCreate',\n paramName: 'productOrder',\n '-last': true,\n }],\n },\n }, {\n operation: {\n returnTypes: 'Void',\n operationId: 'deleteProductOrder',\n allParams: [{\n dataType: 'String',\n paramName: 'id',\n '-last': true,\n }],\n },\n }, {\n operation: {\n returnTypes: 'List<ProductOrder>',\n operationId: 'listProductOrder',\n allParams: [{\n dataType: 'String',\n paramName: 'fields',\n '-last': false,\n }, {\n dataType: 'Integer',\n paramName: 'offset',\n '-last': false,\n }, {\n dataType: 'Integer',\n paramName: 'limit',\n '-last': true,\n }],\n },\n }, {\n operation: {\n returnTypes: 'ProductOrder',\n operationId: 'patchProductOrder',\n allParams: [{\n dataType: 'String',\n paramName: 'id',\n '-last': false,\n }, {\n dataType: 'ProductOrderUpdate',\n paramName: 'productOrder',\n '-last': true,\n }],\n },\n }, {\n operation: {\n returnTypes: 'ProductOrder',\n operationId: 'retrieveProductOrder',\n allParams: [{\n dataType: 'String',\n paramName: 'id',\n '-last': false,\n }, {\n dataType: 'String',\n paramName: 'fields',\n '-last': true,\n }],\n },\n }],\n 'create-operation': true,\n 'delete-operation': true,\n 'list-operation': true,\n 'patch-operation': true,\n 'retrieve-operation': true,\n}"},"templates":[{"name":"main","text":"{{#operations}}\n{{#operation}}\n@Override\npublic ResponseEntity<{{&returnTypes}}> {{operationId}}({{#allParams}}{{dataType}} {{paramName}}{{^-last}}, {{/-last}}{{/allParams}}) {\n {{#create-operation}}\n // Logic for createOrder operation and skip other operation's logic\n {{/create-operation}}\n {{#patch-operation}}\n // Logic for patchOrder operation and skip other operation's logic\n {{/patch-operation}}\n {{#delete-operation}}\n // Logic for deleteOrder operation and skip other operation's logic\n {{/delete-operation}}\n {{#retrieve-operation}}\n // Logic for retrieveOrder operation and skip other operation's logic\n {{/retrieve-operation}}\n {{#list-operation}}\n // Logic for listOrder operation and skip other operation's logic\n {{/list-operation}}\n return new ResponseEntity<>(HttpStatus.OK);\n}\n \n{{/operation}}\n{{/operations}}"}]}
为什么会出现这种情况?因为 Mustache 使用上下文堆栈。当您迭代列表或数组时,输入数据的较低级别保持可见。因此,每个
operation
都可以看到每个 create-operation
、delete-operation
等属性,从而导致所有可选方法体都包含在每个渲染操作中。
模板正确。您只需要更改预处理,以便像
create-operation
这样的属性插入到每个单独的 operation
中,而不是在根级别。换句话说,您希望输入数据如下所示:
{
operations: [{
operation: {
returnTypes: 'ProductOrder',
operationId: 'createProductOrder',
allParams: [ /*...*/ ],
'create-operation': true,
},
}, {
operation: {
returnTypes: 'Void',
operationId: 'deleteProductOrder',
allParams: [ /*...*/ ],
'delete-operation': true,
},
}, {
operation: {
returnTypes: 'List<ProductOrder>',
operationId: 'listProductOrder',
allParams: [ /*...*/ ],
'list-operation': true,
},
}, {
operation: {
returnTypes: 'ProductOrder',
operationId: 'patchProductOrder',
allParams: [ /*...*/ ],
'patch-operation': true,
},
}, {
operation: {
returnTypes: 'ProductOrder',
operationId: 'retrieveProductOrder',
allParams: [ /*...*/ ],
'retrieve-operation': true,
},
}],
}
以下 savestate 表明这确实会产生所需的输出:
{"data":{"text":"{\n operations: [{\n operation: {\n returnTypes: 'ProductOrder',\n operationId: 'createProductOrder',\n allParams: [{\n dataType: 'ProductOrderCreate',\n paramName: 'productOrder',\n '-last': true,\n }],\n 'create-operation': true,\n },\n }, {\n operation: {\n returnTypes: 'Void',\n operationId: 'deleteProductOrder',\n allParams: [{\n dataType: 'String',\n paramName: 'id',\n '-last': true,\n }],\n 'delete-operation': true,\n },\n }, {\n operation: {\n returnTypes: 'List<ProductOrder>',\n operationId: 'listProductOrder',\n allParams: [{\n dataType: 'String',\n paramName: 'fields',\n '-last': false,\n }, {\n dataType: 'Integer',\n paramName: 'offset',\n '-last': false,\n }, {\n dataType: 'Integer',\n paramName: 'limit',\n '-last': true,\n }],\n 'list-operation': true,\n },\n }, {\n operation: {\n returnTypes: 'ProductOrder',\n operationId: 'patchProductOrder',\n allParams: [{\n dataType: 'String',\n paramName: 'id',\n '-last': false,\n }, {\n dataType: 'ProductOrderUpdate',\n paramName: 'productOrder',\n '-last': true,\n }],\n 'patch-operation': true,\n },\n }, {\n operation: {\n returnTypes: 'ProductOrder',\n operationId: 'retrieveProductOrder',\n allParams: [{\n dataType: 'String',\n paramName: 'id',\n '-last': false,\n }, {\n dataType: 'String',\n paramName: 'fields',\n '-last': true,\n }],\n 'retrieve-operation': true,\n },\n }],\n}"},"templates":[{"name":"main","text":"{{#operations}}\n{{#operation}}\n@Override\npublic ResponseEntity<{{&returnTypes}}> {{operationId}}({{#allParams}}{{dataType}} {{paramName}}{{^-last}}, {{/-last}}{{/allParams}}) {\n {{#create-operation}}\n // Logic for createOrder operation and skip other operation's logic\n {{/create-operation}}\n {{#patch-operation}}\n // Logic for patchOrder operation and skip other operation's logic\n {{/patch-operation}}\n {{#delete-operation}}\n // Logic for deleteOrder operation and skip other operation's logic\n {{/delete-operation}}\n {{#retrieve-operation}}\n // Logic for retrieveOrder operation and skip other operation's logic\n {{/retrieve-operation}}\n {{#list-operation}}\n // Logic for listOrder operation and skip other operation's logic\n {{/list-operation}}\n return new ResponseEntity<>(HttpStatus.OK);\n}\n \n{{/operation}}\n{{/operations}}"}]}
不幸的是,由于我不了解 OpenAPI Generator,所以我无法告诉您获取上述形状的数据的最正确方法是什么。也许其他人可以添加解决这个问题的答案。