Skip to content

[GO] Go Server: preserve order of the routes as defined in the OpenAPI file #19550

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,10 @@ public interface CodegenConfig {

void setSkipOperationExample(boolean skipOperationExample);

boolean isSkipSortingOperations();

void setSkipSortingOperations(boolean skipSortingOperations);

public boolean isHideGenerationTimestamp();

public void setHideGenerationTimestamp(boolean hideGenerationTimestamp);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,8 @@ apiTemplateFiles are for API outputs only (controllers/handlers).
@Getter @Setter
protected int removeOperationIdPrefixCount = 1;
protected boolean skipOperationExample;
// sort operations by default
protected boolean skipSortingOperations = false;

protected final static Pattern XML_MIME_PATTERN = Pattern.compile("(?i)application\\/(.*)[+]?xml(;.*)?");
protected final static Pattern JSON_MIME_PATTERN = Pattern.compile("(?i)application\\/json(;.*)?");
Expand Down Expand Up @@ -6154,6 +6156,16 @@ public void setSkipOperationExample(boolean skipOperationExample) {
this.skipOperationExample = skipOperationExample;
}

@Override
public boolean isSkipSortingOperations() {
return this.skipSortingOperations;
}

@Override
public void setSkipSortingOperations(boolean skipSortingOperations) {
this.skipSortingOperations = skipSortingOperations;
}

@Override
public boolean isHideGenerationTimestamp() {
return hideGenerationTimestamp;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ public Generator opts(ClientOptInput opts) {
this.opts = opts;
this.openAPI = opts.getOpenAPI();
this.config = opts.getConfig();

List<TemplateDefinition> userFiles = opts.getUserDefinedTemplates();
if (userFiles != null) {
this.userDefinedTemplates = Collections.unmodifiableList(userFiles);
Expand Down Expand Up @@ -680,7 +681,10 @@ void generateApis(List<File> files, List<OperationsMap> allOperations, List<Mode
for (String tag : paths.keySet()) {
try {
List<CodegenOperation> ops = paths.get(tag);
ops.sort((one, another) -> ObjectUtils.compare(one.operationId, another.operationId));
if(!this.config.isSkipSortingOperations()) {
// sort operations by operationId
ops.sort((one, another) -> ObjectUtils.compare(one.operationId, another.operationId));
}
OperationsMap operation = processOperations(config, tag, ops, allModels);
URL url = URLPathUtils.getServerURL(openAPI, config.serverVariableOverrides());
operation.put("basePath", basePath);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ public class GoServerCodegen extends AbstractGoCodegen {
public GoServerCodegen() {
super();

// skip sorting of operations to preserve the order found in the OpenAPI spec file
super.setSkipSortingOperations(true);

modifyFeatureSet(features -> features
.includeDocumentationFeatures(DocumentationFeature.Readme)
.wireFormatFeatures(EnumSet.of(WireFormatFeature.JSON, WireFormatFeature.XML))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
* Copyright 2018 SmartBear Software
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.openapitools.codegen.goserver;

import org.openapitools.codegen.DefaultGenerator;
import org.openapitools.codegen.TestUtils;
import org.openapitools.codegen.config.CodegenConfigurator;
import org.testng.Assert;
import org.testng.annotations.Test;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;

public class GoServerCodegenTest {

@Test
public void verifyGoMod() throws IOException {
File output = Files.createTempDirectory("test").toFile();
output.deleteOnExit();

final CodegenConfigurator configurator = createDefaultCodegenConfigurator(output)
.setInputSpec("src/test/resources/3_0/go-server/route-order.yaml");

DefaultGenerator generator = new DefaultGenerator();
List<File> files = generator.opts(configurator.toClientOptInput()).generate();
files.forEach(File::deleteOnExit);

TestUtils.assertFileExists(Paths.get(output + "/go.mod"));
TestUtils.assertFileContains(Paths.get(output + "/go.mod"),
"module github.com/my-user/my-repo");
TestUtils.assertFileContains(Paths.get(output + "/go.mod"),
"require github.com/gorilla/mux v1.8.0");
}

@Test
public void verifyOrder() throws IOException {
File output = Files.createTempDirectory("test").toFile();
output.deleteOnExit();

final CodegenConfigurator configurator = createDefaultCodegenConfigurator(output)
.setInputSpec("src/test/resources/3_0/go-server/route-order.yaml");

DefaultGenerator generator = new DefaultGenerator();
List<File> files = generator.opts(configurator.toClientOptInput()).generate();
files.forEach(File::deleteOnExit);

TestUtils.assertFileExists(Paths.get(output + "/go/routers.go"));
TestUtils.assertFileContains(Paths.get(output + "/go/routers.go"),
"type Routes map[string]Route");

TestUtils.assertFileExists(Paths.get(output + "/go/api_dev.go"));
// verify /getPath/latest is first route
Assert.assertEquals(Files.readAllLines(Paths.get(output + "/go/api_dev.go")).get(52), "\t\t\"GetLatest\": Route{");
// verify /getPath/{id} is second route
Assert.assertEquals(Files.readAllLines(Paths.get(output + "/go/api_dev.go")).get(57), "\t\t\"GetById\": Route{");

}

private static CodegenConfigurator createDefaultCodegenConfigurator(File output) {
return new CodegenConfigurator()
.setGeneratorName("go-server")
.setGitUserId("my-user")
.setGitRepoId("my-repo")
.setPackageName("mypackage")
.setOutputDir(output.getAbsolutePath().replace("\\", "/"));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
openapi: 3.0.0

info:
version: 1.0.0
title: Simple no path and body param spec

paths:
/getPath/latest:
get:
tags:
- dev
summary: summary
description: description
operationId: getLatest
responses:
'204':
description: successful operation
/getPath/{id}:
get:
tags:
- dev
summary: summary
description: description
operationId: GetById
parameters:
- name: id
in: path
required: true
schema:
type: string
responses:
'204':
description: successful operation
24 changes: 12 additions & 12 deletions samples/openapi3/server/petstore/go/go-petstore/go/api.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading