From a55453b5f7cd0656d7c031918923f6077df66878 Mon Sep 17 00:00:00 2001 From: Wouter Wijsman Date: Sat, 19 Aug 2023 12:42:58 +0200 Subject: [PATCH] Update go-gin-server templates to return a configurable library (#10479) * Update go-gin-server templates to return a configurable library Before this change, the user would be required to make changes in the generated code. This makes it really hard to update the API and the documentation at the same time. With this change, the generated code can be imported as is and used. The user just needs to set the handler functions for each endpoint. * Use spaces instead of tabs for api files * Use space instead of tab for ApiHandleFunctions in go-gin-server * Update samples for go-gin-server --- .../go-gin-server/controller-api.mustache | 17 +- .../resources/go-gin-server/main.mustache | 4 +- .../resources/go-gin-server/routers.mustache | 54 ++-- .../petstore/go-gin-api-server/go/api_pet.go | 67 ++-- .../go-gin-api-server/go/api_store.go | 33 +- .../petstore/go-gin-api-server/go/api_user.go | 65 ++-- .../petstore/go-gin-api-server/go/routers.go | 303 +++++++++--------- .../server/petstore/go-gin-api-server/main.go | 4 +- 8 files changed, 252 insertions(+), 295 deletions(-) diff --git a/modules/openapi-generator/src/main/resources/go-gin-server/controller-api.mustache b/modules/openapi-generator/src/main/resources/go-gin-server/controller-api.mustache index daad0d7dfff..197da1c3312 100644 --- a/modules/openapi-generator/src/main/resources/go-gin-server/controller-api.mustache +++ b/modules/openapi-generator/src/main/resources/go-gin-server/controller-api.mustache @@ -3,15 +3,16 @@ package {{packageName}} {{#operations}} import ( - "net/http" - "github.com/gin-gonic/gin" -){{#operation}} +) -// {{nickname}} - {{{summary}}} +type {{classname}} struct { +{{#operation}} + // {{httpMethod}} {{{basePathWithoutHost}}}{{{path}}} + // {{{summary}}} {{#isDeprecated}} -// Deprecated + // Deprecated {{/isDeprecated}} -func {{nickname}}(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{}) -}{{/operation}}{{/operations}} + {{nickname}} gin.HandlerFunc +{{/operation}} +}{{/operations}} diff --git a/modules/openapi-generator/src/main/resources/go-gin-server/main.mustache b/modules/openapi-generator/src/main/resources/go-gin-server/main.mustache index 0ad0a71b3e0..837c88e8142 100644 --- a/modules/openapi-generator/src/main/resources/go-gin-server/main.mustache +++ b/modules/openapi-generator/src/main/resources/go-gin-server/main.mustache @@ -11,9 +11,11 @@ import ( ) func main() { + routes := sw.ApiHandleFunctions{} + log.Printf("Server started") - router := sw.NewRouter() + router := sw.NewRouter(routes) log.Fatal(router.Run(":{{serverPort}}")) } diff --git a/modules/openapi-generator/src/main/resources/go-gin-server/routers.mustache b/modules/openapi-generator/src/main/resources/go-gin-server/routers.mustache index c8636474dc9..d99c4429f62 100644 --- a/modules/openapi-generator/src/main/resources/go-gin-server/routers.mustache +++ b/modules/openapi-generator/src/main/resources/go-gin-server/routers.mustache @@ -10,22 +10,22 @@ import ( // Route is the information for every URI. type Route struct { // Name is the name of this Route. - Name string + Name string // Method is the string for the HTTP method. ex) GET, POST etc.. - Method string + Method string // Pattern is the pattern of the URI. - Pattern string + Pattern string // HandlerFunc is the handler function of this route. - HandlerFunc gin.HandlerFunc + HandlerFunc gin.HandlerFunc } -// Routes is the list of the generated Route. -type Routes []Route - // NewRouter returns a new router. -func NewRouter() *gin.Engine { +func NewRouter(handleFunctions ApiHandleFunctions) *gin.Engine { router := gin.Default() - for _, route := range routes { + for _, route := range getRoutes(handleFunctions) { + if route.HandlerFunc == nil { + route.HandlerFunc = DefaultHandleFunc + } switch route.Method { case http.MethodGet: router.GET(route.Pattern, route.HandlerFunc) @@ -43,23 +43,25 @@ func NewRouter() *gin.Engine { return router } -// Index is the index handler. -func Index(c *gin.Context) { - c.String(http.StatusOK, "Hello World!") +// Default handler for not yet implemented routes +func DefaultHandleFunc(c *gin.Context) { + c.String(http.StatusNotImplemented, "501 not implemented") } -var routes = Routes{ - { - "Index", - http.MethodGet, - "{{{basePathWithoutHost}}}/", - Index, - },{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}} - - { - "{{operationId}}", - http.Method{{httpMethod}}, - "{{{basePathWithoutHost}}}{{{path}}}", - {{operationId}}, - },{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}} +type ApiHandleFunctions struct { +{{#apiInfo}}{{#apis}}{{#operations}} + // Routes for the {{classname}} part of the API + {{classname}} {{classname}}{{/operations}}{{/apis}}{{/apiInfo}} +} + +func getRoutes(handleFunctions ApiHandleFunctions) []Route { + return []Route{ + {{#apiInfo}}{{#apis}}{{#operations}}{{#operation}} + { + "{{operationId}}", + http.Method{{httpMethod}}, + "{{{basePathWithoutHost}}}{{{path}}}", + handleFunctions.{{classname}}.{{operationId}}, + },{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}} + } } diff --git a/samples/server/petstore/go-gin-api-server/go/api_pet.go b/samples/server/petstore/go-gin-api-server/go/api_pet.go index 3377d007de8..1bbe82e8f0e 100644 --- a/samples/server/petstore/go-gin-api-server/go/api_pet.go +++ b/samples/server/petstore/go-gin-api-server/go/api_pet.go @@ -10,48 +10,33 @@ package petstoreserver import ( - "net/http" - "github.com/gin-gonic/gin" ) -// AddPet - Add a new pet to the store -func AddPet(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{}) -} - -// DeletePet - Deletes a pet -func DeletePet(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{}) -} - -// FindPetsByStatus - Finds Pets by status -func FindPetsByStatus(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{}) -} - -// FindPetsByTags - Finds Pets by tags -// Deprecated -func FindPetsByTags(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{}) -} - -// GetPetById - Find pet by ID -func GetPetById(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{}) -} - -// UpdatePet - Update an existing pet -func UpdatePet(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{}) -} - -// UpdatePetWithForm - Updates a pet in the store with form data -func UpdatePetWithForm(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{}) -} - -// UploadFile - uploads an image -func UploadFile(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{}) +type PetApi struct { + // Post /v2/pet + // Add a new pet to the store + AddPet gin.HandlerFunc + // Delete /v2/pet/:petId + // Deletes a pet + DeletePet gin.HandlerFunc + // Get /v2/pet/findByStatus + // Finds Pets by status + FindPetsByStatus gin.HandlerFunc + // Get /v2/pet/findByTags + // Finds Pets by tags + // Deprecated + FindPetsByTags gin.HandlerFunc + // Get /v2/pet/:petId + // Find pet by ID + GetPetById gin.HandlerFunc + // Put /v2/pet + // Update an existing pet + UpdatePet gin.HandlerFunc + // Post /v2/pet/:petId + // Updates a pet in the store with form data + UpdatePetWithForm gin.HandlerFunc + // Post /v2/pet/:petId/uploadImage + // uploads an image + UploadFile gin.HandlerFunc } diff --git a/samples/server/petstore/go-gin-api-server/go/api_store.go b/samples/server/petstore/go-gin-api-server/go/api_store.go index 565a2a2336d..9201a2ad9b2 100644 --- a/samples/server/petstore/go-gin-api-server/go/api_store.go +++ b/samples/server/petstore/go-gin-api-server/go/api_store.go @@ -10,27 +10,20 @@ package petstoreserver import ( - "net/http" - "github.com/gin-gonic/gin" ) -// DeleteOrder - Delete purchase order by ID -func DeleteOrder(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{}) -} - -// GetInventory - Returns pet inventories by status -func GetInventory(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{}) -} - -// GetOrderById - Find purchase order by ID -func GetOrderById(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{}) -} - -// PlaceOrder - Place an order for a pet -func PlaceOrder(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{}) +type StoreApi struct { + // Delete /v2/store/order/:orderId + // Delete purchase order by ID + DeleteOrder gin.HandlerFunc + // Get /v2/store/inventory + // Returns pet inventories by status + GetInventory gin.HandlerFunc + // Get /v2/store/order/:orderId + // Find purchase order by ID + GetOrderById gin.HandlerFunc + // Post /v2/store/order + // Place an order for a pet + PlaceOrder gin.HandlerFunc } diff --git a/samples/server/petstore/go-gin-api-server/go/api_user.go b/samples/server/petstore/go-gin-api-server/go/api_user.go index 1e6c5a8ad87..d9e10c614ec 100644 --- a/samples/server/petstore/go-gin-api-server/go/api_user.go +++ b/samples/server/petstore/go-gin-api-server/go/api_user.go @@ -10,47 +10,32 @@ package petstoreserver import ( - "net/http" - "github.com/gin-gonic/gin" ) -// CreateUser - Create user -func CreateUser(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{}) -} - -// CreateUsersWithArrayInput - Creates list of users with given input array -func CreateUsersWithArrayInput(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{}) -} - -// CreateUsersWithListInput - Creates list of users with given input array -func CreateUsersWithListInput(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{}) -} - -// DeleteUser - Delete user -func DeleteUser(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{}) -} - -// GetUserByName - Get user by user name -func GetUserByName(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{}) -} - -// LoginUser - Logs user into the system -func LoginUser(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{}) -} - -// LogoutUser - Logs out current logged in user session -func LogoutUser(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{}) -} - -// UpdateUser - Updated user -func UpdateUser(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{}) +type UserApi struct { + // Post /v2/user + // Create user + CreateUser gin.HandlerFunc + // Post /v2/user/createWithArray + // Creates list of users with given input array + CreateUsersWithArrayInput gin.HandlerFunc + // Post /v2/user/createWithList + // Creates list of users with given input array + CreateUsersWithListInput gin.HandlerFunc + // Delete /v2/user/:username + // Delete user + DeleteUser gin.HandlerFunc + // Get /v2/user/:username + // Get user by user name + GetUserByName gin.HandlerFunc + // Get /v2/user/login + // Logs user into the system + LoginUser gin.HandlerFunc + // Get /v2/user/logout + // Logs out current logged in user session + LogoutUser gin.HandlerFunc + // Put /v2/user/:username + // Updated user + UpdateUser gin.HandlerFunc } diff --git a/samples/server/petstore/go-gin-api-server/go/routers.go b/samples/server/petstore/go-gin-api-server/go/routers.go index d0fbe840a1b..684344a10a4 100644 --- a/samples/server/petstore/go-gin-api-server/go/routers.go +++ b/samples/server/petstore/go-gin-api-server/go/routers.go @@ -18,22 +18,22 @@ import ( // Route is the information for every URI. type Route struct { // Name is the name of this Route. - Name string + Name string // Method is the string for the HTTP method. ex) GET, POST etc.. - Method string + Method string // Pattern is the pattern of the URI. - Pattern string + Pattern string // HandlerFunc is the handler function of this route. - HandlerFunc gin.HandlerFunc + HandlerFunc gin.HandlerFunc } -// Routes is the list of the generated Route. -type Routes []Route - // NewRouter returns a new router. -func NewRouter() *gin.Engine { +func NewRouter(handleFunctions ApiHandleFunctions) *gin.Engine { router := gin.Default() - for _, route := range routes { + for _, route := range getRoutes(handleFunctions) { + if route.HandlerFunc == nil { + route.HandlerFunc = DefaultHandleFunc + } switch route.Method { case http.MethodGet: router.GET(route.Pattern, route.HandlerFunc) @@ -51,156 +51,143 @@ func NewRouter() *gin.Engine { return router } -// Index is the index handler. -func Index(c *gin.Context) { - c.String(http.StatusOK, "Hello World!") +// Default handler for not yet implemented routes +func DefaultHandleFunc(c *gin.Context) { + c.String(http.StatusNotImplemented, "501 not implemented") } -var routes = Routes{ - { - "Index", - http.MethodGet, - "/v2/", - Index, - }, +type ApiHandleFunctions struct { - { - "AddPet", - http.MethodPost, - "/v2/pet", - AddPet, - }, - - { - "DeletePet", - http.MethodDelete, - "/v2/pet/:petId", - DeletePet, - }, - - { - "FindPetsByStatus", - http.MethodGet, - "/v2/pet/findByStatus", - FindPetsByStatus, - }, - - { - "FindPetsByTags", - http.MethodGet, - "/v2/pet/findByTags", - FindPetsByTags, - }, - - { - "GetPetById", - http.MethodGet, - "/v2/pet/:petId", - GetPetById, - }, - - { - "UpdatePet", - http.MethodPut, - "/v2/pet", - UpdatePet, - }, - - { - "UpdatePetWithForm", - http.MethodPost, - "/v2/pet/:petId", - UpdatePetWithForm, - }, - - { - "UploadFile", - http.MethodPost, - "/v2/pet/:petId/uploadImage", - UploadFile, - }, - - { - "DeleteOrder", - http.MethodDelete, - "/v2/store/order/:orderId", - DeleteOrder, - }, - - { - "GetInventory", - http.MethodGet, - "/v2/store/inventory", - GetInventory, - }, - - { - "GetOrderById", - http.MethodGet, - "/v2/store/order/:orderId", - GetOrderById, - }, - - { - "PlaceOrder", - http.MethodPost, - "/v2/store/order", - PlaceOrder, - }, - - { - "CreateUser", - http.MethodPost, - "/v2/user", - CreateUser, - }, - - { - "CreateUsersWithArrayInput", - http.MethodPost, - "/v2/user/createWithArray", - CreateUsersWithArrayInput, - }, - - { - "CreateUsersWithListInput", - http.MethodPost, - "/v2/user/createWithList", - CreateUsersWithListInput, - }, - - { - "DeleteUser", - http.MethodDelete, - "/v2/user/:username", - DeleteUser, - }, - - { - "GetUserByName", - http.MethodGet, - "/v2/user/:username", - GetUserByName, - }, - - { - "LoginUser", - http.MethodGet, - "/v2/user/login", - LoginUser, - }, - - { - "LogoutUser", - http.MethodGet, - "/v2/user/logout", - LogoutUser, - }, - - { - "UpdateUser", - http.MethodPut, - "/v2/user/:username", - UpdateUser, - }, + // Routes for the PetApi part of the API + PetApi PetApi + // Routes for the StoreApi part of the API + StoreApi StoreApi + // Routes for the UserApi part of the API + UserApi UserApi +} + +func getRoutes(handleFunctions ApiHandleFunctions) []Route { + return []Route{ + + { + "AddPet", + http.MethodPost, + "/v2/pet", + handleFunctions.PetApi.AddPet, + }, + { + "DeletePet", + http.MethodDelete, + "/v2/pet/:petId", + handleFunctions.PetApi.DeletePet, + }, + { + "FindPetsByStatus", + http.MethodGet, + "/v2/pet/findByStatus", + handleFunctions.PetApi.FindPetsByStatus, + }, + { + "FindPetsByTags", + http.MethodGet, + "/v2/pet/findByTags", + handleFunctions.PetApi.FindPetsByTags, + }, + { + "GetPetById", + http.MethodGet, + "/v2/pet/:petId", + handleFunctions.PetApi.GetPetById, + }, + { + "UpdatePet", + http.MethodPut, + "/v2/pet", + handleFunctions.PetApi.UpdatePet, + }, + { + "UpdatePetWithForm", + http.MethodPost, + "/v2/pet/:petId", + handleFunctions.PetApi.UpdatePetWithForm, + }, + { + "UploadFile", + http.MethodPost, + "/v2/pet/:petId/uploadImage", + handleFunctions.PetApi.UploadFile, + }, + { + "DeleteOrder", + http.MethodDelete, + "/v2/store/order/:orderId", + handleFunctions.StoreApi.DeleteOrder, + }, + { + "GetInventory", + http.MethodGet, + "/v2/store/inventory", + handleFunctions.StoreApi.GetInventory, + }, + { + "GetOrderById", + http.MethodGet, + "/v2/store/order/:orderId", + handleFunctions.StoreApi.GetOrderById, + }, + { + "PlaceOrder", + http.MethodPost, + "/v2/store/order", + handleFunctions.StoreApi.PlaceOrder, + }, + { + "CreateUser", + http.MethodPost, + "/v2/user", + handleFunctions.UserApi.CreateUser, + }, + { + "CreateUsersWithArrayInput", + http.MethodPost, + "/v2/user/createWithArray", + handleFunctions.UserApi.CreateUsersWithArrayInput, + }, + { + "CreateUsersWithListInput", + http.MethodPost, + "/v2/user/createWithList", + handleFunctions.UserApi.CreateUsersWithListInput, + }, + { + "DeleteUser", + http.MethodDelete, + "/v2/user/:username", + handleFunctions.UserApi.DeleteUser, + }, + { + "GetUserByName", + http.MethodGet, + "/v2/user/:username", + handleFunctions.UserApi.GetUserByName, + }, + { + "LoginUser", + http.MethodGet, + "/v2/user/login", + handleFunctions.UserApi.LoginUser, + }, + { + "LogoutUser", + http.MethodGet, + "/v2/user/logout", + handleFunctions.UserApi.LogoutUser, + }, + { + "UpdateUser", + http.MethodPut, + "/v2/user/:username", + handleFunctions.UserApi.UpdateUser, + }, + } } diff --git a/samples/server/petstore/go-gin-api-server/main.go b/samples/server/petstore/go-gin-api-server/main.go index f1bc1ae09a4..05aee5b9255 100644 --- a/samples/server/petstore/go-gin-api-server/main.go +++ b/samples/server/petstore/go-gin-api-server/main.go @@ -19,9 +19,11 @@ import ( ) func main() { + routes := sw.ApiHandleFunctions{} + log.Printf("Server started") - router := sw.NewRouter() + router := sw.NewRouter(routes) log.Fatal(router.Run(":8080")) }