Skip to content

Commit a34eeae

Browse files
authored
[GO Gin Server] Webhooks support: add missing webhook handlers (#17411)
* Implement postProcessWebhooksWithModels * Implement postProcessWebhooksWithModels * Add missing webhook handlers * Test webhook handler * Generate samples
1 parent b20c8db commit a34eeae

7 files changed

Lines changed: 260 additions & 72 deletions

File tree

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractGoCodegen.java

Lines changed: 100 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,7 @@
2222
import org.apache.commons.io.FilenameUtils;
2323
import org.apache.commons.lang3.StringUtils;
2424
import org.openapitools.codegen.*;
25-
import org.openapitools.codegen.model.ModelMap;
26-
import org.openapitools.codegen.model.ModelsMap;
27-
import org.openapitools.codegen.model.OperationMap;
28-
import org.openapitools.codegen.model.OperationsMap;
25+
import org.openapitools.codegen.model.*;
2926
import org.openapitools.codegen.utils.ModelUtils;
3027
import org.slf4j.Logger;
3128
import org.slf4j.LoggerFactory;
@@ -586,6 +583,105 @@ public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List<Mo
586583
return objs;
587584
}
588585

586+
@Override
587+
public WebhooksMap postProcessWebhooksWithModels(WebhooksMap objs, List<ModelMap> allModels) {
588+
OperationMap objectMap = objs.getWebhooks();
589+
List<CodegenOperation> operations = objectMap.getOperation();
590+
591+
for (CodegenOperation operation : operations) {
592+
// http method verb conversion (e.g. PUT => Put)
593+
operation.httpMethod = camelize(operation.httpMethod.toLowerCase(Locale.ROOT));
594+
}
595+
596+
// remove model imports to avoid error
597+
List<Map<String, String>> imports = objs.getImports();
598+
if (imports == null)
599+
return objs;
600+
601+
Iterator<Map<String, String>> iterator = imports.iterator();
602+
while (iterator.hasNext()) {
603+
String _import = iterator.next().get("import");
604+
if (_import.startsWith(apiPackage()))
605+
iterator.remove();
606+
}
607+
608+
// this will only import "fmt" and "strings" if there are items in pathParams
609+
for (CodegenOperation operation : operations) {
610+
if (operation.pathParams != null && operation.pathParams.size() > 0) {
611+
imports.add(createMapping("import", "strings"));
612+
break; //just need to import once
613+
}
614+
}
615+
616+
boolean addedTimeImport = false;
617+
boolean addedOSImport = false;
618+
boolean addedReflectImport = false;
619+
for (CodegenOperation operation : operations) {
620+
// import "os" if the operation uses files
621+
if (!addedOSImport && "*os.File".equals(operation.returnType)) {
622+
imports.add(createMapping("import", "os"));
623+
addedOSImport = true;
624+
}
625+
for (CodegenParameter param : operation.allParams) {
626+
// import "os" if the operation uses files
627+
if (!addedOSImport && "*os.File".equals(param.dataType)) {
628+
imports.add(createMapping("import", "os"));
629+
addedOSImport = true;
630+
}
631+
632+
// import "time" if the operation has a time parameter.
633+
if (!addedTimeImport && "time.Time".equals(param.dataType)) {
634+
imports.add(createMapping("import", "time"));
635+
addedTimeImport = true;
636+
}
637+
638+
// import "reflect" package if the parameter is collectionFormat=multi
639+
if (!addedReflectImport && param.isCollectionFormatMulti) {
640+
imports.add(createMapping("import", "reflect"));
641+
addedReflectImport = true;
642+
}
643+
644+
// set x-exportParamName
645+
char nameFirstChar = param.paramName.charAt(0);
646+
if (Character.isUpperCase(nameFirstChar)) {
647+
// First char is already uppercase, just use paramName.
648+
param.vendorExtensions.put("x-export-param-name", param.paramName);
649+
} else {
650+
// It's a lowercase first char, let's convert it to uppercase
651+
StringBuilder sb = new StringBuilder(param.paramName);
652+
sb.setCharAt(0, Character.toUpperCase(nameFirstChar));
653+
param.vendorExtensions.put("x-export-param-name", sb.toString());
654+
}
655+
}
656+
657+
setExportParameterName(operation.queryParams);
658+
setExportParameterName(operation.formParams);
659+
setExportParameterName(operation.headerParams);
660+
setExportParameterName(operation.bodyParams);
661+
setExportParameterName(operation.cookieParams);
662+
setExportParameterName(operation.optionalParams);
663+
setExportParameterName(operation.requiredParams);
664+
665+
}
666+
667+
// recursively add import for mapping one type to multiple imports
668+
List<Map<String, String>> recursiveImports = objs.getImports();
669+
if (recursiveImports == null)
670+
return objs;
671+
672+
ListIterator<Map<String, String>> listIterator = imports.listIterator();
673+
while (listIterator.hasNext()) {
674+
String _import = listIterator.next().get("import");
675+
// if the import package happens to be found in the importMapping (key)
676+
// add the corresponding import package to the list
677+
if (importMapping.containsKey(_import)) {
678+
listIterator.add(createMapping("import", importMapping.get(_import)));
679+
}
680+
}
681+
682+
return objs;
683+
}
684+
589685
private void setExportParameterName(List<CodegenParameter> codegenParameters) {
590686
for (CodegenParameter param : codegenParameters) {
591687
char nameFirstChar = param.paramName.charAt(0);

modules/openapi-generator/src/main/resources/go-gin-server/controller-api.mustache

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,18 @@ import (
77
)
88

99
type {{classname}} struct {
10+
}
11+
1012
{{#operation}}
11-
// {{httpMethod}} {{{basePathWithoutHost}}}{{{path}}}
12-
// {{{summary}}}
13+
// {{httpMethod}} {{{basePathWithoutHost}}}{{{path}}}{{#summary}}
14+
// {{{.}}} {{/summary}}
1315
{{#isDeprecated}}
14-
// Deprecated
16+
// Deprecated
1517
{{/isDeprecated}}
16-
{{nickname}} gin.HandlerFunc
18+
func (api *{{classname}}) {{nickname}}(c *gin.Context) {
19+
// Your handler implementation
20+
c.JSON(200, gin.H{"status": "OK"})
21+
}
22+
1723
{{/operation}}
18-
}{{/operations}}
24+
{{/operations}}

modules/openapi-generator/src/main/resources/go-gin-server/routers.mustache

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ func DefaultHandleFunc(c *gin.Context) {
5151
type ApiHandleFunctions struct {
5252
{{#apiInfo}}{{#apis}}{{#operations}}
5353
// Routes for the {{classname}} part of the API
54-
{{classname}} {{classname}}{{/operations}}{{/apis}}{{/apiInfo}}
54+
{{classname}} {{classname}}{{/operations}}{{/apis}}{{/apiInfo}}{{#webhooks}}{{#operations}}
55+
{{classname}} {{classname}}{{/operations}}{{/webhooks}}
5556
}
5657

5758
func getRoutes(handleFunctions ApiHandleFunctions) []Route {

modules/openapi-generator/src/test/java/org/openapitools/codegen/goginserver/GoGinServerCodegenTest.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,12 @@ public void webhooks() throws IOException {
7474

7575
DefaultGenerator generator = new DefaultGenerator();
7676
List<File> files = generator.opts(configurator.toClientOptInput()).generate();
77-
files.forEach(File::deleteOnExit);
77+
//files.forEach(File::deleteOnExit);
7878

7979
TestUtils.assertFileContains(Paths.get(output + "/go/routers.go"),
8080
"NewPetPost");
81+
TestUtils.assertFileContains(Paths.get(output + "/go/api_default.go"),
82+
" c.JSON(200, gin.H{\"status\": \"OK\"})");
8183
}
8284

8385
}

samples/server/petstore/go-gin-api-server/go/api_pet.go

Lines changed: 58 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -14,29 +14,62 @@ import (
1414
)
1515

1616
type PetAPI struct {
17-
// Post /v2/pet
18-
// Add a new pet to the store
19-
AddPet gin.HandlerFunc
20-
// Delete /v2/pet/:petId
21-
// Deletes a pet
22-
DeletePet gin.HandlerFunc
23-
// Get /v2/pet/findByStatus
24-
// Finds Pets by status
25-
FindPetsByStatus gin.HandlerFunc
26-
// Get /v2/pet/findByTags
27-
// Finds Pets by tags
28-
// Deprecated
29-
FindPetsByTags gin.HandlerFunc
30-
// Get /v2/pet/:petId
31-
// Find pet by ID
32-
GetPetById gin.HandlerFunc
33-
// Put /v2/pet
34-
// Update an existing pet
35-
UpdatePet gin.HandlerFunc
36-
// Post /v2/pet/:petId
37-
// Updates a pet in the store with form data
38-
UpdatePetWithForm gin.HandlerFunc
39-
// Post /v2/pet/:petId/uploadImage
40-
// uploads an image
41-
UploadFile gin.HandlerFunc
4217
}
18+
19+
// Post /v2/pet
20+
// Add a new pet to the store
21+
func (api *PetAPI) AddPet(c *gin.Context) {
22+
// Your handler implementation
23+
c.JSON(200, gin.H{"status": "OK"})
24+
}
25+
26+
// Delete /v2/pet/:petId
27+
// Deletes a pet
28+
func (api *PetAPI) DeletePet(c *gin.Context) {
29+
// Your handler implementation
30+
c.JSON(200, gin.H{"status": "OK"})
31+
}
32+
33+
// Get /v2/pet/findByStatus
34+
// Finds Pets by status
35+
func (api *PetAPI) FindPetsByStatus(c *gin.Context) {
36+
// Your handler implementation
37+
c.JSON(200, gin.H{"status": "OK"})
38+
}
39+
40+
// Get /v2/pet/findByTags
41+
// Finds Pets by tags
42+
// Deprecated
43+
func (api *PetAPI) FindPetsByTags(c *gin.Context) {
44+
// Your handler implementation
45+
c.JSON(200, gin.H{"status": "OK"})
46+
}
47+
48+
// Get /v2/pet/:petId
49+
// Find pet by ID
50+
func (api *PetAPI) GetPetById(c *gin.Context) {
51+
// Your handler implementation
52+
c.JSON(200, gin.H{"status": "OK"})
53+
}
54+
55+
// Put /v2/pet
56+
// Update an existing pet
57+
func (api *PetAPI) UpdatePet(c *gin.Context) {
58+
// Your handler implementation
59+
c.JSON(200, gin.H{"status": "OK"})
60+
}
61+
62+
// Post /v2/pet/:petId
63+
// Updates a pet in the store with form data
64+
func (api *PetAPI) UpdatePetWithForm(c *gin.Context) {
65+
// Your handler implementation
66+
c.JSON(200, gin.H{"status": "OK"})
67+
}
68+
69+
// Post /v2/pet/:petId/uploadImage
70+
// uploads an image
71+
func (api *PetAPI) UploadFile(c *gin.Context) {
72+
// Your handler implementation
73+
c.JSON(200, gin.H{"status": "OK"})
74+
}
75+

samples/server/petstore/go-gin-api-server/go/api_store.go

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,33 @@ import (
1414
)
1515

1616
type StoreAPI struct {
17-
// Delete /v2/store/order/:orderId
18-
// Delete purchase order by ID
19-
DeleteOrder gin.HandlerFunc
20-
// Get /v2/store/inventory
21-
// Returns pet inventories by status
22-
GetInventory gin.HandlerFunc
23-
// Get /v2/store/order/:orderId
24-
// Find purchase order by ID
25-
GetOrderById gin.HandlerFunc
26-
// Post /v2/store/order
27-
// Place an order for a pet
28-
PlaceOrder gin.HandlerFunc
2917
}
18+
19+
// Delete /v2/store/order/:orderId
20+
// Delete purchase order by ID
21+
func (api *StoreAPI) DeleteOrder(c *gin.Context) {
22+
// Your handler implementation
23+
c.JSON(200, gin.H{"status": "OK"})
24+
}
25+
26+
// Get /v2/store/inventory
27+
// Returns pet inventories by status
28+
func (api *StoreAPI) GetInventory(c *gin.Context) {
29+
// Your handler implementation
30+
c.JSON(200, gin.H{"status": "OK"})
31+
}
32+
33+
// Get /v2/store/order/:orderId
34+
// Find purchase order by ID
35+
func (api *StoreAPI) GetOrderById(c *gin.Context) {
36+
// Your handler implementation
37+
c.JSON(200, gin.H{"status": "OK"})
38+
}
39+
40+
// Post /v2/store/order
41+
// Place an order for a pet
42+
func (api *StoreAPI) PlaceOrder(c *gin.Context) {
43+
// Your handler implementation
44+
c.JSON(200, gin.H{"status": "OK"})
45+
}
46+

samples/server/petstore/go-gin-api-server/go/api_user.go

Lines changed: 57 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -14,28 +14,61 @@ import (
1414
)
1515

1616
type UserAPI struct {
17-
// Post /v2/user
18-
// Create user
19-
CreateUser gin.HandlerFunc
20-
// Post /v2/user/createWithArray
21-
// Creates list of users with given input array
22-
CreateUsersWithArrayInput gin.HandlerFunc
23-
// Post /v2/user/createWithList
24-
// Creates list of users with given input array
25-
CreateUsersWithListInput gin.HandlerFunc
26-
// Delete /v2/user/:username
27-
// Delete user
28-
DeleteUser gin.HandlerFunc
29-
// Get /v2/user/:username
30-
// Get user by user name
31-
GetUserByName gin.HandlerFunc
32-
// Get /v2/user/login
33-
// Logs user into the system
34-
LoginUser gin.HandlerFunc
35-
// Get /v2/user/logout
36-
// Logs out current logged in user session
37-
LogoutUser gin.HandlerFunc
38-
// Put /v2/user/:username
39-
// Updated user
40-
UpdateUser gin.HandlerFunc
4117
}
18+
19+
// Post /v2/user
20+
// Create user
21+
func (api *UserAPI) CreateUser(c *gin.Context) {
22+
// Your handler implementation
23+
c.JSON(200, gin.H{"status": "OK"})
24+
}
25+
26+
// Post /v2/user/createWithArray
27+
// Creates list of users with given input array
28+
func (api *UserAPI) CreateUsersWithArrayInput(c *gin.Context) {
29+
// Your handler implementation
30+
c.JSON(200, gin.H{"status": "OK"})
31+
}
32+
33+
// Post /v2/user/createWithList
34+
// Creates list of users with given input array
35+
func (api *UserAPI) CreateUsersWithListInput(c *gin.Context) {
36+
// Your handler implementation
37+
c.JSON(200, gin.H{"status": "OK"})
38+
}
39+
40+
// Delete /v2/user/:username
41+
// Delete user
42+
func (api *UserAPI) DeleteUser(c *gin.Context) {
43+
// Your handler implementation
44+
c.JSON(200, gin.H{"status": "OK"})
45+
}
46+
47+
// Get /v2/user/:username
48+
// Get user by user name
49+
func (api *UserAPI) GetUserByName(c *gin.Context) {
50+
// Your handler implementation
51+
c.JSON(200, gin.H{"status": "OK"})
52+
}
53+
54+
// Get /v2/user/login
55+
// Logs user into the system
56+
func (api *UserAPI) LoginUser(c *gin.Context) {
57+
// Your handler implementation
58+
c.JSON(200, gin.H{"status": "OK"})
59+
}
60+
61+
// Get /v2/user/logout
62+
// Logs out current logged in user session
63+
func (api *UserAPI) LogoutUser(c *gin.Context) {
64+
// Your handler implementation
65+
c.JSON(200, gin.H{"status": "OK"})
66+
}
67+
68+
// Put /v2/user/:username
69+
// Updated user
70+
func (api *UserAPI) UpdateUser(c *gin.Context) {
71+
// Your handler implementation
72+
c.JSON(200, gin.H{"status": "OK"})
73+
}
74+

0 commit comments

Comments
 (0)