diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractGoCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractGoCodegen.java index e45bc2ef3fead472987d93f2146509b036f72c7d..cee83d467c845818164f7e5c5dd0f3c3727dd6fd 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractGoCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractGoCodegen.java @@ -311,16 +311,17 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege @Override public String toApiFilename(String name) { + final String apiName; // replace - with _ e.g. created-at => created_at - name = name.replaceAll("-", "_"); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'. - + String api = name.replaceAll("-", "_"); // e.g. PetApi.go => pet_api.go - name = "api_" + underscore(name); - if (isReservedFilename(name)) { - LOGGER.warn(name + ".go with suffix (reserved word) cannot be used as filename. Renamed to " + name + "_.go"); - name += "_"; + api = "api_" + underscore(api); + if (isReservedFilename(api)) { + LOGGER.warn(name + ".go with suffix (reserved word) cannot be used as filename. Renamed to " + api + "_.go"); + api += "_"; } - return name; + apiName = api; + return apiName; } /** @@ -807,7 +808,7 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege return; // skip if GO_POST_PROCESS_FILE env variable is not defined } - // only procees the following type (or we can simply rely on the file extension to check if it's a Go file) + // only process the following type (or we can simply rely on the file extension to check if it's a Go file) Set<String> supportedFileType = new HashSet<String>( Arrays.asList( "supporting-mustache", diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/GoServerCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/GoServerCodegen.java index df37293a02faa611492a707cd2c619ffa785799d..a0f76b8c2997e7b87964855dd2446eeff60730eb 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/GoServerCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/GoServerCodegen.java @@ -235,10 +235,8 @@ public class GoServerCodegen extends AbstractGoCodegen { // override imports to only include packages for interface parameters imports.clear(); - boolean addedOptionalImport = false; boolean addedTimeImport = false; boolean addedOSImport = false; - boolean addedReflectImport = false; for (CodegenOperation operation : operations) { for (CodegenParameter param : operation.allParams) { // import "os" if the operation uses files @@ -247,7 +245,7 @@ public class GoServerCodegen extends AbstractGoCodegen { addedOSImport = true; } - // import "time" if the operation has a required time parameter. + // import "time" if the operation has a required time parameter if (param.required) { if (!addedTimeImport && "time.Time".equals(param.dataType)) { imports.add(createMapping("import", "time")); diff --git a/modules/openapi-generator/src/main/resources/go-server/controller-api.mustache b/modules/openapi-generator/src/main/resources/go-server/controller-api.mustache index d177852270cde099ce5eac0de03ae57ce89e8772..2c6b5da8b524aabc1d658c25eec8f3dc1bc9e801 100644 --- a/modules/openapi-generator/src/main/resources/go-server/controller-api.mustache +++ b/modules/openapi-generator/src/main/resources/go-server/controller-api.mustache @@ -16,7 +16,7 @@ type {{classname}}Controller struct { // New{{classname}}Controller creates a default api controller func New{{classname}}Controller(s {{classname}}Servicer) Router { - return &{{classname}}Controller{ service: s } + return &{{classname}}Controller{service: s} } // Routes returns all of the api route for the {{classname}}Controller @@ -34,11 +34,18 @@ func (c *{{classname}}Controller) Routes() Routes { // {{nickname}} - {{{summary}}} func (c *{{classname}}Controller) {{nickname}}(w http.ResponseWriter, r *http.Request) { {{#hasFormParams}} - err := r.ParseForm() - if err != nil { + {{#isMultipart}} + if err := r.ParseMultipartForm(32 << 20); err != nil { + w.WriteHeader(http.StatusBadRequest) + return + } + {{/isMultipart}} + {{^isMultipart}} + if err := r.ParseForm(); err != nil { w.WriteHeader(http.StatusBadRequest) return } + {{/isMultipart}} {{/hasFormParams}} {{#hasPathParams}} params := mux.Vars(r) @@ -49,14 +56,14 @@ func (c *{{classname}}Controller) {{nickname}}(w http.ResponseWriter, r *http.Re {{#allParams}} {{#isPathParam}} {{#isLong}} - {{paramName}}, err := parseInt64Parameter(params["{{baseName}}"]) + {{paramName}}, err := parseInt64Parameter(params["{{baseName}}"], {{required}}) if err != nil { w.WriteHeader(http.StatusBadRequest) return } - {{/isLong}} + {{/isLong}} {{#isInteger}} - {{paramName}}, err := parseInt32Parameter(params["{{baseName}}"]) + {{paramName}}, err := parseInt32Parameter(params["{{baseName}}"], {{required}}) if err != nil { w.WriteHeader(http.StatusBadRequest) return @@ -69,14 +76,14 @@ func (c *{{classname}}Controller) {{nickname}}(w http.ResponseWriter, r *http.Re {{/isPathParam}} {{#isQueryParam}} {{#isLong}} - {{paramName}}, err := parseInt64Parameter(query.Get("{{baseName}}")) + {{paramName}}, err := parseInt64Parameter(query.Get("{{baseName}}"), {{required}}) if err != nil { w.WriteHeader(http.StatusBadRequest) return } {{/isLong}} {{#isInteger}} - {{paramName}}, err := parseInt32Parameter(query.Get("{{baseName}}")) + {{paramName}}, err := parseInt32Parameter(query.Get("{{baseName}}"), {{required}}) if err != nil { w.WriteHeader(http.StatusBadRequest) return @@ -98,24 +105,26 @@ func (c *{{classname}}Controller) {{nickname}}(w http.ResponseWriter, r *http.Re {{/isLong}} {{/isQueryParam}} {{#isFormParam}} - {{#isFile}} - {{#isArray}} - {{paramName}}, err := ReadFormFilesToTempFiles(r, "{{baseName}}"){{/isArray}}{{^isArray}}{{paramName}}, err := ReadFormFileToTempFile(r, "{{baseName}}") + {{#isFile}}{{#isArray}} + {{paramName}}, err := ReadFormFilesToTempFiles(r, "{{baseName}}"){{/isArray}}{{^isArray}} + {{paramName}}, err := ReadFormFileToTempFile(r, "{{baseName}}") {{/isArray}} if err != nil { w.WriteHeader(http.StatusBadRequest) return } {{/isFile}} - {{#isLong}} - {{paramName}}, err := parseInt64Parameter( r.FormValue("{{baseName}}")) + {{#isLong}}{{#isArray}} + {{paramName}}, err := parseInt64ArrayParameter(r.FormValue("{{baseName}}"), ",", {{required}}){{/isArray}}{{^isArray}} + {{paramName}}, err := parseInt64Parameter(r.FormValue("{{baseName}}"), {{required}}){{/isArray}} if err != nil { w.WriteHeader(http.StatusBadRequest) return } {{/isLong}} - {{#isInteger}} - {{paramName}}, err := parseInt32Parameter( r.FormValue("{{baseName}}")) + {{#isInteger}}{{#isArray}} + {{paramName}}, err := parseInt32ArrayParameter(r.FormValue("{{baseName}}"), ",", {{required}}){{/isArray}}{{^isArray}} + {{paramName}}, err := parseInt32Parameter(r.FormValue("{{baseName}}"), {{required}}){{/isArray}} if err != nil { w.WriteHeader(http.StatusBadRequest) return @@ -139,12 +148,12 @@ func (c *{{classname}}Controller) {{nickname}}(w http.ResponseWriter, r *http.Re {{/isBodyParam}} {{/allParams}} result, err := c.service.{{nickname}}(r.Context(){{#allParams}}, {{#isBodyParam}}*{{/isBodyParam}}{{paramName}}{{/allParams}}) - //If an error occured, encode the error with the status code + // If an error occurred, encode the error with the status code if err != nil { EncodeJSONResponse(err.Error(), &result.Code,{{#addResponseHeaders}} result.Headers,{{/addResponseHeaders}} w) return } - //If no error, encode the body and the result code + // If no error, encode the body and the result code EncodeJSONResponse(result.Body, &result.Code,{{#addResponseHeaders}} result.Headers,{{/addResponseHeaders}} w) - + }{{/operation}}{{/operations}} diff --git a/modules/openapi-generator/src/main/resources/go-server/routers.mustache b/modules/openapi-generator/src/main/resources/go-server/routers.mustache index c5d580b290b37577e5ac59da8d0528e7a1fdcd7a..d76397166c694d595c583f93fa5b22336b334060 100644 --- a/modules/openapi-generator/src/main/resources/go-server/routers.mustache +++ b/modules/openapi-generator/src/main/resources/go-server/routers.mustache @@ -3,22 +3,24 @@ package {{packageName}} import ( "encoding/json" + "errors" + "github.com/gorilla/mux" + {{#featureCORS}} + "github.com/gorilla/handlers" + {{/featureCORS}} "io/ioutil" "mime/multipart" "net/http" "os" "strconv" - {{#featureCORS}} - "github.com/gorilla/handlers" - {{/featureCORS}} - "github.com/gorilla/mux" + "strings" ) // A Route defines the parameters for an api endpoint type Route struct { - Name string - Method string - Pattern string + Name string + Method string + Pattern string HandlerFunc http.HandlerFunc } @@ -30,6 +32,8 @@ type Router interface { Routes() Routes } +const errMsgRequiredMissing = "required parameter is missing" + // NewRouter creates a new router for any number of api routers func NewRouter(routers ...Router) *mux.Router { router := mux.NewRouter().StrictSlash(true) @@ -134,17 +138,34 @@ func readFileHeaderToTempFile(fileHeader *multipart.FileHeader) (*os.File, error return file, nil } -// parseInt64Parameter parses a string parameter to an int64 -func parseInt64Parameter(param string) (int64, error) { +// parseInt64Parameter parses a string parameter to an int64. +func parseInt64Parameter(param string, required bool) (int64, error) { + if param == "" { + if required { + return 0, errors.New(errMsgRequiredMissing) + } + + return 0, nil + } + return strconv.ParseInt(param, 10, 64) } -// parseInt32Parameter parses a string parameter to an int32 -func parseInt32Parameter(param string) (int32, error) { +// parseInt32Parameter parses a string parameter to an int32. +func parseInt32Parameter(param string, required bool) (int32, error) { + if param == "" { + if required { + return 0, errors.New(errMsgRequiredMissing) + } + + return 0, nil + } + val, err := strconv.ParseInt(param, 10, 32) if err != nil { return -1, err } + return int32(val), nil } @@ -154,5 +175,54 @@ func parseBoolParameter(param string) (bool, error) { if err != nil { return false, err } + return bool(val), nil } + +// parseInt64ArrayParameter parses a string parameter containing array of values to []int64. +func parseInt64ArrayParameter(param, delim string, required bool) ([]int64, error) { + if param == "" { + if required { + return nil, errors.New(errMsgRequiredMissing) + } + + return nil, nil + } + + str := strings.Split(param, delim) + ints := make([]int64, len(str)) + + for i, s := range str { + if v, err := strconv.ParseInt(s, 10, 64); err != nil { + return nil, err + } else { + ints[i] = v + } + } + + return ints, nil +} + +// parseInt32ArrayParameter parses a string parameter containing array of values to []int32. +func parseInt32ArrayParameter(param, delim string, required bool) ([]int32, error) { + if param == "" { + if required { + return nil, errors.New(errMsgRequiredMissing) + } + + return nil, nil + } + + str := strings.Split(param, delim) + ints := make([]int32, len(str)) + + for i, s := range str { + if v, err := strconv.ParseInt(s, 10, 32); err != nil { + return nil, err + } else { + ints[i] = int32(v) + } + } + + return ints, nil +} \ No newline at end of file diff --git a/samples/server/petstore/go-api-server/go/api_pet.go b/samples/server/petstore/go-api-server/go/api_pet.go index a33c3909267304c18556694d2faa95fd093d8f95..cc38d894e67c685a6495519d9f6dd72957678778 100644 --- a/samples/server/petstore/go-api-server/go/api_pet.go +++ b/samples/server/petstore/go-api-server/go/api_pet.go @@ -24,7 +24,7 @@ type PetApiController struct { // NewPetApiController creates a default api controller func NewPetApiController(s PetApiServicer) Router { - return &PetApiController{ service: s } + return &PetApiController{service: s} } // Routes returns all of the api route for the PetApiController @@ -89,20 +89,20 @@ func (c *PetApiController) AddPet(w http.ResponseWriter, r *http.Request) { return } result, err := c.service.AddPet(r.Context(), *pet) - //If an error occured, encode the error with the status code + // If an error occurred, encode the error with the status code if err != nil { EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w) return } - //If no error, encode the body and the result code + // If no error, encode the body and the result code EncodeJSONResponse(result.Body, &result.Code, result.Headers, w) - + } // DeletePet - Deletes a pet func (c *PetApiController) DeletePet(w http.ResponseWriter, r *http.Request) { params := mux.Vars(r) - petId, err := parseInt64Parameter(params["petId"]) + petId, err := parseInt64Parameter(params["petId"], true) if err != nil { w.WriteHeader(http.StatusBadRequest) return @@ -110,14 +110,14 @@ func (c *PetApiController) DeletePet(w http.ResponseWriter, r *http.Request) { apiKey := r.Header.Get("api_key") result, err := c.service.DeletePet(r.Context(), petId, apiKey) - //If an error occured, encode the error with the status code + // If an error occurred, encode the error with the status code if err != nil { EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w) return } - //If no error, encode the body and the result code + // If no error, encode the body and the result code EncodeJSONResponse(result.Body, &result.Code, result.Headers, w) - + } // FindPetsByStatus - Finds Pets by status @@ -125,14 +125,14 @@ func (c *PetApiController) FindPetsByStatus(w http.ResponseWriter, r *http.Reque query := r.URL.Query() status := strings.Split(query.Get("status"), ",") result, err := c.service.FindPetsByStatus(r.Context(), status) - //If an error occured, encode the error with the status code + // If an error occurred, encode the error with the status code if err != nil { EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w) return } - //If no error, encode the body and the result code + // If no error, encode the body and the result code EncodeJSONResponse(result.Body, &result.Code, result.Headers, w) - + } // FindPetsByTags - Finds Pets by tags @@ -140,34 +140,34 @@ func (c *PetApiController) FindPetsByTags(w http.ResponseWriter, r *http.Request query := r.URL.Query() tags := strings.Split(query.Get("tags"), ",") result, err := c.service.FindPetsByTags(r.Context(), tags) - //If an error occured, encode the error with the status code + // If an error occurred, encode the error with the status code if err != nil { EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w) return } - //If no error, encode the body and the result code + // If no error, encode the body and the result code EncodeJSONResponse(result.Body, &result.Code, result.Headers, w) - + } // GetPetById - Find pet by ID func (c *PetApiController) GetPetById(w http.ResponseWriter, r *http.Request) { params := mux.Vars(r) - petId, err := parseInt64Parameter(params["petId"]) + petId, err := parseInt64Parameter(params["petId"], true) if err != nil { w.WriteHeader(http.StatusBadRequest) return } result, err := c.service.GetPetById(r.Context(), petId) - //If an error occured, encode the error with the status code + // If an error occurred, encode the error with the status code if err != nil { EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w) return } - //If no error, encode the body and the result code + // If no error, encode the body and the result code EncodeJSONResponse(result.Body, &result.Code, result.Headers, w) - + } // UpdatePet - Update an existing pet @@ -178,70 +178,69 @@ func (c *PetApiController) UpdatePet(w http.ResponseWriter, r *http.Request) { return } result, err := c.service.UpdatePet(r.Context(), *pet) - //If an error occured, encode the error with the status code + // If an error occurred, encode the error with the status code if err != nil { EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w) return } - //If no error, encode the body and the result code + // If no error, encode the body and the result code EncodeJSONResponse(result.Body, &result.Code, result.Headers, w) - + } // UpdatePetWithForm - Updates a pet in the store with form data func (c *PetApiController) UpdatePetWithForm(w http.ResponseWriter, r *http.Request) { - err := r.ParseForm() - if err != nil { + if err := r.ParseForm(); err != nil { w.WriteHeader(http.StatusBadRequest) return } params := mux.Vars(r) - petId, err := parseInt64Parameter(params["petId"]) + petId, err := parseInt64Parameter(params["petId"], true) if err != nil { w.WriteHeader(http.StatusBadRequest) return } - name := r.FormValue("name") - status := r.FormValue("status") + name := r.FormValue("name") + status := r.FormValue("status") result, err := c.service.UpdatePetWithForm(r.Context(), petId, name, status) - //If an error occured, encode the error with the status code + // If an error occurred, encode the error with the status code if err != nil { EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w) return } - //If no error, encode the body and the result code + // If no error, encode the body and the result code EncodeJSONResponse(result.Body, &result.Code, result.Headers, w) - + } // UploadFile - uploads an image func (c *PetApiController) UploadFile(w http.ResponseWriter, r *http.Request) { - err := r.ParseForm() - if err != nil { + if err := r.ParseMultipartForm(32 << 20); err != nil { w.WriteHeader(http.StatusBadRequest) return } params := mux.Vars(r) - petId, err := parseInt64Parameter(params["petId"]) + petId, err := parseInt64Parameter(params["petId"], true) if err != nil { w.WriteHeader(http.StatusBadRequest) return } - additionalMetadata := r.FormValue("additionalMetadata") -file, err := ReadFormFileToTempFile(r, "file") + additionalMetadata := r.FormValue("additionalMetadata") + + file, err := ReadFormFileToTempFile(r, "file") if err != nil { w.WriteHeader(http.StatusBadRequest) return } - result, err := c.service.UploadFile(r.Context(), petId, additionalMetadata, file) - //If an error occured, encode the error with the status code + result, err := c.service.UploadFile(r.Context(), petId, additionalMetadata, file) + // If an error occurred, encode the error with the status code if err != nil { EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w) return } - //If no error, encode the body and the result code + // If no error, encode the body and the result code EncodeJSONResponse(result.Body, &result.Code, result.Headers, w) - + } diff --git a/samples/server/petstore/go-api-server/go/api_store.go b/samples/server/petstore/go-api-server/go/api_store.go index f58d80790beb2f80389be6640460d60f57aab684..05df99f8bf3e771e791e9612a35cb4d685266a28 100644 --- a/samples/server/petstore/go-api-server/go/api_store.go +++ b/samples/server/petstore/go-api-server/go/api_store.go @@ -24,7 +24,7 @@ type StoreApiController struct { // NewStoreApiController creates a default api controller func NewStoreApiController(s StoreApiServicer) Router { - return &StoreApiController{ service: s } + return &StoreApiController{service: s} } // Routes returns all of the api route for the StoreApiController @@ -63,47 +63,47 @@ func (c *StoreApiController) DeleteOrder(w http.ResponseWriter, r *http.Request) orderId := params["orderId"] result, err := c.service.DeleteOrder(r.Context(), orderId) - //If an error occured, encode the error with the status code + // If an error occurred, encode the error with the status code if err != nil { EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w) return } - //If no error, encode the body and the result code + // If no error, encode the body and the result code EncodeJSONResponse(result.Body, &result.Code, result.Headers, w) - + } // GetInventory - Returns pet inventories by status func (c *StoreApiController) GetInventory(w http.ResponseWriter, r *http.Request) { result, err := c.service.GetInventory(r.Context()) - //If an error occured, encode the error with the status code + // If an error occurred, encode the error with the status code if err != nil { EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w) return } - //If no error, encode the body and the result code + // If no error, encode the body and the result code EncodeJSONResponse(result.Body, &result.Code, result.Headers, w) - + } // GetOrderById - Find purchase order by ID func (c *StoreApiController) GetOrderById(w http.ResponseWriter, r *http.Request) { params := mux.Vars(r) - orderId, err := parseInt64Parameter(params["orderId"]) + orderId, err := parseInt64Parameter(params["orderId"], true) if err != nil { w.WriteHeader(http.StatusBadRequest) return } result, err := c.service.GetOrderById(r.Context(), orderId) - //If an error occured, encode the error with the status code + // If an error occurred, encode the error with the status code if err != nil { EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w) return } - //If no error, encode the body and the result code + // If no error, encode the body and the result code EncodeJSONResponse(result.Body, &result.Code, result.Headers, w) - + } // PlaceOrder - Place an order for a pet @@ -114,12 +114,12 @@ func (c *StoreApiController) PlaceOrder(w http.ResponseWriter, r *http.Request) return } result, err := c.service.PlaceOrder(r.Context(), *order) - //If an error occured, encode the error with the status code + // If an error occurred, encode the error with the status code if err != nil { EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w) return } - //If no error, encode the body and the result code + // If no error, encode the body and the result code EncodeJSONResponse(result.Body, &result.Code, result.Headers, w) - + } diff --git a/samples/server/petstore/go-api-server/go/api_user.go b/samples/server/petstore/go-api-server/go/api_user.go index c52badcbb2a3307796124f3fa751bc55a3871f10..9b89014ddbcd583cbf78fbbc1451059e4966976e 100644 --- a/samples/server/petstore/go-api-server/go/api_user.go +++ b/samples/server/petstore/go-api-server/go/api_user.go @@ -24,7 +24,7 @@ type UserApiController struct { // NewUserApiController creates a default api controller func NewUserApiController(s UserApiServicer) Router { - return &UserApiController{ service: s } + return &UserApiController{service: s} } // Routes returns all of the api route for the UserApiController @@ -89,14 +89,14 @@ func (c *UserApiController) CreateUser(w http.ResponseWriter, r *http.Request) { return } result, err := c.service.CreateUser(r.Context(), *user) - //If an error occured, encode the error with the status code + // If an error occurred, encode the error with the status code if err != nil { EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w) return } - //If no error, encode the body and the result code + // If no error, encode the body and the result code EncodeJSONResponse(result.Body, &result.Code, result.Headers, w) - + } // CreateUsersWithArrayInput - Creates list of users with given input array @@ -107,14 +107,14 @@ func (c *UserApiController) CreateUsersWithArrayInput(w http.ResponseWriter, r * return } result, err := c.service.CreateUsersWithArrayInput(r.Context(), *user) - //If an error occured, encode the error with the status code + // If an error occurred, encode the error with the status code if err != nil { EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w) return } - //If no error, encode the body and the result code + // If no error, encode the body and the result code EncodeJSONResponse(result.Body, &result.Code, result.Headers, w) - + } // CreateUsersWithListInput - Creates list of users with given input array @@ -125,14 +125,14 @@ func (c *UserApiController) CreateUsersWithListInput(w http.ResponseWriter, r *h return } result, err := c.service.CreateUsersWithListInput(r.Context(), *user) - //If an error occured, encode the error with the status code + // If an error occurred, encode the error with the status code if err != nil { EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w) return } - //If no error, encode the body and the result code + // If no error, encode the body and the result code EncodeJSONResponse(result.Body, &result.Code, result.Headers, w) - + } // DeleteUser - Delete user @@ -141,14 +141,14 @@ func (c *UserApiController) DeleteUser(w http.ResponseWriter, r *http.Request) { username := params["username"] result, err := c.service.DeleteUser(r.Context(), username) - //If an error occured, encode the error with the status code + // If an error occurred, encode the error with the status code if err != nil { EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w) return } - //If no error, encode the body and the result code + // If no error, encode the body and the result code EncodeJSONResponse(result.Body, &result.Code, result.Headers, w) - + } // GetUserByName - Get user by user name @@ -157,14 +157,14 @@ func (c *UserApiController) GetUserByName(w http.ResponseWriter, r *http.Request username := params["username"] result, err := c.service.GetUserByName(r.Context(), username) - //If an error occured, encode the error with the status code + // If an error occurred, encode the error with the status code if err != nil { EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w) return } - //If no error, encode the body and the result code + // If no error, encode the body and the result code EncodeJSONResponse(result.Body, &result.Code, result.Headers, w) - + } // LoginUser - Logs user into the system @@ -173,27 +173,27 @@ func (c *UserApiController) LoginUser(w http.ResponseWriter, r *http.Request) { username := query.Get("username") password := query.Get("password") result, err := c.service.LoginUser(r.Context(), username, password) - //If an error occured, encode the error with the status code + // If an error occurred, encode the error with the status code if err != nil { EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w) return } - //If no error, encode the body and the result code + // If no error, encode the body and the result code EncodeJSONResponse(result.Body, &result.Code, result.Headers, w) - + } // LogoutUser - Logs out current logged in user session func (c *UserApiController) LogoutUser(w http.ResponseWriter, r *http.Request) { result, err := c.service.LogoutUser(r.Context()) - //If an error occured, encode the error with the status code + // If an error occurred, encode the error with the status code if err != nil { EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w) return } - //If no error, encode the body and the result code + // If no error, encode the body and the result code EncodeJSONResponse(result.Body, &result.Code, result.Headers, w) - + } // UpdateUser - Updated user @@ -207,12 +207,12 @@ func (c *UserApiController) UpdateUser(w http.ResponseWriter, r *http.Request) { return } result, err := c.service.UpdateUser(r.Context(), username, *user) - //If an error occured, encode the error with the status code + // If an error occurred, encode the error with the status code if err != nil { EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w) return } - //If no error, encode the body and the result code + // If no error, encode the body and the result code EncodeJSONResponse(result.Body, &result.Code, result.Headers, w) - + } diff --git a/samples/server/petstore/go-api-server/go/routers.go b/samples/server/petstore/go-api-server/go/routers.go index b41e17558433b588a979b4c922c4bd044d8cbff9..7f41207fbde5b92aea034f8b575f6a6fbe3626f8 100644 --- a/samples/server/petstore/go-api-server/go/routers.go +++ b/samples/server/petstore/go-api-server/go/routers.go @@ -11,19 +11,21 @@ package petstoreserver import ( "encoding/json" + "errors" + "github.com/gorilla/mux" "io/ioutil" "mime/multipart" "net/http" "os" "strconv" - "github.com/gorilla/mux" + "strings" ) // A Route defines the parameters for an api endpoint type Route struct { - Name string - Method string - Pattern string + Name string + Method string + Pattern string HandlerFunc http.HandlerFunc } @@ -35,6 +37,8 @@ type Router interface { Routes() Routes } +const errMsgRequiredMissing = "required parameter is missing" + // NewRouter creates a new router for any number of api routers func NewRouter(routers ...Router) *mux.Router { router := mux.NewRouter().StrictSlash(true) @@ -123,17 +127,34 @@ func readFileHeaderToTempFile(fileHeader *multipart.FileHeader) (*os.File, error return file, nil } -// parseInt64Parameter parses a string parameter to an int64 -func parseInt64Parameter(param string) (int64, error) { +// parseInt64Parameter parses a string parameter to an int64. +func parseInt64Parameter(param string, required bool) (int64, error) { + if param == "" { + if required { + return 0, errors.New(errMsgRequiredMissing) + } + + return 0, nil + } + return strconv.ParseInt(param, 10, 64) } -// parseInt32Parameter parses a string parameter to an int32 -func parseInt32Parameter(param string) (int32, error) { +// parseInt32Parameter parses a string parameter to an int32. +func parseInt32Parameter(param string, required bool) (int32, error) { + if param == "" { + if required { + return 0, errors.New(errMsgRequiredMissing) + } + + return 0, nil + } + val, err := strconv.ParseInt(param, 10, 32) if err != nil { return -1, err } + return int32(val), nil } @@ -143,5 +164,54 @@ func parseBoolParameter(param string) (bool, error) { if err != nil { return false, err } + return bool(val), nil } + +// parseInt64ArrayParameter parses a string parameter containing array of values to []int64. +func parseInt64ArrayParameter(param, delim string, required bool) ([]int64, error) { + if param == "" { + if required { + return nil, errors.New(errMsgRequiredMissing) + } + + return nil, nil + } + + str := strings.Split(param, delim) + ints := make([]int64, len(str)) + + for i, s := range str { + if v, err := strconv.ParseInt(s, 10, 64); err != nil { + return nil, err + } else { + ints[i] = v + } + } + + return ints, nil +} + +// parseInt32ArrayParameter parses a string parameter containing array of values to []int32. +func parseInt32ArrayParameter(param, delim string, required bool) ([]int32, error) { + if param == "" { + if required { + return nil, errors.New(errMsgRequiredMissing) + } + + return nil, nil + } + + str := strings.Split(param, delim) + ints := make([]int32, len(str)) + + for i, s := range str { + if v, err := strconv.ParseInt(s, 10, 32); err != nil { + return nil, err + } else { + ints[i] = int32(v) + } + } + + return ints, nil +} \ No newline at end of file