Add an option to skip unmarshall json in Go client generator (#18448)

* feat(go): Add a vendor extension to option out of generating the UnmarshalJSON method

* add generate unmarshal json option in go client generator

* update doc

---------

Co-authored-by: Radoslav Kotsev <radoslav.kotsev@cellpointmobile.com>
This commit is contained in:
William Cheng
2024-04-25 12:52:48 +08:00
committed by GitHub
parent 3bd6d67cc0
commit a00549cd65
10 changed files with 176 additions and 1 deletions

View File

@@ -22,6 +22,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|enumClassPrefix|Prefix enum with class name| |false|
|generateInterfaces|Generate interfaces for api classes| |false|
|generateMarshalJSON|Generate MarshalJSON method| |true|
|generateUnmarshalJSON|Generate UnmarshalJSON method| |true|
|hideGenerationTimestamp|Hides the generation timestamp when files are generated.| |true|
|isGoSubmodule|whether the generated Go module is a submodule| |false|
|packageName|Go package name (convention: lowercase).| |openapi|

View File

@@ -442,6 +442,8 @@ public class CodegenConstants {
public static final String GENERATE_MARSHAL_JSON = "generateMarshalJSON";
public static final String GENERATE_MARSHAL_JSON_DESC = "Generate MarshalJSON method";
public static final String GENERATE_UNMARSHAL_JSON = "generateUnmarshalJSON";
public static final String GENERATE_UNMARSHAL_JSON_DESC = "Generate UnmarshalJSON method";
public static final String MAX_ATTEMPTS_FOR_RETRY = "maxAttemptsForRetry";
public static final String WAIT_TIME_OF_THREAD = "waitTimeMillis";

View File

@@ -48,6 +48,8 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
protected boolean generateInterfaces = false;
protected boolean withGoMod = false;
protected boolean generateMarshalJSON = true;
protected boolean generateUnmarshalJSON = true;
protected String packageName = "openapi";
protected Set<String> numberTypes;
@@ -775,7 +777,11 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
}
if (generateMarshalJSON) {
model.vendorExtensions.put("x-go-generate-marshal-json", true);
model.vendorExtensions.putIfAbsent("x-go-generate-marshal-json", true);
}
if (generateUnmarshalJSON) {
model.vendorExtensions.putIfAbsent("x-go-generate-unmarshal-json", true);
}
}
@@ -932,6 +938,10 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
this.generateMarshalJSON = generateMarshalJSON;
}
public void setGenerateUnmarshalJSON(boolean generateUnmarshalJSON) {
this.generateUnmarshalJSON = generateUnmarshalJSON;
}
@Override
public String toDefaultValue(Schema schema) {
schema = unaliasSchema(schema);

View File

@@ -150,6 +150,7 @@ public class GoClientCodegen extends AbstractGoCodegen {
this.setDisallowAdditionalPropertiesIfNotPresent(true);
cliOptions.add(CliOption.newBoolean(WITH_GO_MOD, "Generate go.mod and go.sum", true));
cliOptions.add(CliOption.newBoolean(CodegenConstants.GENERATE_MARSHAL_JSON, CodegenConstants.GENERATE_MARSHAL_JSON_DESC, true));
cliOptions.add(CliOption.newBoolean(CodegenConstants.GENERATE_UNMARSHAL_JSON, CodegenConstants.GENERATE_UNMARSHAL_JSON_DESC, true));
this.setWithGoMod(true);
}
@@ -287,6 +288,11 @@ public class GoClientCodegen extends AbstractGoCodegen {
setGenerateMarshalJSON(Boolean.parseBoolean(additionalProperties.get(CodegenConstants.GENERATE_MARSHAL_JSON).toString()));
}
if (additionalProperties.containsKey(CodegenConstants.GENERATE_UNMARSHAL_JSON)) {
setGenerateUnmarshalJSON(Boolean.parseBoolean(additionalProperties.get(CodegenConstants.GENERATE_UNMARSHAL_JSON).toString()));
}
// add lambda for mustache templates to handle oneOf/anyOf naming
// e.g. []string => ArrayOfString
additionalProperties.put("lambda.type-to-name", (Mustache.Lambda) (fragment, writer) -> writer.write(typeToName(fragment.execute())));

View File

@@ -337,6 +337,7 @@ func (o {{classname}}) ToMap() (map[string]interface{}, error) {
return toSerialize, nil
}
{{#vendorExtensions.x-go-generate-unmarshal-json}}
{{#isAdditionalPropertiesTrue}}
func (o *{{{classname}}}) UnmarshalJSON(data []byte) (err error) {
{{/isAdditionalPropertiesTrue}}
@@ -514,4 +515,5 @@ func (o *{{{classname}}}) UnmarshalJSON(data []byte) (err error) {
}
{{/isArray}}
{{/vendorExtensions.x-go-generate-unmarshal-json}}
{{>nullable_model}}

View File

@@ -312,6 +312,48 @@ public class GoClientCodegenTest {
"BaseItem");
}
@Test
public void testVendorExtensionGenerateUnmarshalJson() throws IOException {
File output = Files.createTempDirectory("test").toFile();
output.deleteOnExit();
final CodegenConfigurator configurator = new CodegenConfigurator()
.setGeneratorName("go")
.setGitUserId("OpenAPITools")
.setGitRepoId("openapi-generator")
.setInputSpec("src/test/resources/3_0/go/allof_with_unmarshal_json.yaml")
.setOutputDir(output.getAbsolutePath().replace("\\", "/"));
DefaultGenerator generator = new DefaultGenerator();
List<File> files = generator.opts(configurator.toClientOptInput()).generate();
files.forEach(File::deleteOnExit);
TestUtils.assertFileExists(Paths.get(output + "/model_base_item.go"));
TestUtils.assertFileContains(Paths.get(output + "/model_base_item.go"),
"func (o *BaseItem) UnmarshalJSON(data []byte) (err error) {");
}
@Test
public void testVendorExtensionSkipGenerateUnmarshalJson() throws IOException {
File output = Files.createTempDirectory("test").toFile();
output.deleteOnExit();
final CodegenConfigurator configurator = new CodegenConfigurator()
.setGeneratorName("go")
.setGitUserId("OpenAPITools")
.setGitRepoId("openapi-generator")
.setInputSpec("src/test/resources/3_0/go/allof_skip_unmarshal_json.yaml")
.setOutputDir(output.getAbsolutePath().replace("\\", "/"));
DefaultGenerator generator = new DefaultGenerator();
List<File> files = generator.opts(configurator.toClientOptInput()).generate();
files.forEach(File::deleteOnExit);
TestUtils.assertFileExists(Paths.get(output + "/model_base_item.go"));
TestUtils.assertFileNotContains(Paths.get(output + "/model_base_item.go"),
"func (o *BaseItem) UnmarshalJSON(data []byte) (err error) {");
}
@Test
public void testAdditionalPropertiesWithGoMod() throws Exception {
File output = Files.createTempDirectory("test").toFile();

View File

@@ -53,5 +53,6 @@ public class GoClientOptionsTest extends AbstractOptionsTest {
verify(clientCodegen).setUseOneOfDiscriminatorLookup(GoClientOptionsProvider.USE_ONE_OF_DISCRIMINATOR_LOOKUP_VALUE);
verify(clientCodegen).setWithGoMod(GoClientOptionsProvider.WITH_GO_MOD_VALUE);
verify(clientCodegen).setGenerateMarshalJSON(GoClientOptionsProvider.GENERATE_MARSHAL_JSON_VALUE);
verify(clientCodegen).setGenerateUnmarshalJSON(GoClientOptionsProvider.GENERATE_UNMARSHAL_JSON_VALUE);
}
}

View File

@@ -38,6 +38,7 @@ public class GoClientOptionsProvider implements OptionsProvider {
public static final boolean USE_ONE_OF_DISCRIMINATOR_LOOKUP_VALUE = true;
public static final boolean WITH_GO_MOD_VALUE = true;
public static final boolean GENERATE_MARSHAL_JSON_VALUE = true;
public static final boolean GENERATE_UNMARSHAL_JSON_VALUE = true;
@Override
public String getLanguage() {
@@ -60,6 +61,7 @@ public class GoClientOptionsProvider implements OptionsProvider {
.put(CodegenConstants.USE_ONEOF_DISCRIMINATOR_LOOKUP, "true")
.put(CodegenConstants.WITH_GO_MOD, "true")
.put(CodegenConstants.GENERATE_MARSHAL_JSON, "true")
.put(CodegenConstants.GENERATE_UNMARSHAL_JSON, "true")
.put("generateInterfaces", "true")
.put("structPrefix", "true")
.build();

View File

@@ -0,0 +1,55 @@
openapi: 3.0.0
info:
title: Test
version: 1.0.0
paths: {}
components:
schemas:
FinalItem:
type: object
allOf:
- $ref: '#/components/schemas/BaseItem'
- $ref: '#/components/schemas/AdditionalData'
BaseItem:
type: object
x-go-generate-unmarshal-json: false
properties:
title:
type: string
type:
type: string
enum:
- FINAL
example: FINAL
discriminator:
propertyName: type
mapping:
FINAL: '#/components/schemas/FinalItem'
required:
- title
- type
AdditionalData:
type: object
properties:
prop1:
type: string
quantity:
type: integer
format: int32
example: 1
minimum: 1
unitPrice:
type: number
format: double
example: 9.99
minimum: 0.0
totalPrice:
type: number
format: double
example: 9.99
minimum: 0.0
required:
- prop1
- quantity
- unitPrice
- totalPrice

View File

@@ -0,0 +1,54 @@
openapi: 3.0.0
info:
title: Test
version: 1.0.0
paths: {}
components:
schemas:
FinalItem:
type: object
allOf:
- $ref: '#/components/schemas/BaseItem'
- $ref: '#/components/schemas/AdditionalData'
BaseItem:
type: object
properties:
title:
type: string
type:
type: string
enum:
- FINAL
example: FINAL
discriminator:
propertyName: type
mapping:
FINAL: '#/components/schemas/FinalItem'
required:
- title
- type
AdditionalData:
type: object
properties:
prop1:
type: string
quantity:
type: integer
format: int32
example: 1
minimum: 1
unitPrice:
type: number
format: double
example: 9.99
minimum: 0.0
totalPrice:
type: number
format: double
example: 9.99
minimum: 0.0
required:
- prop1
- quantity
- unitPrice
- totalPrice