Add Go echo server codegen (#9224)

* Update codegen config

* Add templates for Go Echo openapi-codegen

* Add the yaml config file!

* Add GoEchoServerCodegen.java.
This is the first iteration, it works but probably needs a lot of improvements.

* Update codegen, adds some comments.

* Update GoEchoServerCodegen.java

* Update GoEchoServerCodegen.java

* Update GoEchoServerCodegen.java and related yaml file

* Add the result of generate-samples.sh for CI purposes.

* Add the result of bin/utils/ensure-up-to-date for CI purposes.

* Update go-echo-server-petstore-new.yaml
Fix the outputdir

* Update in regard to result of ./bin/generate-samples.sh

* Update in regard to result of ./bin/generate-samples.sh

* Remove wrongly generated files

* Add correct generated files.

* Add changes regarding /bin/utils/ensure-up-to-date

* Update templates to include comments.

* Update/add result of ./bin/generate-samples.sh and ./bin/utils/export_docs_generators.sh
This commit is contained in:
Farshad Nematdoust 2021-04-21 10:22:10 +02:00 committed by GitHub
parent 92561085ba
commit 733a180a62
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 1800 additions and 0 deletions

View File

@ -0,0 +1,6 @@
generatorName: go-echo-server
outputDir: samples/server/petstore/go-echo-server
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/go-echo-server
additionalProperties:
hideGenerationTimestamp: "true"

View File

@ -86,6 +86,7 @@ The following generators are available:
* [erlang-server](generators/erlang-server.md)
* [fsharp-functions (beta)](generators/fsharp-functions.md)
* [fsharp-giraffe-server (beta)](generators/fsharp-giraffe-server.md)
* [go-echo-server](generators/go-echo-server.md)
* [go-gin-server](generators/go-gin-server.md)
* [go-server](generators/go-server.md)
* [graphql-nodejs-express-server](generators/graphql-nodejs-express-server.md)

View File

@ -0,0 +1,206 @@
---
title: Config Options for go-echo-server
sidebar_label: go-echo-server
---
These options may be applied as additional-properties (cli) or configOptions (plugins). Refer to [configuration docs](https://openapi-generator.tech/docs/configuration) for more details.
| Option | Description | Values | Default |
| ------ | ----------- | ------ | ------- |
|hideGenerationTimestamp|Hides the generation timestamp when files are generated.| |true|
|packageName|Go package name (convention: lowercase).| |openapi|
|packageVersion|Go package version.| |1.0.0|
|serverPort|The network port the generated server binds to| |8080|
## IMPORT MAPPING
| Type/Alias | Imports |
| ---------- | ------- |
## INSTANTIATION TYPES
| Type/Alias | Instantiated By |
| ---------- | --------------- |
## LANGUAGE PRIMITIVES
<ul class="column-ul">
<li>bool</li>
<li>byte</li>
<li>complex128</li>
<li>complex64</li>
<li>float32</li>
<li>float64</li>
<li>int</li>
<li>int32</li>
<li>int64</li>
<li>interface{}</li>
<li>map[string]interface{}</li>
<li>rune</li>
<li>string</li>
<li>uint</li>
<li>uint32</li>
<li>uint64</li>
</ul>
## RESERVED WORDS
<ul class="column-ul">
<li>bool</li>
<li>break</li>
<li>byte</li>
<li>case</li>
<li>chan</li>
<li>complex128</li>
<li>complex64</li>
<li>const</li>
<li>continue</li>
<li>default</li>
<li>defer</li>
<li>else</li>
<li>error</li>
<li>fallthrough</li>
<li>float32</li>
<li>float64</li>
<li>for</li>
<li>func</li>
<li>go</li>
<li>goto</li>
<li>if</li>
<li>import</li>
<li>int</li>
<li>int16</li>
<li>int32</li>
<li>int64</li>
<li>int8</li>
<li>interface</li>
<li>map</li>
<li>nil</li>
<li>package</li>
<li>range</li>
<li>return</li>
<li>rune</li>
<li>select</li>
<li>string</li>
<li>struct</li>
<li>switch</li>
<li>type</li>
<li>uint</li>
<li>uint16</li>
<li>uint32</li>
<li>uint64</li>
<li>uint8</li>
<li>uintptr</li>
<li>var</li>
</ul>
## FEATURE SET
### Client Modification Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|BasePath|✗|ToolingExtension
|Authorizations|✗|ToolingExtension
|UserAgent|✗|ToolingExtension
|MockServer|✗|ToolingExtension
### Data Type Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|Custom|✗|OAS2,OAS3
|Int32|✓|OAS2,OAS3
|Int64|✓|OAS2,OAS3
|Float|✓|OAS2,OAS3
|Double|✓|OAS2,OAS3
|Decimal|✓|ToolingExtension
|String|✓|OAS2,OAS3
|Byte|✓|OAS2,OAS3
|Binary|✓|OAS2,OAS3
|Boolean|✓|OAS2,OAS3
|Date|✓|OAS2,OAS3
|DateTime|✓|OAS2,OAS3
|Password|✓|OAS2,OAS3
|File|✓|OAS2
|Array|✓|OAS2,OAS3
|Maps|✓|ToolingExtension
|CollectionFormat|✓|OAS2
|CollectionFormatMulti|✓|OAS2
|Enum|✓|OAS2,OAS3
|ArrayOfEnum|✓|ToolingExtension
|ArrayOfModel|✓|ToolingExtension
|ArrayOfCollectionOfPrimitives|✓|ToolingExtension
|ArrayOfCollectionOfModel|✓|ToolingExtension
|ArrayOfCollectionOfEnum|✓|ToolingExtension
|MapOfEnum|✓|ToolingExtension
|MapOfModel|✓|ToolingExtension
|MapOfCollectionOfPrimitives|✓|ToolingExtension
|MapOfCollectionOfModel|✓|ToolingExtension
|MapOfCollectionOfEnum|✓|ToolingExtension
### Documentation Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|Readme|✓|ToolingExtension
|Model|✓|ToolingExtension
|Api|✓|ToolingExtension
### Global Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|Host|✓|OAS2,OAS3
|BasePath|✓|OAS2,OAS3
|Info|✓|OAS2,OAS3
|Schemes|✗|OAS2,OAS3
|PartialSchemes|✓|OAS2,OAS3
|Consumes|✓|OAS2
|Produces|✓|OAS2
|ExternalDocumentation|✓|OAS2,OAS3
|Examples|✓|OAS2,OAS3
|XMLStructureDefinitions|✗|OAS2,OAS3
|MultiServer|✗|OAS3
|ParameterizedServer|✗|OAS3
|ParameterStyling|✗|OAS3
|Callbacks|✗|OAS3
|LinkObjects|✗|OAS3
### Parameter Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|Path|✓|OAS2,OAS3
|Query|✓|OAS2,OAS3
|Header|✓|OAS2,OAS3
|Body|✓|OAS2
|FormUnencoded|✓|OAS2
|FormMultipart|✓|OAS2
|Cookie|✗|OAS3
### Schema Support Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|Simple|✓|OAS2,OAS3
|Composite|✓|OAS2,OAS3
|Polymorphism|✗|OAS2,OAS3
|Union|✗|OAS3
### Security Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|BasicAuth|✗|OAS2,OAS3
|ApiKey|✗|OAS2,OAS3
|OpenIDConnect|✗|OAS3
|BearerToken|✗|OAS3
|OAuth2_Implicit|✗|OAS2,OAS3
|OAuth2_Password|✗|OAS2,OAS3
|OAuth2_ClientCredentials|✗|OAS2,OAS3
|OAuth2_AuthorizationCode|✗|OAS2,OAS3
### Wire Format Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|JSON|✓|OAS2,OAS3
|XML|✓|OAS2,OAS3
|PROTOBUF|✗|ToolingExtension
|Custom|✗|OAS2,OAS3

View File

@ -0,0 +1,162 @@
package org.openapitools.codegen.languages;
import org.openapitools.codegen.*;
import java.io.File;
import java.util.*;
import org.openapitools.codegen.meta.features.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class GoEchoServerCodegen extends AbstractGoCodegen {
static final Logger LOGGER = LoggerFactory.getLogger(GoEchoServerCodegen.class);
protected String apiVersion = "1.0.0";
protected int serverPort = 8080;
protected String projectName = "openapi-go-echo-server";
protected String apiPath = "go";
private static final String MODEL_PACKAGE_NAME = "models";
private static final String API_PACKAGE_NAME = "handlers";
private static final String OUTPUT_PATH = "generated-code" + File.separator + "go-echo-server";
public CodegenType getTag() {
return CodegenType.SERVER;
}
public String getName() {
return "go-echo-server";
}
public String getHelp() {
return "Generates a go-echo server. (Beta)";
}
public GoEchoServerCodegen() {
super();
modifyFeatureSet(features -> features
.includeDocumentationFeatures(DocumentationFeature.Readme)
.wireFormatFeatures(EnumSet.of(WireFormatFeature.JSON, WireFormatFeature.XML))
.securityFeatures(EnumSet.noneOf(
SecurityFeature.class
))
.excludeGlobalFeatures(
GlobalFeature.XMLStructureDefinitions,
GlobalFeature.Callbacks,
GlobalFeature.LinkObjects,
GlobalFeature.ParameterStyling
)
.excludeSchemaSupportFeatures(
SchemaSupportFeature.Polymorphism
)
.excludeParameterFeatures(
ParameterFeature.Cookie
)
);
outputFolder = OUTPUT_PATH;
modelTemplateFiles.put("model.mustache", ".go");
setModelPackage(MODEL_PACKAGE_NAME);
apiTemplateFiles.put("api.mustache", ".go");
embeddedTemplateDir = templateDir = "go-echo-server";
/*
* Reserved words. Override this with reserved words specific to your language
*/
setReservedWordsLowerCase(
Arrays.asList(
// data type
"string", "bool", "uint", "uint8", "uint16", "uint32", "uint64",
"int", "int8", "int16", "int32", "int64", "float32", "float64",
"complex64", "complex128", "rune", "byte", "uintptr",
"break", "default", "func", "interface", "select",
"case", "defer", "go", "map", "struct",
"chan", "else", "goto", "package", "switch",
"const", "fallthrough", "if", "range", "type",
"continue", "for", "import", "return", "var", "error", "nil")
// Added "error" as it's used so frequently that it may as well be a keyword
);
CliOption optServerPort = new CliOption("serverPort", "The network port the generated server binds to");
optServerPort.setType("int");
optServerPort.defaultValue(Integer.toString(serverPort));
cliOptions.add(optServerPort);
}
@Override
public Map<String, Object> postProcessOperationsWithModels(Map<String, Object> objs, List<Object> allModels) {
objs = super.postProcessOperationsWithModels(objs, allModels);
Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
List<CodegenOperation> operationList = (List<CodegenOperation>) operations.get("operation");
for (CodegenOperation op : operationList) {
if (op.path != null) {
op.path = op.path.replaceAll("\\{(.*?)\\}", ":$1");
}
}
return objs;
}
@Override
public void processOpts() {
super.processOpts();
if (additionalProperties.containsKey(CodegenConstants.PACKAGE_NAME)) {
setPackageName((String) additionalProperties.get(CodegenConstants.PACKAGE_NAME));
} else {
setPackageName("openapi");
additionalProperties.put(CodegenConstants.PACKAGE_NAME, this.packageName);
}
/*
* Additional Properties. These values can be passed to the templates and
* are available in models, apis, and supporting files
*/
if (additionalProperties.containsKey("apiVersion")) {
this.apiVersion = (String) additionalProperties.get("apiVersion");
} else {
additionalProperties.put("apiVersion", apiVersion);
}
if (additionalProperties.containsKey("serverPort")) {
this.serverPort = Integer.parseInt((String) additionalProperties.get("serverPort"));
} else {
additionalProperties.put("serverPort", serverPort);
}
if (additionalProperties.containsKey("apiPath")) {
this.apiPath = (String) additionalProperties.get("apiPath");
} else {
additionalProperties.put("apiPath", apiPath);
}
if (additionalProperties.containsKey(CodegenConstants.ENUM_CLASS_PREFIX)) {
setEnumClassPrefix(Boolean.parseBoolean(additionalProperties.get(CodegenConstants.ENUM_CLASS_PREFIX).toString()));
if (enumClassPrefix) {
additionalProperties.put(CodegenConstants.ENUM_CLASS_PREFIX, true);
}
}
/*
set model and package names, this is mainly used inside the templates.
*/
modelPackage = MODEL_PACKAGE_NAME;
apiPackage = API_PACKAGE_NAME;
/*
* 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
* it will be processed by the template engine. Otherwise, it will be copied
*/
supportingFiles.add(new SupportingFile("openapi.mustache", ".docs/api", "openapi.yaml"));
supportingFiles.add(new SupportingFile("hello-world.mustache", "models", "hello-world.go"));
supportingFiles.add(new SupportingFile("go-mod.mustache", "", "go.mod"));
supportingFiles.add(new SupportingFile("handler-container.mustache", "handlers", "container.go"));
supportingFiles.add(new SupportingFile("main.mustache", "", "main.go"));
supportingFiles.add(new SupportingFile("Dockerfile.mustache", "", "Dockerfile"));
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md")
.doNotOverwrite());
}
}

View File

@ -131,3 +131,4 @@ org.openapitools.codegen.languages.TypeScriptNestjsClientCodegen
org.openapitools.codegen.languages.TypeScriptNodeClientCodegen
org.openapitools.codegen.languages.TypeScriptReduxQueryClientCodegen
org.openapitools.codegen.languages.TypeScriptRxjsClientCodegen
org.openapitools.codegen.languages.GoEchoServerCodegen

View File

@ -0,0 +1,11 @@
FROM golang:1.16-alpine3.13 as build-env
RUN apk add --no-cache git gcc
RUN mkdir /app
WORKDIR /app
COPY . .
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o {{packageName}}
FROM alpine:3.13
COPY --from=build-env /app/{{packageName}} .
EXPOSE 8080/tcp
USER 1001
ENTRYPOINT ["./{{packageName}}"]

View File

@ -0,0 +1,44 @@
# Go Echo API Server for {{packageName}}
{{#appDescriptionWithNewLines}}
{{{appDescriptionWithNewLines}}}
{{/appDescriptionWithNewLines}}
## Overview
This server was generated by the [openapi-generator]
(https://openapi-generator.tech) project.
By using the [OpenAPI-Spec](https://github.com/OAI/OpenAPI-Specification) from a remote server, you can easily generate a server stub.
-
To see how to make this your own, look here:
[README](https://openapi-generator.tech)
- API version: {{appVersion}}{{^hideGenerationTimestamp}}
- Build date: {{generatedDate}}{{/hideGenerationTimestamp}}
{{#infoUrl}}
For more information, please visit [{{{infoUrl}}}]({{{infoUrl}}})
{{/infoUrl}}
### Running the server
To run the server, follow these simple steps:
```
go mod download
go build -o app
```
To run the server in a docker container
```
docker build --network=host -t {{{packageName}}} .
```
Once the image is built, just run
```
docker run --rm -it {{{packageName}}}
```
### Known Issue
TBA

View File

@ -0,0 +1,15 @@
package handlers
{{#operations}}
import (
"github.com/{{{gitUserId}}}/{{{gitRepoId}}}/models"
"github.com/labstack/echo/v4"
"net/http"
){{#operation}}
// {{nickname}} - {{{summary}}}
func (c *Container) {{operationId}}(ctx echo.Context) error {
return ctx.JSON(http.StatusOK, models.HelloWorld {
Message: "Hello World",
})
}
{{/operation}}{{/operations}}

View File

@ -0,0 +1,5 @@
module github.com/{{{gitUserId}}}/{{{gitRepoId}}}
go 1.16
require github.com/labstack/echo/v4 v4.2.0

View File

@ -0,0 +1,11 @@
package handlers
// Container will hold all dependencies for your application.
type Container struct {
}
// NewContainer returns an empty or an initialized container for your handlers.
func NewContainer() (Container, error) {
c := Container{}
return c, nil
}

View File

@ -0,0 +1,6 @@
package models
// HelloWorld is a sample data structure to make sure each endpoint return something.
type HelloWorld struct {
Message string `json:"message"`
}

View File

@ -0,0 +1,26 @@
package main
import (
"github.com/{{{gitUserId}}}/{{{gitRepoId}}}/handlers"
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
)
func main() {
e := echo.New()
//todo: handle the error!
c, _ := handlers.NewContainer()
// Middleware
e.Use(middleware.Logger())
e.Use(middleware.Recover())
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}
// {{nickname}} - {{{summary}}}
e.{{httpMethod.toUpperCase}}("{{{basePathWithoutHost}}}{{{path}}}", c.{{operationId}})
{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
// Start server
e.Logger.Fatal(e.Start(":{{serverPort}}"))
}

View File

@ -0,0 +1,23 @@
package models
{{#models}}{{#imports}}
{{#-first}}import (
{{/-first}} "{{import}}"{{#-last}}
)
{{/-last}}{{/imports}}{{#model}}{{#isEnum}}{{#description}}// {{{classname}}} : {{{description}}}{{/description}}
type {{{classname}}} {{^format}}{{dataType}}{{/format}}{{#format}}{{{format}}}{{/format}}
// List of {{{classname}}}
const (
{{#allowableValues}}
{{#enumVars}}
{{#enumClassPrefix}}{{{classname.toUpperCase}}}_{{/enumClassPrefix}}{{name}} {{{classname}}} = {{{value}}}
{{/enumVars}}
{{/allowableValues}}
){{/isEnum}}{{^isEnum}}{{#description}}
// {{classname}} - {{{description}}}{{/description}}
type {{classname}} struct {
{{#vars}}{{#description}}
// {{{description}}}{{/description}}
{{name}} {{#isNullable}}*{{/isNullable}}{{{dataType}}} `json:"{{baseName}}{{^required}},omitempty{{/required}}"{{#vendorExtensions.x-go-custom-tag}} {{{.}}}{{/vendorExtensions.x-go-custom-tag}}`
{{/vars}}
}{{/isEnum}}{{/model}}{{/models}}

View File

@ -0,0 +1 @@
{{{openapi-yaml}}}

View File

@ -0,0 +1,822 @@
openapi: 3.0.0
info:
description: This is a sample server Petstore server. For this sample, you can use
the api key `special-key` to test the authorization filters.
license:
name: Apache-2.0
url: https://www.apache.org/licenses/LICENSE-2.0.html
title: OpenAPI Petstore
version: 1.0.0
externalDocs:
description: Find out more about Swagger
url: http://swagger.io
servers:
- url: http://petstore.swagger.io/v2
tags:
- description: Everything about your Pets
name: pet
- description: Access to Petstore orders
name: store
- description: Operations about user
name: user
paths:
/pet:
post:
operationId: addPet
requestBody:
$ref: '#/components/requestBodies/Pet'
responses:
"200":
content:
application/xml:
schema:
$ref: '#/components/schemas/Pet'
application/json:
schema:
$ref: '#/components/schemas/Pet'
description: successful operation
"405":
description: Invalid input
security:
- petstore_auth:
- write:pets
- read:pets
summary: Add a new pet to the store
tags:
- pet
put:
operationId: updatePet
requestBody:
$ref: '#/components/requestBodies/Pet'
responses:
"200":
content:
application/xml:
schema:
$ref: '#/components/schemas/Pet'
application/json:
schema:
$ref: '#/components/schemas/Pet'
description: successful operation
"400":
description: Invalid ID supplied
"404":
description: Pet not found
"405":
description: Validation exception
security:
- petstore_auth:
- write:pets
- read:pets
summary: Update an existing pet
tags:
- pet
/pet/findByStatus:
get:
description: Multiple status values can be provided with comma separated strings
operationId: findPetsByStatus
parameters:
- description: Status values that need to be considered for filter
explode: false
in: query
name: status
required: true
schema:
items:
default: available
enum:
- available
- pending
- sold
type: string
type: array
style: form
responses:
"200":
content:
application/xml:
schema:
items:
$ref: '#/components/schemas/Pet'
type: array
application/json:
schema:
items:
$ref: '#/components/schemas/Pet'
type: array
description: successful operation
"400":
description: Invalid status value
security:
- petstore_auth:
- read:pets
summary: Finds Pets by status
tags:
- pet
/pet/findByTags:
get:
deprecated: true
description: Multiple tags can be provided with comma separated strings. Use
tag1, tag2, tag3 for testing.
operationId: findPetsByTags
parameters:
- description: Tags to filter by
explode: false
in: query
name: tags
required: true
schema:
items:
type: string
type: array
style: form
responses:
"200":
content:
application/xml:
schema:
items:
$ref: '#/components/schemas/Pet'
type: array
application/json:
schema:
items:
$ref: '#/components/schemas/Pet'
type: array
description: successful operation
"400":
description: Invalid tag value
security:
- petstore_auth:
- read:pets
summary: Finds Pets by tags
tags:
- pet
/pet/{petId}:
delete:
operationId: deletePet
parameters:
- explode: false
in: header
name: api_key
required: false
schema:
type: string
style: simple
- description: Pet id to delete
explode: false
in: path
name: petId
required: true
schema:
format: int64
type: integer
style: simple
responses:
"400":
description: Invalid pet value
security:
- petstore_auth:
- write:pets
- read:pets
summary: Deletes a pet
tags:
- pet
get:
description: Returns a single pet
operationId: getPetById
parameters:
- description: ID of pet to return
explode: false
in: path
name: petId
required: true
schema:
format: int64
type: integer
style: simple
responses:
"200":
content:
application/xml:
schema:
$ref: '#/components/schemas/Pet'
application/json:
schema:
$ref: '#/components/schemas/Pet'
description: successful operation
"400":
description: Invalid ID supplied
"404":
description: Pet not found
security:
- api_key: []
summary: Find pet by ID
tags:
- pet
post:
operationId: updatePetWithForm
parameters:
- description: ID of pet that needs to be updated
explode: false
in: path
name: petId
required: true
schema:
format: int64
type: integer
style: simple
requestBody:
$ref: '#/components/requestBodies/inline_object'
content:
application/x-www-form-urlencoded:
schema:
properties:
name:
description: Updated name of the pet
type: string
status:
description: Updated status of the pet
type: string
type: object
responses:
"405":
description: Invalid input
security:
- petstore_auth:
- write:pets
- read:pets
summary: Updates a pet in the store with form data
tags:
- pet
/pet/{petId}/uploadImage:
post:
operationId: uploadFile
parameters:
- description: ID of pet to update
explode: false
in: path
name: petId
required: true
schema:
format: int64
type: integer
style: simple
requestBody:
$ref: '#/components/requestBodies/inline_object_1'
content:
multipart/form-data:
schema:
properties:
additionalMetadata:
description: Additional data to pass to server
type: string
file:
description: file to upload
format: binary
type: string
type: object
responses:
"200":
content:
application/json:
schema:
$ref: '#/components/schemas/ApiResponse'
description: successful operation
security:
- petstore_auth:
- write:pets
- read:pets
summary: uploads an image
tags:
- pet
/store/inventory:
get:
description: Returns a map of status codes to quantities
operationId: getInventory
responses:
"200":
content:
application/json:
schema:
additionalProperties:
format: int32
type: integer
type: object
description: successful operation
security:
- api_key: []
summary: Returns pet inventories by status
tags:
- store
/store/order:
post:
operationId: placeOrder
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Order'
description: order placed for purchasing the pet
required: true
responses:
"200":
content:
application/xml:
schema:
$ref: '#/components/schemas/Order'
application/json:
schema:
$ref: '#/components/schemas/Order'
description: successful operation
"400":
description: Invalid Order
summary: Place an order for a pet
tags:
- store
/store/order/{orderId}:
delete:
description: For valid response try integer IDs with value < 1000. Anything
above 1000 or nonintegers will generate API errors
operationId: deleteOrder
parameters:
- description: ID of the order that needs to be deleted
explode: false
in: path
name: orderId
required: true
schema:
type: string
style: simple
responses:
"400":
description: Invalid ID supplied
"404":
description: Order not found
summary: Delete purchase order by ID
tags:
- store
get:
description: For valid response try integer IDs with value <= 5 or > 10. Other
values will generated exceptions
operationId: getOrderById
parameters:
- description: ID of pet that needs to be fetched
explode: false
in: path
name: orderId
required: true
schema:
format: int64
maximum: 5
minimum: 1
type: integer
style: simple
responses:
"200":
content:
application/xml:
schema:
$ref: '#/components/schemas/Order'
application/json:
schema:
$ref: '#/components/schemas/Order'
description: successful operation
"400":
description: Invalid ID supplied
"404":
description: Order not found
summary: Find purchase order by ID
tags:
- store
/user:
post:
description: This can only be done by the logged in user.
operationId: createUser
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/User'
description: Created user object
required: true
responses:
default:
description: successful operation
security:
- api_key: []
summary: Create user
tags:
- user
/user/createWithArray:
post:
operationId: createUsersWithArrayInput
requestBody:
$ref: '#/components/requestBodies/UserArray'
responses:
default:
description: successful operation
security:
- api_key: []
summary: Creates list of users with given input array
tags:
- user
/user/createWithList:
post:
operationId: createUsersWithListInput
requestBody:
$ref: '#/components/requestBodies/UserArray'
responses:
default:
description: successful operation
security:
- api_key: []
summary: Creates list of users with given input array
tags:
- user
/user/login:
get:
operationId: loginUser
parameters:
- description: The user name for login
explode: true
in: query
name: username
required: true
schema:
pattern: ^[a-zA-Z0-9]+[a-zA-Z0-9\.\-_]*[a-zA-Z0-9]+$
type: string
style: form
- description: The password for login in clear text
explode: true
in: query
name: password
required: true
schema:
type: string
style: form
responses:
"200":
content:
application/xml:
schema:
type: string
application/json:
schema:
type: string
description: successful operation
headers:
Set-Cookie:
description: Cookie authentication key for use with the `api_key` apiKey
authentication.
explode: false
schema:
example: AUTH_KEY=abcde12345; Path=/; HttpOnly
type: string
style: simple
X-Rate-Limit:
description: calls per hour allowed by the user
explode: false
schema:
format: int32
type: integer
style: simple
X-Expires-After:
description: date in UTC when toekn expires
explode: false
schema:
format: date-time
type: string
style: simple
"400":
description: Invalid username/password supplied
summary: Logs user into the system
tags:
- user
/user/logout:
get:
operationId: logoutUser
responses:
default:
description: successful operation
security:
- api_key: []
summary: Logs out current logged in user session
tags:
- user
/user/{username}:
delete:
description: This can only be done by the logged in user.
operationId: deleteUser
parameters:
- description: The name that needs to be deleted
explode: false
in: path
name: username
required: true
schema:
type: string
style: simple
responses:
"400":
description: Invalid username supplied
"404":
description: User not found
security:
- api_key: []
summary: Delete user
tags:
- user
get:
operationId: getUserByName
parameters:
- description: The name that needs to be fetched. Use user1 for testing.
explode: false
in: path
name: username
required: true
schema:
type: string
style: simple
responses:
"200":
content:
application/xml:
schema:
$ref: '#/components/schemas/User'
application/json:
schema:
$ref: '#/components/schemas/User'
description: successful operation
"400":
description: Invalid username supplied
"404":
description: User not found
summary: Get user by user name
tags:
- user
put:
description: This can only be done by the logged in user.
operationId: updateUser
parameters:
- description: name that need to be deleted
explode: false
in: path
name: username
required: true
schema:
type: string
style: simple
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/User'
description: Updated user object
required: true
responses:
"400":
description: Invalid user supplied
"404":
description: User not found
security:
- api_key: []
summary: Updated user
tags:
- user
components:
requestBodies:
UserArray:
content:
application/json:
schema:
items:
$ref: '#/components/schemas/User'
type: array
description: List of user object
required: true
Pet:
content:
application/json:
schema:
$ref: '#/components/schemas/Pet'
application/xml:
schema:
$ref: '#/components/schemas/Pet'
description: Pet object that needs to be added to the store
required: true
inline_object:
content:
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/inline_object'
inline_object_1:
content:
multipart/form-data:
schema:
$ref: '#/components/schemas/inline_object_1'
schemas:
Order:
description: An order for a pets from the pet store
example:
petId: 6
quantity: 1
id: 0
shipDate: 2000-01-23T04:56:07.000+00:00
complete: false
status: placed
properties:
id:
format: int64
type: integer
petId:
format: int64
type: integer
quantity:
format: int32
type: integer
shipDate:
format: date-time
type: string
status:
description: Order Status
enum:
- placed
- approved
- delivered
type: string
complete:
default: false
type: boolean
title: Pet Order
type: object
xml:
name: Order
Category:
description: A category for a pet
example:
name: name
id: 6
properties:
id:
format: int64
type: integer
name:
pattern: ^[a-zA-Z0-9]+[a-zA-Z0-9\.\-_]*[a-zA-Z0-9]+$
type: string
title: Pet category
type: object
xml:
name: Category
User:
description: A User who is purchasing from the pet store
example:
firstName: firstName
lastName: lastName
password: password
userStatus: 6
phone: phone
id: 0
email: email
username: username
properties:
id:
format: int64
type: integer
username:
type: string
firstName:
type: string
lastName:
type: string
email:
type: string
password:
type: string
phone:
type: string
userStatus:
description: User Status
format: int32
type: integer
title: a User
type: object
xml:
name: User
Tag:
description: A tag for a pet
example:
name: name
id: 1
properties:
id:
format: int64
type: integer
name:
type: string
title: Pet Tag
type: object
xml:
name: Tag
Pet:
description: A pet for sale in the pet store
example:
photoUrls:
- photoUrls
- photoUrls
name: doggie
id: 0
category:
name: name
id: 6
tags:
- name: name
id: 1
- name: name
id: 1
status: available
properties:
id:
format: int64
type: integer
category:
$ref: '#/components/schemas/Category'
name:
example: doggie
type: string
photoUrls:
items:
type: string
type: array
xml:
name: photoUrl
wrapped: true
tags:
items:
$ref: '#/components/schemas/Tag'
type: array
xml:
name: tag
wrapped: true
status:
description: pet status in the store
enum:
- available
- pending
- sold
type: string
required:
- name
- photoUrls
title: a Pet
type: object
xml:
name: Pet
ApiResponse:
description: Describes the result of uploading an image resource
example:
code: 0
type: type
message: message
properties:
code:
format: int32
type: integer
type:
type: string
message:
type: string
title: An uploaded response
type: object
inline_object:
properties:
name:
description: Updated name of the pet
type: string
status:
description: Updated status of the pet
type: string
type: object
inline_object_1:
properties:
additionalMetadata:
description: Additional data to pass to server
type: string
file:
description: file to upload
format: binary
type: string
type: object
securitySchemes:
petstore_auth:
flows:
implicit:
authorizationUrl: http://petstore.swagger.io/api/oauth/dialog
scopes:
write:pets: modify pets in your account
read:pets: read your pets
type: oauth2
api_key:
in: header
name: api_key
type: apiKey

View File

@ -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

View File

@ -0,0 +1,16 @@
.docs/api/openapi.yaml
Dockerfile
README.md
go.mod
handlers/api_pet.go
handlers/api_store.go
handlers/api_user.go
handlers/container.go
main.go
models/hello-world.go
models/model_api_response.go
models/model_category.go
models/model_order.go
models/model_pet.go
models/model_tag.go
models/model_user.go

View File

@ -0,0 +1 @@
5.1.1-SNAPSHOT

View File

@ -0,0 +1,11 @@
FROM golang:1.16-alpine3.13 as build-env
RUN apk add --no-cache git gcc
RUN mkdir /app
WORKDIR /app
COPY . .
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o openapi
FROM alpine:3.13
COPY --from=build-env /app/openapi .
EXPOSE 8080/tcp
USER 1001
ENTRYPOINT ["./openapi"]

View File

@ -0,0 +1,38 @@
# Go Echo API Server for openapi
This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
## Overview
This server was generated by the [openapi-generator]
(https://openapi-generator.tech) project.
By using the [OpenAPI-Spec](https://github.com/OAI/OpenAPI-Specification) from a remote server, you can easily generate a server stub.
-
To see how to make this your own, look here:
[README](https://openapi-generator.tech)
- API version: 1.0.0
### Running the server
To run the server, follow these simple steps:
```
go mod download
go build -o app
```
To run the server in a docker container
```
docker build --network=host -t openapi .
```
Once the image is built, just run
```
docker run --rm -it openapi
```
### Known Issue
TBA

View File

@ -0,0 +1,5 @@
module github.com/GIT_USER_ID/GIT_REPO_ID
go 1.16
require github.com/labstack/echo/v4 v4.2.0

View File

@ -0,0 +1,69 @@
package handlers
import (
"github.com/GIT_USER_ID/GIT_REPO_ID/models"
"github.com/labstack/echo/v4"
"net/http"
)
// AddPet - Add a new pet to the store
func (c *Container) AddPet(ctx echo.Context) error {
return ctx.JSON(http.StatusOK, models.HelloWorld {
Message: "Hello World",
})
}
// DeletePet - Deletes a pet
func (c *Container) DeletePet(ctx echo.Context) error {
return ctx.JSON(http.StatusOK, models.HelloWorld {
Message: "Hello World",
})
}
// FindPetsByStatus - Finds Pets by status
func (c *Container) FindPetsByStatus(ctx echo.Context) error {
return ctx.JSON(http.StatusOK, models.HelloWorld {
Message: "Hello World",
})
}
// FindPetsByTags - Finds Pets by tags
func (c *Container) FindPetsByTags(ctx echo.Context) error {
return ctx.JSON(http.StatusOK, models.HelloWorld {
Message: "Hello World",
})
}
// GetPetById - Find pet by ID
func (c *Container) GetPetById(ctx echo.Context) error {
return ctx.JSON(http.StatusOK, models.HelloWorld {
Message: "Hello World",
})
}
// UpdatePet - Update an existing pet
func (c *Container) UpdatePet(ctx echo.Context) error {
return ctx.JSON(http.StatusOK, models.HelloWorld {
Message: "Hello World",
})
}
// UpdatePetWithForm - Updates a pet in the store with form data
func (c *Container) UpdatePetWithForm(ctx echo.Context) error {
return ctx.JSON(http.StatusOK, models.HelloWorld {
Message: "Hello World",
})
}
// UploadFile - uploads an image
func (c *Container) UploadFile(ctx echo.Context) error {
return ctx.JSON(http.StatusOK, models.HelloWorld {
Message: "Hello World",
})
}

View File

@ -0,0 +1,37 @@
package handlers
import (
"github.com/GIT_USER_ID/GIT_REPO_ID/models"
"github.com/labstack/echo/v4"
"net/http"
)
// DeleteOrder - Delete purchase order by ID
func (c *Container) DeleteOrder(ctx echo.Context) error {
return ctx.JSON(http.StatusOK, models.HelloWorld {
Message: "Hello World",
})
}
// GetInventory - Returns pet inventories by status
func (c *Container) GetInventory(ctx echo.Context) error {
return ctx.JSON(http.StatusOK, models.HelloWorld {
Message: "Hello World",
})
}
// GetOrderById - Find purchase order by ID
func (c *Container) GetOrderById(ctx echo.Context) error {
return ctx.JSON(http.StatusOK, models.HelloWorld {
Message: "Hello World",
})
}
// PlaceOrder - Place an order for a pet
func (c *Container) PlaceOrder(ctx echo.Context) error {
return ctx.JSON(http.StatusOK, models.HelloWorld {
Message: "Hello World",
})
}

View File

@ -0,0 +1,69 @@
package handlers
import (
"github.com/GIT_USER_ID/GIT_REPO_ID/models"
"github.com/labstack/echo/v4"
"net/http"
)
// CreateUser - Create user
func (c *Container) CreateUser(ctx echo.Context) error {
return ctx.JSON(http.StatusOK, models.HelloWorld {
Message: "Hello World",
})
}
// CreateUsersWithArrayInput - Creates list of users with given input array
func (c *Container) CreateUsersWithArrayInput(ctx echo.Context) error {
return ctx.JSON(http.StatusOK, models.HelloWorld {
Message: "Hello World",
})
}
// CreateUsersWithListInput - Creates list of users with given input array
func (c *Container) CreateUsersWithListInput(ctx echo.Context) error {
return ctx.JSON(http.StatusOK, models.HelloWorld {
Message: "Hello World",
})
}
// DeleteUser - Delete user
func (c *Container) DeleteUser(ctx echo.Context) error {
return ctx.JSON(http.StatusOK, models.HelloWorld {
Message: "Hello World",
})
}
// GetUserByName - Get user by user name
func (c *Container) GetUserByName(ctx echo.Context) error {
return ctx.JSON(http.StatusOK, models.HelloWorld {
Message: "Hello World",
})
}
// LoginUser - Logs user into the system
func (c *Container) LoginUser(ctx echo.Context) error {
return ctx.JSON(http.StatusOK, models.HelloWorld {
Message: "Hello World",
})
}
// LogoutUser - Logs out current logged in user session
func (c *Container) LogoutUser(ctx echo.Context) error {
return ctx.JSON(http.StatusOK, models.HelloWorld {
Message: "Hello World",
})
}
// UpdateUser - Updated user
func (c *Container) UpdateUser(ctx echo.Context) error {
return ctx.JSON(http.StatusOK, models.HelloWorld {
Message: "Hello World",
})
}

View File

@ -0,0 +1,11 @@
package handlers
// Container will hold all dependencies for your application.
type Container struct {
}
// NewContainer returns an empty or an initialized container for your handlers.
func NewContainer() (Container, error) {
c := Container{}
return c, nil
}

View File

@ -0,0 +1,83 @@
package main
import (
"github.com/GIT_USER_ID/GIT_REPO_ID/handlers"
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
)
func main() {
e := echo.New()
//todo: handle the error!
c, _ := handlers.NewContainer()
// Middleware
e.Use(middleware.Logger())
e.Use(middleware.Recover())
// AddPet - Add a new pet to the store
e.POST("/v2/pet", c.AddPet)
// DeletePet - Deletes a pet
e.DELETE("/v2/pet/:petId", c.DeletePet)
// FindPetsByStatus - Finds Pets by status
e.GET("/v2/pet/findByStatus", c.FindPetsByStatus)
// FindPetsByTags - Finds Pets by tags
e.GET("/v2/pet/findByTags", c.FindPetsByTags)
// GetPetById - Find pet by ID
e.GET("/v2/pet/:petId", c.GetPetById)
// UpdatePet - Update an existing pet
e.PUT("/v2/pet", c.UpdatePet)
// UpdatePetWithForm - Updates a pet in the store with form data
e.POST("/v2/pet/:petId", c.UpdatePetWithForm)
// UploadFile - uploads an image
e.POST("/v2/pet/:petId/uploadImage", c.UploadFile)
// DeleteOrder - Delete purchase order by ID
e.DELETE("/v2/store/order/:orderId", c.DeleteOrder)
// GetInventory - Returns pet inventories by status
e.GET("/v2/store/inventory", c.GetInventory)
// GetOrderById - Find purchase order by ID
e.GET("/v2/store/order/:orderId", c.GetOrderById)
// PlaceOrder - Place an order for a pet
e.POST("/v2/store/order", c.PlaceOrder)
// CreateUser - Create user
e.POST("/v2/user", c.CreateUser)
// CreateUsersWithArrayInput - Creates list of users with given input array
e.POST("/v2/user/createWithArray", c.CreateUsersWithArrayInput)
// CreateUsersWithListInput - Creates list of users with given input array
e.POST("/v2/user/createWithList", c.CreateUsersWithListInput)
// DeleteUser - Delete user
e.DELETE("/v2/user/:username", c.DeleteUser)
// GetUserByName - Get user by user name
e.GET("/v2/user/:username", c.GetUserByName)
// LoginUser - Logs user into the system
e.GET("/v2/user/login", c.LoginUser)
// LogoutUser - Logs out current logged in user session
e.GET("/v2/user/logout", c.LogoutUser)
// UpdateUser - Updated user
e.PUT("/v2/user/:username", c.UpdateUser)
// Start server
e.Logger.Fatal(e.Start(":8080"))
}

View File

@ -0,0 +1,6 @@
package models
// HelloWorld is a sample data structure to make sure each endpoint return something.
type HelloWorld struct {
Message string `json:"message"`
}

View File

@ -0,0 +1,11 @@
package models
// ApiResponse - Describes the result of uploading an image resource
type ApiResponse struct {
Code int32 `json:"code,omitempty"`
Type string `json:"type,omitempty"`
Message string `json:"message,omitempty"`
}

View File

@ -0,0 +1,9 @@
package models
// Category - A category for a pet
type Category struct {
Id int64 `json:"id,omitempty"`
Name string `json:"name,omitempty"`
}

View File

@ -0,0 +1,22 @@
package models
import (
"time"
)
// Order - An order for a pets from the pet store
type Order struct {
Id int64 `json:"id,omitempty"`
PetId int64 `json:"petId,omitempty"`
Quantity int32 `json:"quantity,omitempty"`
ShipDate time.Time `json:"shipDate,omitempty"`
// Order Status
Status string `json:"status,omitempty"`
Complete bool `json:"complete,omitempty"`
}

View File

@ -0,0 +1,18 @@
package models
// Pet - A pet for sale in the pet store
type Pet struct {
Id int64 `json:"id,omitempty"`
Category Category `json:"category,omitempty"`
Name string `json:"name"`
PhotoUrls []string `json:"photoUrls"`
Tags []Tag `json:"tags,omitempty"`
// pet status in the store
Status string `json:"status,omitempty"`
}

View File

@ -0,0 +1,9 @@
package models
// Tag - A tag for a pet
type Tag struct {
Id int64 `json:"id,omitempty"`
Name string `json:"name,omitempty"`
}

View File

@ -0,0 +1,22 @@
package models
// User - A User who is purchasing from the pet store
type User struct {
Id int64 `json:"id,omitempty"`
Username string `json:"username,omitempty"`
FirstName string `json:"firstName,omitempty"`
LastName string `json:"lastName,omitempty"`
Email string `json:"email,omitempty"`
Password string `json:"password,omitempty"`
Phone string `json:"phone,omitempty"`
// User Status
UserStatus int32 `json:"userStatus,omitempty"`
}