Skip to content

Commit

Permalink
Generate API files as interfaces for go-gin server (#17784)
Browse files Browse the repository at this point in the history
* add feature to generate only interface files

* generate sample

* add workflow file foe go gin service

* add workflow file foe go gin service

* add workflow file foe go gin service

* update samples
  • Loading branch information
mfatihercik committed Feb 20, 2024
1 parent 95377cd commit 48565ae
Show file tree
Hide file tree
Showing 24 changed files with 1,559 additions and 20 deletions.
31 changes: 31 additions & 0 deletions .github/workflows/samples-go-gin.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Samples Go

on:
push:
paths:
- 'samples/server/petstore/go-gin-api-server/**'
- 'samples/server/petstore/go-gin-api-server-interface-only/**'
pull_request:
paths:
- 'samples/server/petstore/go-gin-api-server/**'
- 'samples/server/petstore/go-gin-api-server-interface-only/**'

jobs:
build:
name: Build Go
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
sample:
- samples/server/petstore/go-gin-api-server/
- samples/server/petstore/go-gin-api-server-interface-only/
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: "stable"
- run: go version
- name: Run test
working-directory: ${{ matrix.sample }}
run: go test -mod=mod -v
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
generatorName: go-gin-server
outputDir: samples/server/petstore/go-gin-api-server-interface-only
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/go-gin-server
additionalProperties:
hideGenerationTimestamp: "true"
packageName: petstoreserver
interfaceOnly: true
1 change: 1 addition & 0 deletions docs/generators/go-gin-server.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|apiPath|Name of the folder that contains the Go source code| |go|
|enumClassPrefix|Prefix enum with class name| |false|
|hideGenerationTimestamp|Hides the generation timestamp when files are generated.| |true|
|interfaceOnly|Whether to generate only API interface stubs without the implementation files.| |false|
|packageName|Go package name (convention: lowercase).| |openapi|
|packageVersion|Go package version.| |1.0.0|
|serverPort|The network port the generated server binds to| |8080|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ public class GoGinServerCodegen extends AbstractGoCodegen {

private final Logger LOGGER = LoggerFactory.getLogger(GoGinServerCodegen.class);

public static final String INTERFACE_ONLY = "interfaceOnly";

protected boolean interfaceOnly = false;

protected String apiVersion = "1.0.0";
protected int serverPort = 8080;
protected String projectName = "openapi-server";
Expand Down Expand Up @@ -114,6 +118,8 @@ public GoGinServerCodegen() {

cliOptions.add(new CliOption("apiPath", "Name of the folder that contains the Go source code")
.defaultValue(apiPath));
cliOptions.add(CliOption.newBoolean(INTERFACE_ONLY,
"Whether to generate only API interface stubs without the implementation files.", interfaceOnly));

CliOption optServerPort = new CliOption("serverPort", "The network port the generated server binds to");
optServerPort.setType("int");
Expand Down Expand Up @@ -148,6 +154,10 @@ public void processOpts() {
additionalProperties.put(CodegenConstants.PACKAGE_NAME, this.packageName);
}

if (additionalProperties.containsKey(INTERFACE_ONLY)) {
this.setInterfaceOnly(Boolean.parseBoolean(additionalProperties.get(INTERFACE_ONLY).toString()));
}

/*
* Additional Properties. These values can be passed to the templates and
* are available in models, apis, and supporting files
Expand Down Expand Up @@ -180,6 +190,11 @@ public void processOpts() {
modelPackage = packageName;
apiPackage = packageName;

if (interfaceOnly) {
apiTemplateFiles.clear();
apiTemplateFiles.put("interface-api.mustache", ".go");
}

/*
* Supporting Files. You can write single files for the generator with the
* entire object tree available. If the input file has a suffix of `.mustache
Expand All @@ -194,6 +209,10 @@ public void processOpts() {
supportingFiles.add(new SupportingFile("go.mod.mustache", "go.mod"));
}

public void setInterfaceOnly(boolean interfaceOnly) {
this.interfaceOnly = interfaceOnly;
}

@Override
public String apiPackage() {
return apiPath;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{{>partial_header}}
package {{packageName}}

{{#operations}}
import (
"github.com/gin-gonic/gin"
)

type {{classname}} interface {
{{#operation}}
// {{nickname}} {{httpMethod}} {{{basePathWithoutHost}}}{{{path}}}{{#summary}}
// {{{.}}} {{/summary}}
{{#isDeprecated}}
// Deprecated
{{/isDeprecated}}
{{nickname}}(c *gin.Context)

{{/operation}}
{{/operations}}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,16 @@

package org.openapitools.codegen.goginserver;

import org.openapitools.codegen.*;
import org.openapitools.codegen.DefaultGenerator;
import org.openapitools.codegen.TestUtils;
import org.openapitools.codegen.config.CodegenConfigurator;
import org.openapitools.codegen.languages.GoClientCodegen;
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.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


public class GoGinServerCodegenTest {
Expand All @@ -40,13 +36,8 @@ public void verifyGoMod() throws IOException {
File output = Files.createTempDirectory("test").toFile();
output.deleteOnExit();

final CodegenConfigurator configurator = new CodegenConfigurator()
.setGeneratorName("go-gin-server")
.setGitUserId("my-user")
.setGitRepoId("my-repo")
.setPackageName("my-package")
.setInputSpec("src/test/resources/3_0/petstore.yaml")
.setOutputDir(output.getAbsolutePath().replace("\\", "/"));
final CodegenConfigurator configurator = createDefaultCodegenConfigurator(output)
.setInputSpec("src/test/resources/3_0/petstore.yaml");

DefaultGenerator generator = new DefaultGenerator();
List<File> files = generator.opts(configurator.toClientOptInput()).generate();
Expand All @@ -64,13 +55,8 @@ public void webhooks() throws IOException {
File output = Files.createTempDirectory("test").toFile();
output.deleteOnExit();

final CodegenConfigurator configurator = new CodegenConfigurator()
.setGeneratorName("go-gin-server")
.setGitUserId("my-user")
.setGitRepoId("my-repo")
.setPackageName("my-package")
.setInputSpec("src/test/resources/3_1/webhooks.yaml")
.setOutputDir(output.getAbsolutePath().replace("\\", "/"));
final CodegenConfigurator configurator = createDefaultCodegenConfigurator(output)
.setInputSpec("src/test/resources/3_1/webhooks.yaml");

DefaultGenerator generator = new DefaultGenerator();
List<File> files = generator.opts(configurator.toClientOptInput()).generate();
Expand All @@ -82,4 +68,30 @@ public void webhooks() throws IOException {
" c.JSON(200, gin.H{\"status\": \"OK\"})");
}

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

final CodegenConfigurator configurator = createDefaultCodegenConfigurator(output)
.setInputSpec("src/test/resources/3_0/petstore.yaml")
.addAdditionalProperty("interfaceOnly", true);

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

TestUtils.assertFileContains(Paths.get(output + "/go/api_pet.go"),
"type PetAPI interface");
}

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

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# OpenAPI Generator Ignore
# Generated by openapi-generator https://github.com/openapitools/openapi-generator

# Use this file to prevent files from being overwritten by the generator.
# The patterns follow closely to .gitignore or .dockerignore.

# As an example, the C# client generator defines ApiClient.cs.
# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
#ApiClient.cs

# You can match any string of characters against a directory, file or extension with a single asterisk (*):
#foo/*/qux
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux

# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
#foo/**/qux
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux

# You can also negate patterns with an exclamation (!).
# For example, you can ignore all files in a docs folder with the file extension .md:
#docs/*.md
# Then explicitly reverse the ignore rule for a single file:
#!docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
Dockerfile
api/openapi.yaml
go.mod
go/README.md
go/api_pet.go
go/api_store.go
go/api_user.go
go/model_api_response.go
go/model_category.go
go/model_order.go
go/model_pet.go
go/model_tag.go
go/model_user.go
go/routers.go
main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
7.4.0-SNAPSHOT
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
FROM golang:1.19 AS build
WORKDIR /go/src
COPY go ./go
COPY main.go .
COPY go.sum .
COPY go.mod .

ENV CGO_ENABLED=0

RUN go build -o petstoreserver .

FROM scratch AS runtime
ENV GIN_MODE=release
COPY --from=build /go/src/petstoreserver ./
EXPOSE 8080/tcp
ENTRYPOINT ["./petstoreserver"]
Loading

0 comments on commit 48565ae

Please sign in to comment.