[go-server] Feat: add required assertions to models (#10068)

* Add RequiredError

* Add IsZeroValue helper

* Add AssertRequired method to all models

* Add AssertRequired call for body param

* Regenerate files

* Add DisallowUnknownFields

* Regenerate samples

* Use hasRequired in model to remove unnecessary code

* Revert disallowUnknownFields

* Use isAdditionalPropertiesTrue for disallowing unknown fields

* Updated samples

* Fix indent

* Add require checks for nested slices

* Add new tests

* Regenerate samples

* Regenerate samples after merging
This commit is contained in:
Ween Jiann 2021-08-07 21:29:14 +08:00 committed by GitHub
parent 189b44b191
commit 11d29eb22b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
56 changed files with 4441 additions and 52 deletions

View File

@ -0,0 +1,9 @@
generatorName: go-server
outputDir: samples/server/petstore/go-server-required
inputSpec: modules/openapi-generator/src/test/resources/3_0/server-required.yaml
templateDir: modules/openapi-generator/src/main/resources/go-server
additionalProperties:
hideGenerationTimestamp: "true"
packageName: petstoreserver
addResponseHeaders: true
router: "chi"

View File

@ -174,14 +174,36 @@ func (c *{{classname}}Controller) {{nickname}}(w http.ResponseWriter, r *http.Re
{{paramName}} := r.Header.Get("{{baseName}}")
{{/isHeaderParam}}
{{#isBodyParam}}
{{paramName}} := &{{dataType}}{}
if err := json.NewDecoder(r.Body).Decode(&{{paramName}}); err != nil {
{{paramName}} := {{dataType}}{}
d := json.NewDecoder(r.Body)
{{^isAdditionalPropertiesTrue}}
d.DisallowUnknownFields()
{{/isAdditionalPropertiesTrue}}
if err := d.Decode(&{{paramName}}); err != nil {
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
{{#isArray}}
{{#items.isModel}}
for _, el := range {{paramName}} {
if err := Assert{{baseType}}Required(el); err != nil {
c.errorHandler(w, r, err, nil)
return
}
}
{{/items.isModel}}
{{/isArray}}
{{^isArray}}
{{#isModel}}
if err := Assert{{baseType}}Required({{paramName}}); err != nil {
c.errorHandler(w, r, err, nil)
return
}
{{/isModel}}
{{/isArray}}
{{/isBodyParam}}
{{/allParams}}
result, err := c.service.{{nickname}}(r.Context(){{#allParams}}, {{#isBodyParam}}*{{/isBodyParam}}{{paramName}}{{/allParams}})
result, err := c.service.{{nickname}}(r.Context(){{#allParams}}, {{paramName}}{{/allParams}})
// If an error occurred, encode the error with the status code
if err != nil {
c.errorHandler(w, r, err, &result)

View File

@ -2,9 +2,16 @@
package {{packageName}}
import (
"errors"
"fmt"
"net/http"
)
var (
// ErrTypeAssertionError is thrown when type an interface does not match the asserted type
ErrTypeAssertionError = errors.New("unable to assert type")
)
// ParsingError indicates that an error has occurred when parsing request parameters
type ParsingError struct {
Err error
@ -18,6 +25,15 @@ func (e *ParsingError) Error() string {
return e.Err.Error()
}
// RequiredError indicates that an error has occurred when parsing request parameters
type RequiredError struct {
Field string
}
func (e *RequiredError) Error() string {
return fmt.Sprintf("required field '%s' is zero value.", e.Field)
}
// ErrorHandler defines the required method for handling error. You may implement it and inject this into a controller if
// you would like errors to be handled differently from the DefaultErrorHandler
type ErrorHandler func(w http.ResponseWriter, r *http.Request, err error, result *ImplResponse)
@ -28,6 +44,9 @@ func DefaultErrorHandler(w http.ResponseWriter, r *http.Request, err error, resu
if _, ok := err.(*ParsingError); ok {
// Handle parsing errors
EncodeJSONResponse(err.Error(), func(i int) *int { return &i }(http.StatusBadRequest),{{#addResponseHeaders}} map[string][]string{},{{/addResponseHeaders}} w)
} else if _, ok := err.(*RequiredError); ok {
// Handle missing required errors
EncodeJSONResponse(err.Error(), func(i int) *int { return &i }(http.StatusUnprocessableEntity),{{#addResponseHeaders}} map[string][]string{},{{/addResponseHeaders}} w)
} else {
// Handle all other errors
EncodeJSONResponse(err.Error(), &result.Code,{{#addResponseHeaders}} result.Headers,{{/addResponseHeaders}} w)

View File

@ -1,7 +1,11 @@
{{>partial_header}}
package {{packageName}}
//Response return a ImplResponse struct filled
import (
"reflect"
)
// Response return a ImplResponse struct filled
func Response(code int, body interface{}) ImplResponse {
return ImplResponse {
Code: code,
@ -13,7 +17,7 @@ func Response(code int, body interface{}) ImplResponse {
}
{{#addResponseHeaders}}
//ResponseWithHeaders return a ImplResponse struct filled, including headers
// ResponseWithHeaders return a ImplResponse struct filled, including headers
func ResponseWithHeaders(code int, headers map[string][]string, body interface{}) ImplResponse {
return ImplResponse {
Code: code,
@ -22,3 +26,35 @@ func ResponseWithHeaders(code int, headers map[string][]string, body interface{}
}
}
{{/addResponseHeaders}}
// IsZeroValue checks if the val is the zero-ed value.
func IsZeroValue(val interface{}) bool {
return val == nil || reflect.DeepEqual(val, reflect.Zero(reflect.TypeOf(val)).Interface())
}
// AssertInterfaceRequired recursively checks each struct in a slice against the callback.
// This method traverse nested slices in a preorder fashion.
func AssertRecurseInterfaceRequired(obj interface{}, callback func(interface{}) error) error {
return AssertRecurseValueRequired(reflect.ValueOf(obj), callback)
}
// AssertNestedValueRequired checks each struct in the nested slice against the callback.
// This method traverse nested slices in a preorder fashion.
func AssertRecurseValueRequired(value reflect.Value, callback func(interface{}) error) error {
switch value.Kind() {
// If it is a struct we check using callback
case reflect.Struct:
if err := callback(value.Interface()); err != nil {
return err
}
// If it is a slice we continue recursion
case reflect.Slice:
for i := 0; i < value.Len(); i += 1 {
if err := AssertRecurseValueRequired(value.Index(i), callback); err != nil {
return err
}
}
}
return nil
}

View File

@ -34,4 +34,101 @@ type {{classname}} struct {
{{/deprecated}}
{{name}} {{#isNullable}}*{{/isNullable}}{{{dataType}}} `json:"{{baseName}}{{^required}},omitempty{{/required}}"{{#vendorExtensions.x-go-custom-tag}} {{{.}}}{{/vendorExtensions.x-go-custom-tag}}`
{{/vars}}
}{{/isEnum}}{{/model}}{{/models}}
}{{/isEnum}}
// Assert{{classname}}Required checks if the required fields are not zero-ed
func Assert{{classname}}Required(obj {{classname}}) error {
{{#hasRequired}}
elements := map[string]interface{}{
{{#requiredVars}} "{{baseName}}": obj.{{name}},
{{/requiredVars}} }
for name, el := range elements {
if isZero := IsZeroValue(el); isZero {
return &RequiredError{Field: name}
}
}
{{/hasRequired}}
{{#parent}}
{{^isMap}}
{{^isArray}}
if err := Assert{{{parent}}}Required(obj.{{{parent}}}); err != nil {
return err
}
{{/isArray}}
{{/isMap}}
{{/parent}}
{{#Vars}}
{{#isNullable}}
{{#isModel}}
if obj.{{name}} != nil {
{{/isModel}}
{{#isArray}}
{{#items.isModel}}
if obj.{{name}} != nil {
{{/items.isModel}}
{{^items.isModel}}
{{#mostInnerItems.isModel}}
{{^mostInnerItems.isPrimitiveType}}
if obj.{{name}} != nil {
{{/mostInnerItems.isPrimitiveType}}
{{/mostInnerItems.isModel}}
{{/items.isModel}}
{{/isArray}}
{{/isNullable}}
{{#isModel}}
{{#isNullable}} {{/isNullable}} if err := Assert{{baseType}}Required({{#isNullable}}*{{/isNullable}}obj.{{name}}); err != nil {
{{#isNullable}} {{/isNullable}} return err
{{#isNullable}} {{/isNullable}} }
{{/isModel}}
{{#isArray}}
{{#items.isModel}}
{{#isNullable}} {{/isNullable}} for _, el := range {{#isNullable}}*{{/isNullable}}obj.{{name}} {
{{#isNullable}} {{/isNullable}} if err := Assert{{items.baseType}}Required(el); err != nil {
{{#isNullable}} {{/isNullable}} return err
{{#isNullable}} {{/isNullable}} }
{{#isNullable}} {{/isNullable}} }
{{/items.isModel}}
{{^items.isModel}}
{{#mostInnerItems.isModel}}
{{^mostInnerItems.isPrimitiveType}}
{{#isNullable}} {{/isNullable}} if err := AssertRecurse{{mostInnerItems.dataType}}Required({{#isNullable}}*{{/isNullable}}obj.{{name}}); err != nil {
{{#isNullable}} {{/isNullable}} return err
{{#isNullable}} {{/isNullable}} }
{{/mostInnerItems.isPrimitiveType}}
{{/mostInnerItems.isModel}}
{{/items.isModel}}
{{/isArray}}
{{#isNullable}}
{{#isModel}}
}
{{/isModel}}
{{#isArray}}
{{#items.isModel}}
}
{{/items.isModel}}
{{^items.isModel}}
{{#mostInnerItems.isModel}}
{{^mostInnerItems.isPrimitiveType}}
}
{{/mostInnerItems.isPrimitiveType}}
{{/mostInnerItems.isModel}}
{{/items.isModel}}
{{/isArray}}
{{/isNullable}}
{{/Vars}}
return nil
}
// AssertRecurse{{classname}}Required recursively checks if required fields are not zero-ed in a nested slice.
// Accepts only nested slice of {{classname}} (e.g. [][]{{classname}}), otherwise ErrTypeAssertionError is thrown.
func AssertRecurse{{classname}}Required(objSlice interface{}) error {
return AssertRecurseInterfaceRequired(objSlice, func(obj interface{}) error {
a{{classname}}, ok := obj.({{classname}})
if !ok {
return ErrTypeAssertionError
}
return Assert{{classname}}Required(a{{classname}})
})
}{{/model}}{{/models}}

View File

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

View File

@ -103,12 +103,18 @@ func (c *PetApiController) Routes() Routes {
// AddPet - Add a new pet to the store
func (c *PetApiController) AddPet(w http.ResponseWriter, r *http.Request) {
pet := &Pet{}
if err := json.NewDecoder(r.Body).Decode(&pet); err != nil {
pet := Pet{}
d := json.NewDecoder(r.Body)
d.DisallowUnknownFields()
if err := d.Decode(&pet); err != nil {
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
result, err := c.service.AddPet(r.Context(), *pet)
if err := AssertPetRequired(pet); err != nil {
c.errorHandler(w, r, err, nil)
return
}
result, err := c.service.AddPet(r.Context(), pet)
// If an error occurred, encode the error with the status code
if err != nil {
c.errorHandler(w, r, err, &result)
@ -193,12 +199,18 @@ func (c *PetApiController) GetPetById(w http.ResponseWriter, r *http.Request) {
// UpdatePet - Update an existing pet
func (c *PetApiController) UpdatePet(w http.ResponseWriter, r *http.Request) {
pet := &Pet{}
if err := json.NewDecoder(r.Body).Decode(&pet); err != nil {
pet := Pet{}
d := json.NewDecoder(r.Body)
d.DisallowUnknownFields()
if err := d.Decode(&pet); err != nil {
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
result, err := c.service.UpdatePet(r.Context(), *pet)
if err := AssertPetRequired(pet); err != nil {
c.errorHandler(w, r, err, nil)
return
}
result, err := c.service.UpdatePet(r.Context(), pet)
// If an error occurred, encode the error with the status code
if err != nil {
c.errorHandler(w, r, err, &result)

View File

@ -128,12 +128,18 @@ func (c *StoreApiController) GetOrderById(w http.ResponseWriter, r *http.Request
// PlaceOrder - Place an order for a pet
func (c *StoreApiController) PlaceOrder(w http.ResponseWriter, r *http.Request) {
order := &Order{}
if err := json.NewDecoder(r.Body).Decode(&order); err != nil {
order := Order{}
d := json.NewDecoder(r.Body)
d.DisallowUnknownFields()
if err := d.Decode(&order); err != nil {
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
result, err := c.service.PlaceOrder(r.Context(), *order)
if err := AssertOrderRequired(order); err != nil {
c.errorHandler(w, r, err, nil)
return
}
result, err := c.service.PlaceOrder(r.Context(), order)
// If an error occurred, encode the error with the status code
if err != nil {
c.errorHandler(w, r, err, &result)

View File

@ -103,12 +103,18 @@ func (c *UserApiController) Routes() Routes {
// CreateUser - Create user
func (c *UserApiController) CreateUser(w http.ResponseWriter, r *http.Request) {
user := &User{}
if err := json.NewDecoder(r.Body).Decode(&user); err != nil {
user := User{}
d := json.NewDecoder(r.Body)
d.DisallowUnknownFields()
if err := d.Decode(&user); err != nil {
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
result, err := c.service.CreateUser(r.Context(), *user)
if err := AssertUserRequired(user); err != nil {
c.errorHandler(w, r, err, nil)
return
}
result, err := c.service.CreateUser(r.Context(), user)
// If an error occurred, encode the error with the status code
if err != nil {
c.errorHandler(w, r, err, &result)
@ -121,12 +127,20 @@ func (c *UserApiController) CreateUser(w http.ResponseWriter, r *http.Request) {
// CreateUsersWithArrayInput - Creates list of users with given input array
func (c *UserApiController) CreateUsersWithArrayInput(w http.ResponseWriter, r *http.Request) {
user := &[]User{}
if err := json.NewDecoder(r.Body).Decode(&user); err != nil {
user := []User{}
d := json.NewDecoder(r.Body)
d.DisallowUnknownFields()
if err := d.Decode(&user); err != nil {
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
result, err := c.service.CreateUsersWithArrayInput(r.Context(), *user)
for _, el := range user {
if err := AssertUserRequired(el); err != nil {
c.errorHandler(w, r, err, nil)
return
}
}
result, err := c.service.CreateUsersWithArrayInput(r.Context(), user)
// If an error occurred, encode the error with the status code
if err != nil {
c.errorHandler(w, r, err, &result)
@ -139,12 +153,20 @@ func (c *UserApiController) CreateUsersWithArrayInput(w http.ResponseWriter, r *
// CreateUsersWithListInput - Creates list of users with given input array
func (c *UserApiController) CreateUsersWithListInput(w http.ResponseWriter, r *http.Request) {
user := &[]User{}
if err := json.NewDecoder(r.Body).Decode(&user); err != nil {
user := []User{}
d := json.NewDecoder(r.Body)
d.DisallowUnknownFields()
if err := d.Decode(&user); err != nil {
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
result, err := c.service.CreateUsersWithListInput(r.Context(), *user)
for _, el := range user {
if err := AssertUserRequired(el); err != nil {
c.errorHandler(w, r, err, nil)
return
}
}
result, err := c.service.CreateUsersWithListInput(r.Context(), user)
// If an error occurred, encode the error with the status code
if err != nil {
c.errorHandler(w, r, err, &result)
@ -221,12 +243,18 @@ func (c *UserApiController) UpdateUser(w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
username := params["username"]
user := &User{}
if err := json.NewDecoder(r.Body).Decode(&user); err != nil {
user := User{}
d := json.NewDecoder(r.Body)
d.DisallowUnknownFields()
if err := d.Decode(&user); err != nil {
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
result, err := c.service.UpdateUser(r.Context(), username, *user)
if err := AssertUserRequired(user); err != nil {
c.errorHandler(w, r, err, nil)
return
}
result, err := c.service.UpdateUser(r.Context(), username, user)
// If an error occurred, encode the error with the status code
if err != nil {
c.errorHandler(w, r, err, &result)

View File

@ -10,9 +10,16 @@
package petstoreserver
import (
"errors"
"fmt"
"net/http"
)
var (
// ErrTypeAssertionError is thrown when type an interface does not match the asserted type
ErrTypeAssertionError = errors.New("unable to assert type")
)
// ParsingError indicates that an error has occurred when parsing request parameters
type ParsingError struct {
Err error
@ -26,6 +33,15 @@ func (e *ParsingError) Error() string {
return e.Err.Error()
}
// RequiredError indicates that an error has occurred when parsing request parameters
type RequiredError struct {
Field string
}
func (e *RequiredError) Error() string {
return fmt.Sprintf("required field '%s' is zero value.", e.Field)
}
// ErrorHandler defines the required method for handling error. You may implement it and inject this into a controller if
// you would like errors to be handled differently from the DefaultErrorHandler
type ErrorHandler func(w http.ResponseWriter, r *http.Request, err error, result *ImplResponse)
@ -36,6 +52,9 @@ func DefaultErrorHandler(w http.ResponseWriter, r *http.Request, err error, resu
if _, ok := err.(*ParsingError); ok {
// Handle parsing errors
EncodeJSONResponse(err.Error(), func(i int) *int { return &i }(http.StatusBadRequest), map[string][]string{}, w)
} else if _, ok := err.(*RequiredError); ok {
// Handle missing required errors
EncodeJSONResponse(err.Error(), func(i int) *int { return &i }(http.StatusUnprocessableEntity), map[string][]string{}, w)
} else {
// Handle all other errors
EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w)

View File

@ -9,7 +9,11 @@
package petstoreserver
//Response return a ImplResponse struct filled
import (
"reflect"
)
// Response return a ImplResponse struct filled
func Response(code int, body interface{}) ImplResponse {
return ImplResponse {
Code: code,
@ -18,7 +22,7 @@ func Response(code int, body interface{}) ImplResponse {
}
}
//ResponseWithHeaders return a ImplResponse struct filled, including headers
// ResponseWithHeaders return a ImplResponse struct filled, including headers
func ResponseWithHeaders(code int, headers map[string][]string, body interface{}) ImplResponse {
return ImplResponse {
Code: code,
@ -26,3 +30,35 @@ func ResponseWithHeaders(code int, headers map[string][]string, body interface{}
Body: body,
}
}
// IsZeroValue checks if the val is the zero-ed value.
func IsZeroValue(val interface{}) bool {
return val == nil || reflect.DeepEqual(val, reflect.Zero(reflect.TypeOf(val)).Interface())
}
// AssertInterfaceRequired recursively checks each struct in a slice against the callback.
// This method traverse nested slices in a preorder fashion.
func AssertRecurseInterfaceRequired(obj interface{}, callback func(interface{}) error) error {
return AssertRecurseValueRequired(reflect.ValueOf(obj), callback)
}
// AssertNestedValueRequired checks each struct in the nested slice against the callback.
// This method traverse nested slices in a preorder fashion.
func AssertRecurseValueRequired(value reflect.Value, callback func(interface{}) error) error {
switch value.Kind() {
// If it is a struct we check using callback
case reflect.Struct:
if err := callback(value.Interface()); err != nil {
return err
}
// If it is a slice we continue recursion
case reflect.Slice:
for i := 0; i < value.Len(); i += 1 {
if err := AssertRecurseValueRequired(value.Index(i), callback); err != nil {
return err
}
}
}
return nil
}

View File

@ -18,3 +18,20 @@ type ApiResponse struct {
Message string `json:"message,omitempty"`
}
// AssertApiResponseRequired checks if the required fields are not zero-ed
func AssertApiResponseRequired(obj ApiResponse) error {
return nil
}
// AssertRecurseApiResponseRequired recursively checks if required fields are not zero-ed in a nested slice.
// Accepts only nested slice of ApiResponse (e.g. [][]ApiResponse), otherwise ErrTypeAssertionError is thrown.
func AssertRecurseApiResponseRequired(objSlice interface{}) error {
return AssertRecurseInterfaceRequired(objSlice, func(obj interface{}) error {
aApiResponse, ok := obj.(ApiResponse)
if !ok {
return ErrTypeAssertionError
}
return AssertApiResponseRequired(aApiResponse)
})
}

View File

@ -16,3 +16,20 @@ type Category struct {
Name string `json:"name,omitempty"`
}
// AssertCategoryRequired checks if the required fields are not zero-ed
func AssertCategoryRequired(obj Category) error {
return nil
}
// AssertRecurseCategoryRequired recursively checks if required fields are not zero-ed in a nested slice.
// Accepts only nested slice of Category (e.g. [][]Category), otherwise ErrTypeAssertionError is thrown.
func AssertRecurseCategoryRequired(objSlice interface{}) error {
return AssertRecurseInterfaceRequired(objSlice, func(obj interface{}) error {
aCategory, ok := obj.(Category)
if !ok {
return ErrTypeAssertionError
}
return AssertCategoryRequired(aCategory)
})
}

View File

@ -29,3 +29,20 @@ type Order struct {
Complete bool `json:"complete,omitempty"`
}
// AssertOrderRequired checks if the required fields are not zero-ed
func AssertOrderRequired(obj Order) error {
return nil
}
// AssertRecurseOrderRequired recursively checks if required fields are not zero-ed in a nested slice.
// Accepts only nested slice of Order (e.g. [][]Order), otherwise ErrTypeAssertionError is thrown.
func AssertRecurseOrderRequired(objSlice interface{}) error {
return AssertRecurseInterfaceRequired(objSlice, func(obj interface{}) error {
aOrder, ok := obj.(Order)
if !ok {
return ErrTypeAssertionError
}
return AssertOrderRequired(aOrder)
})
}

View File

@ -26,3 +26,38 @@ type Pet struct {
// Deprecated
Status string `json:"status,omitempty"`
}
// AssertPetRequired checks if the required fields are not zero-ed
func AssertPetRequired(obj Pet) error {
elements := map[string]interface{}{
"name": obj.Name,
"photoUrls": obj.PhotoUrls,
}
for name, el := range elements {
if isZero := IsZeroValue(el); isZero {
return &RequiredError{Field: name}
}
}
if err := AssertCategoryRequired(obj.Category); err != nil {
return err
}
for _, el := range obj.Tags {
if err := AssertTagRequired(el); err != nil {
return err
}
}
return nil
}
// AssertRecursePetRequired recursively checks if required fields are not zero-ed in a nested slice.
// Accepts only nested slice of Pet (e.g. [][]Pet), otherwise ErrTypeAssertionError is thrown.
func AssertRecursePetRequired(objSlice interface{}) error {
return AssertRecurseInterfaceRequired(objSlice, func(obj interface{}) error {
aPet, ok := obj.(Pet)
if !ok {
return ErrTypeAssertionError
}
return AssertPetRequired(aPet)
})
}

View File

@ -16,3 +16,20 @@ type Tag struct {
Name string `json:"name,omitempty"`
}
// AssertTagRequired checks if the required fields are not zero-ed
func AssertTagRequired(obj Tag) error {
return nil
}
// AssertRecurseTagRequired recursively checks if required fields are not zero-ed in a nested slice.
// Accepts only nested slice of Tag (e.g. [][]Tag), otherwise ErrTypeAssertionError is thrown.
func AssertRecurseTagRequired(objSlice interface{}) error {
return AssertRecurseInterfaceRequired(objSlice, func(obj interface{}) error {
aTag, ok := obj.(Tag)
if !ok {
return ErrTypeAssertionError
}
return AssertTagRequired(aTag)
})
}

View File

@ -29,3 +29,20 @@ type User struct {
// User Status
UserStatus int32 `json:"userStatus,omitempty"`
}
// AssertUserRequired checks if the required fields are not zero-ed
func AssertUserRequired(obj User) error {
return nil
}
// AssertRecurseUserRequired recursively checks if required fields are not zero-ed in a nested slice.
// Accepts only nested slice of User (e.g. [][]User), otherwise ErrTypeAssertionError is thrown.
func AssertRecurseUserRequired(objSlice interface{}) error {
return AssertRecurseInterfaceRequired(objSlice, func(obj interface{}) error {
aUser, ok := obj.(User)
if !ok {
return ErrTypeAssertionError
}
return AssertUserRequired(aUser)
})
}

View File

@ -103,12 +103,18 @@ func (c *PetApiController) Routes() Routes {
// AddPet - Add a new pet to the store
func (c *PetApiController) AddPet(w http.ResponseWriter, r *http.Request) {
pet := &Pet{}
if err := json.NewDecoder(r.Body).Decode(&pet); err != nil {
pet := Pet{}
d := json.NewDecoder(r.Body)
d.DisallowUnknownFields()
if err := d.Decode(&pet); err != nil {
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
result, err := c.service.AddPet(r.Context(), *pet)
if err := AssertPetRequired(pet); err != nil {
c.errorHandler(w, r, err, nil)
return
}
result, err := c.service.AddPet(r.Context(), pet)
// If an error occurred, encode the error with the status code
if err != nil {
c.errorHandler(w, r, err, &result)
@ -191,12 +197,18 @@ func (c *PetApiController) GetPetById(w http.ResponseWriter, r *http.Request) {
// UpdatePet - Update an existing pet
func (c *PetApiController) UpdatePet(w http.ResponseWriter, r *http.Request) {
pet := &Pet{}
if err := json.NewDecoder(r.Body).Decode(&pet); err != nil {
pet := Pet{}
d := json.NewDecoder(r.Body)
d.DisallowUnknownFields()
if err := d.Decode(&pet); err != nil {
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
result, err := c.service.UpdatePet(r.Context(), *pet)
if err := AssertPetRequired(pet); err != nil {
c.errorHandler(w, r, err, nil)
return
}
result, err := c.service.UpdatePet(r.Context(), pet)
// If an error occurred, encode the error with the status code
if err != nil {
c.errorHandler(w, r, err, &result)

View File

@ -126,12 +126,18 @@ func (c *StoreApiController) GetOrderById(w http.ResponseWriter, r *http.Request
// PlaceOrder - Place an order for a pet
func (c *StoreApiController) PlaceOrder(w http.ResponseWriter, r *http.Request) {
order := &Order{}
if err := json.NewDecoder(r.Body).Decode(&order); err != nil {
order := Order{}
d := json.NewDecoder(r.Body)
d.DisallowUnknownFields()
if err := d.Decode(&order); err != nil {
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
result, err := c.service.PlaceOrder(r.Context(), *order)
if err := AssertOrderRequired(order); err != nil {
c.errorHandler(w, r, err, nil)
return
}
result, err := c.service.PlaceOrder(r.Context(), order)
// If an error occurred, encode the error with the status code
if err != nil {
c.errorHandler(w, r, err, &result)

View File

@ -103,12 +103,18 @@ func (c *UserApiController) Routes() Routes {
// CreateUser - Create user
func (c *UserApiController) CreateUser(w http.ResponseWriter, r *http.Request) {
user := &User{}
if err := json.NewDecoder(r.Body).Decode(&user); err != nil {
user := User{}
d := json.NewDecoder(r.Body)
d.DisallowUnknownFields()
if err := d.Decode(&user); err != nil {
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
result, err := c.service.CreateUser(r.Context(), *user)
if err := AssertUserRequired(user); err != nil {
c.errorHandler(w, r, err, nil)
return
}
result, err := c.service.CreateUser(r.Context(), user)
// If an error occurred, encode the error with the status code
if err != nil {
c.errorHandler(w, r, err, &result)
@ -121,12 +127,20 @@ func (c *UserApiController) CreateUser(w http.ResponseWriter, r *http.Request) {
// CreateUsersWithArrayInput - Creates list of users with given input array
func (c *UserApiController) CreateUsersWithArrayInput(w http.ResponseWriter, r *http.Request) {
user := &[]User{}
if err := json.NewDecoder(r.Body).Decode(&user); err != nil {
user := []User{}
d := json.NewDecoder(r.Body)
d.DisallowUnknownFields()
if err := d.Decode(&user); err != nil {
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
result, err := c.service.CreateUsersWithArrayInput(r.Context(), *user)
for _, el := range user {
if err := AssertUserRequired(el); err != nil {
c.errorHandler(w, r, err, nil)
return
}
}
result, err := c.service.CreateUsersWithArrayInput(r.Context(), user)
// If an error occurred, encode the error with the status code
if err != nil {
c.errorHandler(w, r, err, &result)
@ -139,12 +153,20 @@ func (c *UserApiController) CreateUsersWithArrayInput(w http.ResponseWriter, r *
// CreateUsersWithListInput - Creates list of users with given input array
func (c *UserApiController) CreateUsersWithListInput(w http.ResponseWriter, r *http.Request) {
user := &[]User{}
if err := json.NewDecoder(r.Body).Decode(&user); err != nil {
user := []User{}
d := json.NewDecoder(r.Body)
d.DisallowUnknownFields()
if err := d.Decode(&user); err != nil {
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
result, err := c.service.CreateUsersWithListInput(r.Context(), *user)
for _, el := range user {
if err := AssertUserRequired(el); err != nil {
c.errorHandler(w, r, err, nil)
return
}
}
result, err := c.service.CreateUsersWithListInput(r.Context(), user)
// If an error occurred, encode the error with the status code
if err != nil {
c.errorHandler(w, r, err, &result)
@ -218,12 +240,18 @@ func (c *UserApiController) LogoutUser(w http.ResponseWriter, r *http.Request) {
func (c *UserApiController) UpdateUser(w http.ResponseWriter, r *http.Request) {
username := chi.URLParam(r, "username")
user := &User{}
if err := json.NewDecoder(r.Body).Decode(&user); err != nil {
user := User{}
d := json.NewDecoder(r.Body)
d.DisallowUnknownFields()
if err := d.Decode(&user); err != nil {
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
result, err := c.service.UpdateUser(r.Context(), username, *user)
if err := AssertUserRequired(user); err != nil {
c.errorHandler(w, r, err, nil)
return
}
result, err := c.service.UpdateUser(r.Context(), username, user)
// If an error occurred, encode the error with the status code
if err != nil {
c.errorHandler(w, r, err, &result)

View File

@ -10,9 +10,16 @@
package petstoreserver
import (
"errors"
"fmt"
"net/http"
)
var (
// ErrTypeAssertionError is thrown when type an interface does not match the asserted type
ErrTypeAssertionError = errors.New("unable to assert type")
)
// ParsingError indicates that an error has occurred when parsing request parameters
type ParsingError struct {
Err error
@ -26,6 +33,15 @@ func (e *ParsingError) Error() string {
return e.Err.Error()
}
// RequiredError indicates that an error has occurred when parsing request parameters
type RequiredError struct {
Field string
}
func (e *RequiredError) Error() string {
return fmt.Sprintf("required field '%s' is zero value.", e.Field)
}
// ErrorHandler defines the required method for handling error. You may implement it and inject this into a controller if
// you would like errors to be handled differently from the DefaultErrorHandler
type ErrorHandler func(w http.ResponseWriter, r *http.Request, err error, result *ImplResponse)
@ -36,6 +52,9 @@ func DefaultErrorHandler(w http.ResponseWriter, r *http.Request, err error, resu
if _, ok := err.(*ParsingError); ok {
// Handle parsing errors
EncodeJSONResponse(err.Error(), func(i int) *int { return &i }(http.StatusBadRequest), map[string][]string{}, w)
} else if _, ok := err.(*RequiredError); ok {
// Handle missing required errors
EncodeJSONResponse(err.Error(), func(i int) *int { return &i }(http.StatusUnprocessableEntity), map[string][]string{}, w)
} else {
// Handle all other errors
EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w)

View File

@ -9,7 +9,11 @@
package petstoreserver
//Response return a ImplResponse struct filled
import (
"reflect"
)
// Response return a ImplResponse struct filled
func Response(code int, body interface{}) ImplResponse {
return ImplResponse {
Code: code,
@ -18,7 +22,7 @@ func Response(code int, body interface{}) ImplResponse {
}
}
//ResponseWithHeaders return a ImplResponse struct filled, including headers
// ResponseWithHeaders return a ImplResponse struct filled, including headers
func ResponseWithHeaders(code int, headers map[string][]string, body interface{}) ImplResponse {
return ImplResponse {
Code: code,
@ -26,3 +30,35 @@ func ResponseWithHeaders(code int, headers map[string][]string, body interface{}
Body: body,
}
}
// IsZeroValue checks if the val is the zero-ed value.
func IsZeroValue(val interface{}) bool {
return val == nil || reflect.DeepEqual(val, reflect.Zero(reflect.TypeOf(val)).Interface())
}
// AssertInterfaceRequired recursively checks each struct in a slice against the callback.
// This method traverse nested slices in a preorder fashion.
func AssertRecurseInterfaceRequired(obj interface{}, callback func(interface{}) error) error {
return AssertRecurseValueRequired(reflect.ValueOf(obj), callback)
}
// AssertNestedValueRequired checks each struct in the nested slice against the callback.
// This method traverse nested slices in a preorder fashion.
func AssertRecurseValueRequired(value reflect.Value, callback func(interface{}) error) error {
switch value.Kind() {
// If it is a struct we check using callback
case reflect.Struct:
if err := callback(value.Interface()); err != nil {
return err
}
// If it is a slice we continue recursion
case reflect.Slice:
for i := 0; i < value.Len(); i += 1 {
if err := AssertRecurseValueRequired(value.Index(i), callback); err != nil {
return err
}
}
}
return nil
}

View File

@ -18,3 +18,20 @@ type ApiResponse struct {
Message string `json:"message,omitempty"`
}
// AssertApiResponseRequired checks if the required fields are not zero-ed
func AssertApiResponseRequired(obj ApiResponse) error {
return nil
}
// AssertRecurseApiResponseRequired recursively checks if required fields are not zero-ed in a nested slice.
// Accepts only nested slice of ApiResponse (e.g. [][]ApiResponse), otherwise ErrTypeAssertionError is thrown.
func AssertRecurseApiResponseRequired(objSlice interface{}) error {
return AssertRecurseInterfaceRequired(objSlice, func(obj interface{}) error {
aApiResponse, ok := obj.(ApiResponse)
if !ok {
return ErrTypeAssertionError
}
return AssertApiResponseRequired(aApiResponse)
})
}

View File

@ -16,3 +16,20 @@ type Category struct {
Name string `json:"name,omitempty"`
}
// AssertCategoryRequired checks if the required fields are not zero-ed
func AssertCategoryRequired(obj Category) error {
return nil
}
// AssertRecurseCategoryRequired recursively checks if required fields are not zero-ed in a nested slice.
// Accepts only nested slice of Category (e.g. [][]Category), otherwise ErrTypeAssertionError is thrown.
func AssertRecurseCategoryRequired(objSlice interface{}) error {
return AssertRecurseInterfaceRequired(objSlice, func(obj interface{}) error {
aCategory, ok := obj.(Category)
if !ok {
return ErrTypeAssertionError
}
return AssertCategoryRequired(aCategory)
})
}

View File

@ -29,3 +29,20 @@ type Order struct {
Complete bool `json:"complete,omitempty"`
}
// AssertOrderRequired checks if the required fields are not zero-ed
func AssertOrderRequired(obj Order) error {
return nil
}
// AssertRecurseOrderRequired recursively checks if required fields are not zero-ed in a nested slice.
// Accepts only nested slice of Order (e.g. [][]Order), otherwise ErrTypeAssertionError is thrown.
func AssertRecurseOrderRequired(objSlice interface{}) error {
return AssertRecurseInterfaceRequired(objSlice, func(obj interface{}) error {
aOrder, ok := obj.(Order)
if !ok {
return ErrTypeAssertionError
}
return AssertOrderRequired(aOrder)
})
}

View File

@ -26,3 +26,38 @@ type Pet struct {
// Deprecated
Status string `json:"status,omitempty"`
}
// AssertPetRequired checks if the required fields are not zero-ed
func AssertPetRequired(obj Pet) error {
elements := map[string]interface{}{
"name": obj.Name,
"photoUrls": obj.PhotoUrls,
}
for name, el := range elements {
if isZero := IsZeroValue(el); isZero {
return &RequiredError{Field: name}
}
}
if err := AssertCategoryRequired(obj.Category); err != nil {
return err
}
for _, el := range obj.Tags {
if err := AssertTagRequired(el); err != nil {
return err
}
}
return nil
}
// AssertRecursePetRequired recursively checks if required fields are not zero-ed in a nested slice.
// Accepts only nested slice of Pet (e.g. [][]Pet), otherwise ErrTypeAssertionError is thrown.
func AssertRecursePetRequired(objSlice interface{}) error {
return AssertRecurseInterfaceRequired(objSlice, func(obj interface{}) error {
aPet, ok := obj.(Pet)
if !ok {
return ErrTypeAssertionError
}
return AssertPetRequired(aPet)
})
}

View File

@ -16,3 +16,20 @@ type Tag struct {
Name string `json:"name,omitempty"`
}
// AssertTagRequired checks if the required fields are not zero-ed
func AssertTagRequired(obj Tag) error {
return nil
}
// AssertRecurseTagRequired recursively checks if required fields are not zero-ed in a nested slice.
// Accepts only nested slice of Tag (e.g. [][]Tag), otherwise ErrTypeAssertionError is thrown.
func AssertRecurseTagRequired(objSlice interface{}) error {
return AssertRecurseInterfaceRequired(objSlice, func(obj interface{}) error {
aTag, ok := obj.(Tag)
if !ok {
return ErrTypeAssertionError
}
return AssertTagRequired(aTag)
})
}

View File

@ -29,3 +29,20 @@ type User struct {
// User Status
UserStatus int32 `json:"userStatus,omitempty"`
}
// AssertUserRequired checks if the required fields are not zero-ed
func AssertUserRequired(obj User) error {
return nil
}
// AssertRecurseUserRequired recursively checks if required fields are not zero-ed in a nested slice.
// Accepts only nested slice of User (e.g. [][]User), otherwise ErrTypeAssertionError is thrown.
func AssertRecurseUserRequired(objSlice interface{}) error {
return AssertRecurseInterfaceRequired(objSlice, func(obj interface{}) error {
aUser, ok := obj.(User)
if !ok {
return ErrTypeAssertionError
}
return AssertUserRequired(aUser)
})
}

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,25 @@
Dockerfile
README.md
api/openapi.yaml
go.mod
go/api.go
go/api_pet.go
go/api_pet_service.go
go/api_store.go
go/api_store_service.go
go/api_user.go
go/api_user_service.go
go/error.go
go/helpers.go
go/impl.go
go/logger.go
go/model_api_response.go
go/model_category.go
go/model_order.go
go/model_order_info.go
go/model_pet.go
go/model_special_info.go
go/model_tag.go
go/model_user.go
go/routers.go
main.go

View File

@ -0,0 +1 @@
5.2.1-SNAPSHOT

View File

@ -0,0 +1,14 @@
FROM golang:1.10 AS build
WORKDIR /go/src
COPY go ./go
COPY main.go .
ENV CGO_ENABLED=0
RUN go get -d -v ./...
RUN go build -a -installsuffix cgo -o petstoreserver .
FROM scratch AS runtime
COPY --from=build /go/src/petstoreserver ./
EXPOSE 8080/tcp
ENTRYPOINT ["./petstoreserver"]

View File

@ -0,0 +1,35 @@
# Go API Server for petstoreserver
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 run main.go
```
To run the server in a docker container
```
docker build --network=host -t petstoreserver .
```
Once image is built use
```
docker run --rm -it petstoreserver
```

View File

@ -0,0 +1,906 @@
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:
OrderInfo:
description: An order info for a pets from the pet store
properties:
petId:
format: int64
type: integer
quantity:
format: int32
type: integer
shipDate:
format: date-time
type: string
title: Pet Order Info
type: object
xml:
name: OrderInfo
SpecialInfo:
description: An order info for a pets from the pet store
discriminator:
propertyName: type
properties:
promotion:
type: boolean
type:
type: string
title: Pet Order Info
type: object
xml:
name: OrderInfo
Order:
allOf:
- $ref: '#/components/schemas/OrderInfo'
- $ref: '#/components/schemas/SpecialInfo'
description: An order for a pets from the pet store
example:
comment: comment
id: 0
complete: false
status: placed
properties:
id:
format: int64
type: integer
status:
description: Order Status
enum:
- placed
- approved
- delivered
type: string
complete:
default: false
type: boolean
comment:
nullable: true
type: string
required:
- comment
title: Pet Order
type: object
xml:
name: Order
Category:
description: A category for a pet
example:
name: name
id: 6
nullable: true
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
deepSliceModel:
- - - name: name
id: 1
- name: name
id: 1
- - name: name
id: 1
- name: name
id: 1
- - - name: name
id: 1
- name: name
id: 1
- - name: name
id: 1
- name: name
id: 1
id: 0
deepSliceMap:
- - '{}'
- '{}'
- - '{}'
- '{}'
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:
nullable: true
type: string
userStatus:
description: User Status
format: int32
type: integer
deepSliceModel:
description: An array 1-deep.
items:
description: An array 2-deep.
items:
description: An array 3-deep.
items:
$ref: '#/components/schemas/Tag'
type: array
type: array
nullable: true
type: array
deepSliceMap:
description: An array 1-deep.
items:
description: An array 2-deep.
items:
description: An array 3-deep.
properties:
tag:
$ref: '#/components/schemas/Tag'
Pet:
description: An array of pet.
items:
$ref: '#/components/schemas/Pet'
type: array
title: an Object
type: object
type: array
type: array
required:
- deepSliceModel
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
nullable: true
type: array
xml:
name: photoUrl
wrapped: true
tags:
items:
$ref: '#/components/schemas/Tag'
nullable: true
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,5 @@
module github.com/GIT_USER_ID/GIT_REPO_ID
go 1.13
require github.com/go-chi/chi/v5 v5.0.3

View File

@ -0,0 +1,100 @@
/*
* OpenAPI Petstore
*
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package petstoreserver
import (
"context"
"net/http"
"os"
)
// PetApiRouter defines the required methods for binding the api requests to a responses for the PetApi
// The PetApiRouter implementation should parse necessary information from the http request,
// pass the data to a PetApiServicer to perform the required actions, then write the service results to the http response.
type PetApiRouter interface {
AddPet(http.ResponseWriter, *http.Request)
DeletePet(http.ResponseWriter, *http.Request)
FindPetsByStatus(http.ResponseWriter, *http.Request)
// Deprecated
FindPetsByTags(http.ResponseWriter, *http.Request)
GetPetById(http.ResponseWriter, *http.Request)
UpdatePet(http.ResponseWriter, *http.Request)
UpdatePetWithForm(http.ResponseWriter, *http.Request)
UploadFile(http.ResponseWriter, *http.Request)
}
// StoreApiRouter defines the required methods for binding the api requests to a responses for the StoreApi
// The StoreApiRouter implementation should parse necessary information from the http request,
// pass the data to a StoreApiServicer to perform the required actions, then write the service results to the http response.
type StoreApiRouter interface {
DeleteOrder(http.ResponseWriter, *http.Request)
GetInventory(http.ResponseWriter, *http.Request)
GetOrderById(http.ResponseWriter, *http.Request)
PlaceOrder(http.ResponseWriter, *http.Request)
}
// UserApiRouter defines the required methods for binding the api requests to a responses for the UserApi
// The UserApiRouter implementation should parse necessary information from the http request,
// pass the data to a UserApiServicer to perform the required actions, then write the service results to the http response.
type UserApiRouter interface {
CreateUser(http.ResponseWriter, *http.Request)
CreateUsersWithArrayInput(http.ResponseWriter, *http.Request)
CreateUsersWithListInput(http.ResponseWriter, *http.Request)
DeleteUser(http.ResponseWriter, *http.Request)
GetUserByName(http.ResponseWriter, *http.Request)
LoginUser(http.ResponseWriter, *http.Request)
LogoutUser(http.ResponseWriter, *http.Request)
UpdateUser(http.ResponseWriter, *http.Request)
}
// PetApiServicer defines the api actions for the PetApi service
// This interface intended to stay up to date with the openapi yaml used to generate it,
// while the service implementation can ignored with the .openapi-generator-ignore file
// and updated with the logic required for the API.
type PetApiServicer interface {
AddPet(context.Context, Pet) (ImplResponse, error)
DeletePet(context.Context, int64, string) (ImplResponse, error)
FindPetsByStatus(context.Context, []string) (ImplResponse, error)
// Deprecated
FindPetsByTags(context.Context, []string) (ImplResponse, error)
GetPetById(context.Context, int64) (ImplResponse, error)
UpdatePet(context.Context, Pet) (ImplResponse, error)
UpdatePetWithForm(context.Context, int64, string, string) (ImplResponse, error)
UploadFile(context.Context, int64, string, *os.File) (ImplResponse, error)
}
// StoreApiServicer defines the api actions for the StoreApi service
// This interface intended to stay up to date with the openapi yaml used to generate it,
// while the service implementation can ignored with the .openapi-generator-ignore file
// and updated with the logic required for the API.
type StoreApiServicer interface {
DeleteOrder(context.Context, string) (ImplResponse, error)
GetInventory(context.Context) (ImplResponse, error)
GetOrderById(context.Context, int64) (ImplResponse, error)
PlaceOrder(context.Context, Order) (ImplResponse, error)
}
// UserApiServicer defines the api actions for the UserApi service
// This interface intended to stay up to date with the openapi yaml used to generate it,
// while the service implementation can ignored with the .openapi-generator-ignore file
// and updated with the logic required for the API.
type UserApiServicer interface {
CreateUser(context.Context, User) (ImplResponse, error)
CreateUsersWithArrayInput(context.Context, []User) (ImplResponse, error)
CreateUsersWithListInput(context.Context, []User) (ImplResponse, error)
DeleteUser(context.Context, string) (ImplResponse, error)
GetUserByName(context.Context, string) (ImplResponse, error)
LoginUser(context.Context, string, string) (ImplResponse, error)
LogoutUser(context.Context) (ImplResponse, error)
UpdateUser(context.Context, string, User) (ImplResponse, error)
}

View File

@ -0,0 +1,275 @@
/*
* OpenAPI Petstore
*
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package petstoreserver
import (
"encoding/json"
"net/http"
"strings"
"github.com/go-chi/chi/v5"
)
// PetApiController binds http requests to an api service and writes the service results to the http response
type PetApiController struct {
service PetApiServicer
errorHandler ErrorHandler
}
// PetApiOption for how the controller is set up.
type PetApiOption func(*PetApiController)
// WithPetApiErrorHandler inject ErrorHandler into controller
func WithPetApiErrorHandler(h ErrorHandler) PetApiOption {
return func(c *PetApiController) {
c.errorHandler = h
}
}
// NewPetApiController creates a default api controller
func NewPetApiController(s PetApiServicer, opts ...PetApiOption) Router {
controller := &PetApiController{
service: s,
errorHandler: DefaultErrorHandler,
}
for _, opt := range opts {
opt(controller)
}
return controller
}
// Routes returns all of the api route for the PetApiController
func (c *PetApiController) Routes() Routes {
return Routes{
{
"AddPet",
strings.ToUpper("Post"),
"/v2/pet",
c.AddPet,
},
{
"DeletePet",
strings.ToUpper("Delete"),
"/v2/pet/{petId}",
c.DeletePet,
},
{
"FindPetsByStatus",
strings.ToUpper("Get"),
"/v2/pet/findByStatus",
c.FindPetsByStatus,
},
{
"FindPetsByTags",
strings.ToUpper("Get"),
"/v2/pet/findByTags",
c.FindPetsByTags,
},
{
"GetPetById",
strings.ToUpper("Get"),
"/v2/pet/{petId}",
c.GetPetById,
},
{
"UpdatePet",
strings.ToUpper("Put"),
"/v2/pet",
c.UpdatePet,
},
{
"UpdatePetWithForm",
strings.ToUpper("Post"),
"/v2/pet/{petId}",
c.UpdatePetWithForm,
},
{
"UploadFile",
strings.ToUpper("Post"),
"/v2/pet/{petId}/uploadImage",
c.UploadFile,
},
}
}
// AddPet - Add a new pet to the store
func (c *PetApiController) AddPet(w http.ResponseWriter, r *http.Request) {
pet := Pet{}
d := json.NewDecoder(r.Body)
d.DisallowUnknownFields()
if err := d.Decode(&pet); err != nil {
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
if err := AssertPetRequired(pet); err != nil {
c.errorHandler(w, r, err, nil)
return
}
result, err := c.service.AddPet(r.Context(), pet)
// If an error occurred, encode the error with the status code
if err != nil {
c.errorHandler(w, r, err, &result)
return
}
// 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) {
petId, err := parseInt64Parameter(chi.URLParam(r, "petId"), true)
if err != nil {
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
apiKey := r.Header.Get("api_key")
result, err := c.service.DeletePet(r.Context(), petId, apiKey)
// If an error occurred, encode the error with the status code
if err != nil {
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
EncodeJSONResponse(result.Body, &result.Code, result.Headers, w)
}
// FindPetsByStatus - Finds Pets by status
func (c *PetApiController) FindPetsByStatus(w http.ResponseWriter, r *http.Request) {
query := r.URL.Query()
status := strings.Split(query.Get("status"), ",")
result, err := c.service.FindPetsByStatus(r.Context(), status)
// If an error occurred, encode the error with the status code
if err != nil {
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
EncodeJSONResponse(result.Body, &result.Code, result.Headers, w)
}
// FindPetsByTags - Finds Pets by tags
// Deprecated
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 occurred, encode the error with the status code
if err != nil {
c.errorHandler(w, r, err, &result)
return
}
// 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) {
petId, err := parseInt64Parameter(chi.URLParam(r, "petId"), true)
if err != nil {
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
result, err := c.service.GetPetById(r.Context(), petId)
// If an error occurred, encode the error with the status code
if err != nil {
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
EncodeJSONResponse(result.Body, &result.Code, result.Headers, w)
}
// UpdatePet - Update an existing pet
func (c *PetApiController) UpdatePet(w http.ResponseWriter, r *http.Request) {
pet := Pet{}
d := json.NewDecoder(r.Body)
d.DisallowUnknownFields()
if err := d.Decode(&pet); err != nil {
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
if err := AssertPetRequired(pet); err != nil {
c.errorHandler(w, r, err, nil)
return
}
result, err := c.service.UpdatePet(r.Context(), pet)
// If an error occurred, encode the error with the status code
if err != nil {
c.errorHandler(w, r, err, &result)
return
}
// 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) {
if err := r.ParseForm(); err != nil {
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
petId, err := parseInt64Parameter(chi.URLParam(r, "petId"), true)
if err != nil {
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
name := r.FormValue("name")
status := r.FormValue("status")
result, err := c.service.UpdatePetWithForm(r.Context(), petId, name, status)
// If an error occurred, encode the error with the status code
if err != nil {
c.errorHandler(w, r, err, &result)
return
}
// 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) {
if err := r.ParseMultipartForm(32 << 20); err != nil {
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
petId, err := parseInt64Parameter(chi.URLParam(r, "petId"), true)
if err != nil {
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
additionalMetadata := r.FormValue("additionalMetadata")
file, err := ReadFormFileToTempFile(r, "file")
if err != nil {
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
result, err := c.service.UploadFile(r.Context(), petId, additionalMetadata, file)
// If an error occurred, encode the error with the status code
if err != nil {
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
EncodeJSONResponse(result.Body, &result.Code, result.Headers, w)
}

View File

@ -0,0 +1,142 @@
/*
* OpenAPI Petstore
*
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package petstoreserver
import (
"context"
"net/http"
"errors"
"os"
)
// PetApiService is a service that implents the logic for the PetApiServicer
// This service should implement the business logic for every endpoint for the PetApi API.
// Include any external packages or services that will be required by this service.
type PetApiService struct {
}
// NewPetApiService creates a default api service
func NewPetApiService() PetApiServicer {
return &PetApiService{}
}
// AddPet - Add a new pet to the store
func (s *PetApiService) AddPet(ctx context.Context, pet Pet) (ImplResponse, error) {
// TODO - update AddPet with the required logic for this service method.
// Add api_pet_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation.
//TODO: Uncomment the next line to return response Response(200, Pet{}) or use other options such as http.Ok ...
//return Response(200, Pet{}), nil
//TODO: Uncomment the next line to return response Response(405, {}) or use other options such as http.Ok ...
//return Response(405, nil),nil
return Response(http.StatusNotImplemented, nil), errors.New("AddPet method not implemented")
}
// DeletePet - Deletes a pet
func (s *PetApiService) DeletePet(ctx context.Context, petId int64, apiKey string) (ImplResponse, error) {
// TODO - update DeletePet with the required logic for this service method.
// Add api_pet_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation.
//TODO: Uncomment the next line to return response Response(400, {}) or use other options such as http.Ok ...
//return Response(400, nil),nil
return Response(http.StatusNotImplemented, nil), errors.New("DeletePet method not implemented")
}
// FindPetsByStatus - Finds Pets by status
func (s *PetApiService) FindPetsByStatus(ctx context.Context, status []string) (ImplResponse, error) {
// TODO - update FindPetsByStatus with the required logic for this service method.
// Add api_pet_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation.
//TODO: Uncomment the next line to return response Response(200, []Pet{}) or use other options such as http.Ok ...
//return Response(200, []Pet{}), nil
//TODO: Uncomment the next line to return response Response(400, {}) or use other options such as http.Ok ...
//return Response(400, nil),nil
return Response(http.StatusNotImplemented, nil), errors.New("FindPetsByStatus method not implemented")
}
// FindPetsByTags - Finds Pets by tags
// Deprecated
func (s *PetApiService) FindPetsByTags(ctx context.Context, tags []string) (ImplResponse, error) {
// TODO - update FindPetsByTags with the required logic for this service method.
// Add api_pet_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation.
//TODO: Uncomment the next line to return response Response(200, []Pet{}) or use other options such as http.Ok ...
//return Response(200, []Pet{}), nil
//TODO: Uncomment the next line to return response Response(400, {}) or use other options such as http.Ok ...
//return Response(400, nil),nil
return Response(http.StatusNotImplemented, nil), errors.New("FindPetsByTags method not implemented")
}
// GetPetById - Find pet by ID
func (s *PetApiService) GetPetById(ctx context.Context, petId int64) (ImplResponse, error) {
// TODO - update GetPetById with the required logic for this service method.
// Add api_pet_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation.
//TODO: Uncomment the next line to return response Response(200, Pet{}) or use other options such as http.Ok ...
//return Response(200, Pet{}), nil
//TODO: Uncomment the next line to return response Response(400, {}) or use other options such as http.Ok ...
//return Response(400, nil),nil
//TODO: Uncomment the next line to return response Response(404, {}) or use other options such as http.Ok ...
//return Response(404, nil),nil
return Response(http.StatusNotImplemented, nil), errors.New("GetPetById method not implemented")
}
// UpdatePet - Update an existing pet
func (s *PetApiService) UpdatePet(ctx context.Context, pet Pet) (ImplResponse, error) {
// TODO - update UpdatePet with the required logic for this service method.
// Add api_pet_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation.
//TODO: Uncomment the next line to return response Response(200, Pet{}) or use other options such as http.Ok ...
//return Response(200, Pet{}), nil
//TODO: Uncomment the next line to return response Response(400, {}) or use other options such as http.Ok ...
//return Response(400, nil),nil
//TODO: Uncomment the next line to return response Response(404, {}) or use other options such as http.Ok ...
//return Response(404, nil),nil
//TODO: Uncomment the next line to return response Response(405, {}) or use other options such as http.Ok ...
//return Response(405, nil),nil
return Response(http.StatusNotImplemented, nil), errors.New("UpdatePet method not implemented")
}
// UpdatePetWithForm - Updates a pet in the store with form data
func (s *PetApiService) UpdatePetWithForm(ctx context.Context, petId int64, name string, status string) (ImplResponse, error) {
// TODO - update UpdatePetWithForm with the required logic for this service method.
// Add api_pet_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation.
//TODO: Uncomment the next line to return response Response(405, {}) or use other options such as http.Ok ...
//return Response(405, nil),nil
return Response(http.StatusNotImplemented, nil), errors.New("UpdatePetWithForm method not implemented")
}
// UploadFile - uploads an image
func (s *PetApiService) UploadFile(ctx context.Context, petId int64, additionalMetadata string, file *os.File) (ImplResponse, error) {
// TODO - update UploadFile with the required logic for this service method.
// Add api_pet_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation.
//TODO: Uncomment the next line to return response Response(200, ApiResponse{}) or use other options such as http.Ok ...
//return Response(200, ApiResponse{}), nil
return Response(http.StatusNotImplemented, nil), errors.New("UploadFile method not implemented")
}

View File

@ -0,0 +1,149 @@
/*
* OpenAPI Petstore
*
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package petstoreserver
import (
"encoding/json"
"net/http"
"strings"
"github.com/go-chi/chi/v5"
)
// StoreApiController binds http requests to an api service and writes the service results to the http response
type StoreApiController struct {
service StoreApiServicer
errorHandler ErrorHandler
}
// StoreApiOption for how the controller is set up.
type StoreApiOption func(*StoreApiController)
// WithStoreApiErrorHandler inject ErrorHandler into controller
func WithStoreApiErrorHandler(h ErrorHandler) StoreApiOption {
return func(c *StoreApiController) {
c.errorHandler = h
}
}
// NewStoreApiController creates a default api controller
func NewStoreApiController(s StoreApiServicer, opts ...StoreApiOption) Router {
controller := &StoreApiController{
service: s,
errorHandler: DefaultErrorHandler,
}
for _, opt := range opts {
opt(controller)
}
return controller
}
// Routes returns all of the api route for the StoreApiController
func (c *StoreApiController) Routes() Routes {
return Routes{
{
"DeleteOrder",
strings.ToUpper("Delete"),
"/v2/store/order/{orderId}",
c.DeleteOrder,
},
{
"GetInventory",
strings.ToUpper("Get"),
"/v2/store/inventory",
c.GetInventory,
},
{
"GetOrderById",
strings.ToUpper("Get"),
"/v2/store/order/{orderId}",
c.GetOrderById,
},
{
"PlaceOrder",
strings.ToUpper("Post"),
"/v2/store/order",
c.PlaceOrder,
},
}
}
// DeleteOrder - Delete purchase order by ID
func (c *StoreApiController) DeleteOrder(w http.ResponseWriter, r *http.Request) {
orderId := chi.URLParam(r, "orderId")
result, err := c.service.DeleteOrder(r.Context(), orderId)
// If an error occurred, encode the error with the status code
if err != nil {
c.errorHandler(w, r, err, &result)
return
}
// 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 occurred, encode the error with the status code
if err != nil {
c.errorHandler(w, r, err, &result)
return
}
// 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) {
orderId, err := parseInt64Parameter(chi.URLParam(r, "orderId"), true)
if err != nil {
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
result, err := c.service.GetOrderById(r.Context(), orderId)
// If an error occurred, encode the error with the status code
if err != nil {
c.errorHandler(w, r, err, &result)
return
}
// 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
func (c *StoreApiController) PlaceOrder(w http.ResponseWriter, r *http.Request) {
order := Order{}
d := json.NewDecoder(r.Body)
d.DisallowUnknownFields()
if err := d.Decode(&order); err != nil {
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
if err := AssertOrderRequired(order); err != nil {
c.errorHandler(w, r, err, nil)
return
}
result, err := c.service.PlaceOrder(r.Context(), order)
// If an error occurred, encode the error with the status code
if err != nil {
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
EncodeJSONResponse(result.Body, &result.Code, result.Headers, w)
}

View File

@ -0,0 +1,84 @@
/*
* OpenAPI Petstore
*
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package petstoreserver
import (
"context"
"net/http"
"errors"
)
// StoreApiService is a service that implents the logic for the StoreApiServicer
// This service should implement the business logic for every endpoint for the StoreApi API.
// Include any external packages or services that will be required by this service.
type StoreApiService struct {
}
// NewStoreApiService creates a default api service
func NewStoreApiService() StoreApiServicer {
return &StoreApiService{}
}
// DeleteOrder - Delete purchase order by ID
func (s *StoreApiService) DeleteOrder(ctx context.Context, orderId string) (ImplResponse, error) {
// TODO - update DeleteOrder with the required logic for this service method.
// Add api_store_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation.
//TODO: Uncomment the next line to return response Response(400, {}) or use other options such as http.Ok ...
//return Response(400, nil),nil
//TODO: Uncomment the next line to return response Response(404, {}) or use other options such as http.Ok ...
//return Response(404, nil),nil
return Response(http.StatusNotImplemented, nil), errors.New("DeleteOrder method not implemented")
}
// GetInventory - Returns pet inventories by status
func (s *StoreApiService) GetInventory(ctx context.Context) (ImplResponse, error) {
// TODO - update GetInventory with the required logic for this service method.
// Add api_store_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation.
//TODO: Uncomment the next line to return response Response(200, map[string]int32{}) or use other options such as http.Ok ...
//return Response(200, map[string]int32{}), nil
return Response(http.StatusNotImplemented, nil), errors.New("GetInventory method not implemented")
}
// GetOrderById - Find purchase order by ID
func (s *StoreApiService) GetOrderById(ctx context.Context, orderId int64) (ImplResponse, error) {
// TODO - update GetOrderById with the required logic for this service method.
// Add api_store_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation.
//TODO: Uncomment the next line to return response Response(200, Order{}) or use other options such as http.Ok ...
//return Response(200, Order{}), nil
//TODO: Uncomment the next line to return response Response(400, {}) or use other options such as http.Ok ...
//return Response(400, nil),nil
//TODO: Uncomment the next line to return response Response(404, {}) or use other options such as http.Ok ...
//return Response(404, nil),nil
return Response(http.StatusNotImplemented, nil), errors.New("GetOrderById method not implemented")
}
// PlaceOrder - Place an order for a pet
func (s *StoreApiService) PlaceOrder(ctx context.Context, order Order) (ImplResponse, error) {
// TODO - update PlaceOrder with the required logic for this service method.
// Add api_store_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation.
//TODO: Uncomment the next line to return response Response(200, Order{}) or use other options such as http.Ok ...
//return Response(200, Order{}), nil
//TODO: Uncomment the next line to return response Response(400, {}) or use other options such as http.Ok ...
//return Response(400, nil),nil
return Response(http.StatusNotImplemented, nil), errors.New("PlaceOrder method not implemented")
}

View File

@ -0,0 +1,263 @@
/*
* OpenAPI Petstore
*
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package petstoreserver
import (
"encoding/json"
"net/http"
"strings"
"github.com/go-chi/chi/v5"
)
// UserApiController binds http requests to an api service and writes the service results to the http response
type UserApiController struct {
service UserApiServicer
errorHandler ErrorHandler
}
// UserApiOption for how the controller is set up.
type UserApiOption func(*UserApiController)
// WithUserApiErrorHandler inject ErrorHandler into controller
func WithUserApiErrorHandler(h ErrorHandler) UserApiOption {
return func(c *UserApiController) {
c.errorHandler = h
}
}
// NewUserApiController creates a default api controller
func NewUserApiController(s UserApiServicer, opts ...UserApiOption) Router {
controller := &UserApiController{
service: s,
errorHandler: DefaultErrorHandler,
}
for _, opt := range opts {
opt(controller)
}
return controller
}
// Routes returns all of the api route for the UserApiController
func (c *UserApiController) Routes() Routes {
return Routes{
{
"CreateUser",
strings.ToUpper("Post"),
"/v2/user",
c.CreateUser,
},
{
"CreateUsersWithArrayInput",
strings.ToUpper("Post"),
"/v2/user/createWithArray",
c.CreateUsersWithArrayInput,
},
{
"CreateUsersWithListInput",
strings.ToUpper("Post"),
"/v2/user/createWithList",
c.CreateUsersWithListInput,
},
{
"DeleteUser",
strings.ToUpper("Delete"),
"/v2/user/{username}",
c.DeleteUser,
},
{
"GetUserByName",
strings.ToUpper("Get"),
"/v2/user/{username}",
c.GetUserByName,
},
{
"LoginUser",
strings.ToUpper("Get"),
"/v2/user/login",
c.LoginUser,
},
{
"LogoutUser",
strings.ToUpper("Get"),
"/v2/user/logout",
c.LogoutUser,
},
{
"UpdateUser",
strings.ToUpper("Put"),
"/v2/user/{username}",
c.UpdateUser,
},
}
}
// CreateUser - Create user
func (c *UserApiController) CreateUser(w http.ResponseWriter, r *http.Request) {
user := User{}
d := json.NewDecoder(r.Body)
d.DisallowUnknownFields()
if err := d.Decode(&user); err != nil {
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
if err := AssertUserRequired(user); err != nil {
c.errorHandler(w, r, err, nil)
return
}
result, err := c.service.CreateUser(r.Context(), user)
// If an error occurred, encode the error with the status code
if err != nil {
c.errorHandler(w, r, err, &result)
return
}
// 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
func (c *UserApiController) CreateUsersWithArrayInput(w http.ResponseWriter, r *http.Request) {
user := []User{}
d := json.NewDecoder(r.Body)
d.DisallowUnknownFields()
if err := d.Decode(&user); err != nil {
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
for _, el := range user {
if err := AssertUserRequired(el); err != nil {
c.errorHandler(w, r, err, nil)
return
}
}
result, err := c.service.CreateUsersWithArrayInput(r.Context(), user)
// If an error occurred, encode the error with the status code
if err != nil {
c.errorHandler(w, r, err, &result)
return
}
// 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
func (c *UserApiController) CreateUsersWithListInput(w http.ResponseWriter, r *http.Request) {
user := []User{}
d := json.NewDecoder(r.Body)
d.DisallowUnknownFields()
if err := d.Decode(&user); err != nil {
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
for _, el := range user {
if err := AssertUserRequired(el); err != nil {
c.errorHandler(w, r, err, nil)
return
}
}
result, err := c.service.CreateUsersWithListInput(r.Context(), user)
// If an error occurred, encode the error with the status code
if err != nil {
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
EncodeJSONResponse(result.Body, &result.Code, result.Headers, w)
}
// DeleteUser - Delete user
func (c *UserApiController) DeleteUser(w http.ResponseWriter, r *http.Request) {
username := chi.URLParam(r, "username")
result, err := c.service.DeleteUser(r.Context(), username)
// If an error occurred, encode the error with the status code
if err != nil {
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
EncodeJSONResponse(result.Body, &result.Code, result.Headers, w)
}
// GetUserByName - Get user by user name
func (c *UserApiController) GetUserByName(w http.ResponseWriter, r *http.Request) {
username := chi.URLParam(r, "username")
result, err := c.service.GetUserByName(r.Context(), username)
// If an error occurred, encode the error with the status code
if err != nil {
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
EncodeJSONResponse(result.Body, &result.Code, result.Headers, w)
}
// LoginUser - Logs user into the system
func (c *UserApiController) LoginUser(w http.ResponseWriter, r *http.Request) {
query := r.URL.Query()
username := query.Get("username")
password := query.Get("password")
result, err := c.service.LoginUser(r.Context(), username, password)
// If an error occurred, encode the error with the status code
if err != nil {
c.errorHandler(w, r, err, &result)
return
}
// 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 occurred, encode the error with the status code
if err != nil {
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
EncodeJSONResponse(result.Body, &result.Code, result.Headers, w)
}
// UpdateUser - Updated user
func (c *UserApiController) UpdateUser(w http.ResponseWriter, r *http.Request) {
username := chi.URLParam(r, "username")
user := User{}
d := json.NewDecoder(r.Body)
d.DisallowUnknownFields()
if err := d.Decode(&user); err != nil {
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
if err := AssertUserRequired(user); err != nil {
c.errorHandler(w, r, err, nil)
return
}
result, err := c.service.UpdateUser(r.Context(), username, user)
// If an error occurred, encode the error with the status code
if err != nil {
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
EncodeJSONResponse(result.Body, &result.Code, result.Headers, w)
}

View File

@ -0,0 +1,131 @@
/*
* OpenAPI Petstore
*
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package petstoreserver
import (
"context"
"net/http"
"errors"
)
// UserApiService is a service that implents the logic for the UserApiServicer
// This service should implement the business logic for every endpoint for the UserApi API.
// Include any external packages or services that will be required by this service.
type UserApiService struct {
}
// NewUserApiService creates a default api service
func NewUserApiService() UserApiServicer {
return &UserApiService{}
}
// CreateUser - Create user
func (s *UserApiService) CreateUser(ctx context.Context, user User) (ImplResponse, error) {
// TODO - update CreateUser with the required logic for this service method.
// Add api_user_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation.
//TODO: Uncomment the next line to return response Response(0, {}) or use other options such as http.Ok ...
//return Response(0, nil),nil
return Response(http.StatusNotImplemented, nil), errors.New("CreateUser method not implemented")
}
// CreateUsersWithArrayInput - Creates list of users with given input array
func (s *UserApiService) CreateUsersWithArrayInput(ctx context.Context, user []User) (ImplResponse, error) {
// TODO - update CreateUsersWithArrayInput with the required logic for this service method.
// Add api_user_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation.
//TODO: Uncomment the next line to return response Response(0, {}) or use other options such as http.Ok ...
//return Response(0, nil),nil
return Response(http.StatusNotImplemented, nil), errors.New("CreateUsersWithArrayInput method not implemented")
}
// CreateUsersWithListInput - Creates list of users with given input array
func (s *UserApiService) CreateUsersWithListInput(ctx context.Context, user []User) (ImplResponse, error) {
// TODO - update CreateUsersWithListInput with the required logic for this service method.
// Add api_user_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation.
//TODO: Uncomment the next line to return response Response(0, {}) or use other options such as http.Ok ...
//return Response(0, nil),nil
return Response(http.StatusNotImplemented, nil), errors.New("CreateUsersWithListInput method not implemented")
}
// DeleteUser - Delete user
func (s *UserApiService) DeleteUser(ctx context.Context, username string) (ImplResponse, error) {
// TODO - update DeleteUser with the required logic for this service method.
// Add api_user_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation.
//TODO: Uncomment the next line to return response Response(400, {}) or use other options such as http.Ok ...
//return Response(400, nil),nil
//TODO: Uncomment the next line to return response Response(404, {}) or use other options such as http.Ok ...
//return Response(404, nil),nil
return Response(http.StatusNotImplemented, nil), errors.New("DeleteUser method not implemented")
}
// GetUserByName - Get user by user name
func (s *UserApiService) GetUserByName(ctx context.Context, username string) (ImplResponse, error) {
// TODO - update GetUserByName with the required logic for this service method.
// Add api_user_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation.
//TODO: Uncomment the next line to return response Response(200, User{}) or use other options such as http.Ok ...
//return Response(200, User{}), nil
//TODO: Uncomment the next line to return response Response(400, {}) or use other options such as http.Ok ...
//return Response(400, nil),nil
//TODO: Uncomment the next line to return response Response(404, {}) or use other options such as http.Ok ...
//return Response(404, nil),nil
return Response(http.StatusNotImplemented, nil), errors.New("GetUserByName method not implemented")
}
// LoginUser - Logs user into the system
func (s *UserApiService) LoginUser(ctx context.Context, username string, password string) (ImplResponse, error) {
// TODO - update LoginUser with the required logic for this service method.
// Add api_user_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation.
//TODO: Uncomment the next line to return response Response(200, string{}) or use other options such as http.Ok ...
//return Response(200, string{}), nil
//TODO: Uncomment the next line to return response Response(400, {}) or use other options such as http.Ok ...
//return Response(400, nil),nil
return Response(http.StatusNotImplemented, nil), errors.New("LoginUser method not implemented")
}
// LogoutUser - Logs out current logged in user session
func (s *UserApiService) LogoutUser(ctx context.Context) (ImplResponse, error) {
// TODO - update LogoutUser with the required logic for this service method.
// Add api_user_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation.
//TODO: Uncomment the next line to return response Response(0, {}) or use other options such as http.Ok ...
//return Response(0, nil),nil
return Response(http.StatusNotImplemented, nil), errors.New("LogoutUser method not implemented")
}
// UpdateUser - Updated user
func (s *UserApiService) UpdateUser(ctx context.Context, username string, user User) (ImplResponse, error) {
// TODO - update UpdateUser with the required logic for this service method.
// Add api_user_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation.
//TODO: Uncomment the next line to return response Response(400, {}) or use other options such as http.Ok ...
//return Response(400, nil),nil
//TODO: Uncomment the next line to return response Response(404, {}) or use other options such as http.Ok ...
//return Response(404, nil),nil
return Response(http.StatusNotImplemented, nil), errors.New("UpdateUser method not implemented")
}

View File

@ -0,0 +1,62 @@
/*
* OpenAPI Petstore
*
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package petstoreserver
import (
"errors"
"fmt"
"net/http"
)
var (
// ErrTypeAssertionError is thrown when type an interface does not match the asserted type
ErrTypeAssertionError = errors.New("unable to assert type")
)
// ParsingError indicates that an error has occurred when parsing request parameters
type ParsingError struct {
Err error
}
func (e *ParsingError) Unwrap() error {
return e.Err
}
func (e *ParsingError) Error() string {
return e.Err.Error()
}
// RequiredError indicates that an error has occurred when parsing request parameters
type RequiredError struct {
Field string
}
func (e *RequiredError) Error() string {
return fmt.Sprintf("required field '%s' is zero value.", e.Field)
}
// ErrorHandler defines the required method for handling error. You may implement it and inject this into a controller if
// you would like errors to be handled differently from the DefaultErrorHandler
type ErrorHandler func(w http.ResponseWriter, r *http.Request, err error, result *ImplResponse)
// DefaultErrorHandler defines the default logic on how to handle errors from the controller. Any errors from parsing
// request params will return a StatusBadRequest. Otherwise, the error code originating from the servicer will be used.
func DefaultErrorHandler(w http.ResponseWriter, r *http.Request, err error, result *ImplResponse) {
if _, ok := err.(*ParsingError); ok {
// Handle parsing errors
EncodeJSONResponse(err.Error(), func(i int) *int { return &i }(http.StatusBadRequest), map[string][]string{}, w)
} else if _, ok := err.(*RequiredError); ok {
// Handle missing required errors
EncodeJSONResponse(err.Error(), func(i int) *int { return &i }(http.StatusUnprocessableEntity), map[string][]string{}, w)
} else {
// Handle all other errors
EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w)
}
}

View File

@ -0,0 +1,64 @@
/*
* OpenAPI Petstore
*
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package petstoreserver
import (
"reflect"
)
// Response return a ImplResponse struct filled
func Response(code int, body interface{}) ImplResponse {
return ImplResponse {
Code: code,
Headers: nil,
Body: body,
}
}
// ResponseWithHeaders return a ImplResponse struct filled, including headers
func ResponseWithHeaders(code int, headers map[string][]string, body interface{}) ImplResponse {
return ImplResponse {
Code: code,
Headers: headers,
Body: body,
}
}
// IsZeroValue checks if the val is the zero-ed value.
func IsZeroValue(val interface{}) bool {
return val == nil || reflect.DeepEqual(val, reflect.Zero(reflect.TypeOf(val)).Interface())
}
// AssertInterfaceRequired recursively checks each struct in a slice against the callback.
// This method traverse nested slices in a preorder fashion.
func AssertRecurseInterfaceRequired(obj interface{}, callback func(interface{}) error) error {
return AssertRecurseValueRequired(reflect.ValueOf(obj), callback)
}
// AssertNestedValueRequired checks each struct in the nested slice against the callback.
// This method traverse nested slices in a preorder fashion.
func AssertRecurseValueRequired(value reflect.Value, callback func(interface{}) error) error {
switch value.Kind() {
// If it is a struct we check using callback
case reflect.Struct:
if err := callback(value.Interface()); err != nil {
return err
}
// If it is a slice we continue recursion
case reflect.Slice:
for i := 0; i < value.Len(); i += 1 {
if err := AssertRecurseValueRequired(value.Index(i), callback); err != nil {
return err
}
}
}
return nil
}

View File

@ -0,0 +1,17 @@
/*
* OpenAPI Petstore
*
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package petstoreserver
//Implementation response defines an error code with the associated body
type ImplResponse struct {
Code int
Headers map[string][]string
Body interface{}
}

View File

@ -0,0 +1,32 @@
/*
* OpenAPI Petstore
*
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package petstoreserver
import (
"log"
"net/http"
"time"
)
func Logger(inner http.Handler, name string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
inner.ServeHTTP(w, r)
log.Printf(
"%s %s %s %s",
r.Method,
r.RequestURI,
name,
time.Since(start),
)
})
}

View File

@ -0,0 +1,37 @@
/*
* OpenAPI Petstore
*
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package petstoreserver
// 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"`
}
// AssertApiResponseRequired checks if the required fields are not zero-ed
func AssertApiResponseRequired(obj ApiResponse) error {
return nil
}
// AssertRecurseApiResponseRequired recursively checks if required fields are not zero-ed in a nested slice.
// Accepts only nested slice of ApiResponse (e.g. [][]ApiResponse), otherwise ErrTypeAssertionError is thrown.
func AssertRecurseApiResponseRequired(objSlice interface{}) error {
return AssertRecurseInterfaceRequired(objSlice, func(obj interface{}) error {
aApiResponse, ok := obj.(ApiResponse)
if !ok {
return ErrTypeAssertionError
}
return AssertApiResponseRequired(aApiResponse)
})
}

View File

@ -0,0 +1,35 @@
/*
* OpenAPI Petstore
*
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package petstoreserver
// Category - A category for a pet
type Category struct {
Id int64 `json:"id,omitempty"`
Name string `json:"name,omitempty"`
}
// AssertCategoryRequired checks if the required fields are not zero-ed
func AssertCategoryRequired(obj Category) error {
return nil
}
// AssertRecurseCategoryRequired recursively checks if required fields are not zero-ed in a nested slice.
// Accepts only nested slice of Category (e.g. [][]Category), otherwise ErrTypeAssertionError is thrown.
func AssertRecurseCategoryRequired(objSlice interface{}) error {
return AssertRecurseInterfaceRequired(objSlice, func(obj interface{}) error {
aCategory, ok := obj.(Category)
if !ok {
return ErrTypeAssertionError
}
return AssertCategoryRequired(aCategory)
})
}

View File

@ -0,0 +1,64 @@
/*
* OpenAPI Petstore
*
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package petstoreserver
import (
"time"
)
// Order - An order for a pets from the pet store
type Order struct {
SpecialInfo
Id int64 `json:"id,omitempty"`
// Order Status
Status string `json:"status,omitempty"`
Complete bool `json:"complete,omitempty"`
Comment *string `json:"comment"`
PetId int64 `json:"petId,omitempty"`
Quantity int32 `json:"quantity,omitempty"`
ShipDate time.Time `json:"shipDate,omitempty"`
}
// AssertOrderRequired checks if the required fields are not zero-ed
func AssertOrderRequired(obj Order) error {
elements := map[string]interface{}{
"comment": obj.Comment,
}
for name, el := range elements {
if isZero := IsZeroValue(el); isZero {
return &RequiredError{Field: name}
}
}
if err := AssertSpecialInfoRequired(obj.SpecialInfo); err != nil {
return err
}
return nil
}
// AssertRecurseOrderRequired recursively checks if required fields are not zero-ed in a nested slice.
// Accepts only nested slice of Order (e.g. [][]Order), otherwise ErrTypeAssertionError is thrown.
func AssertRecurseOrderRequired(objSlice interface{}) error {
return AssertRecurseInterfaceRequired(objSlice, func(obj interface{}) error {
aOrder, ok := obj.(Order)
if !ok {
return ErrTypeAssertionError
}
return AssertOrderRequired(aOrder)
})
}

View File

@ -0,0 +1,41 @@
/*
* OpenAPI Petstore
*
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package petstoreserver
import (
"time"
)
// OrderInfo - An order info for a pets from the pet store
type OrderInfo struct {
PetId int64 `json:"petId,omitempty"`
Quantity int32 `json:"quantity,omitempty"`
ShipDate time.Time `json:"shipDate,omitempty"`
}
// AssertOrderInfoRequired checks if the required fields are not zero-ed
func AssertOrderInfoRequired(obj OrderInfo) error {
return nil
}
// AssertRecurseOrderInfoRequired recursively checks if required fields are not zero-ed in a nested slice.
// Accepts only nested slice of OrderInfo (e.g. [][]OrderInfo), otherwise ErrTypeAssertionError is thrown.
func AssertRecurseOrderInfoRequired(objSlice interface{}) error {
return AssertRecurseInterfaceRequired(objSlice, func(obj interface{}) error {
aOrderInfo, ok := obj.(OrderInfo)
if !ok {
return ErrTypeAssertionError
}
return AssertOrderInfoRequired(aOrderInfo)
})
}

View File

@ -0,0 +1,66 @@
/*
* OpenAPI Petstore
*
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package petstoreserver
// 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"`
}
// AssertPetRequired checks if the required fields are not zero-ed
func AssertPetRequired(obj Pet) error {
elements := map[string]interface{}{
"name": obj.Name,
"photoUrls": obj.PhotoUrls,
}
for name, el := range elements {
if isZero := IsZeroValue(el); isZero {
return &RequiredError{Field: name}
}
}
if obj.Category != nil {
if err := AssertCategoryRequired(*obj.Category); err != nil {
return err
}
}
if obj.Tags != nil {
for _, el := range *obj.Tags {
if err := AssertTagRequired(el); err != nil {
return err
}
}
}
return nil
}
// AssertRecursePetRequired recursively checks if required fields are not zero-ed in a nested slice.
// Accepts only nested slice of Pet (e.g. [][]Pet), otherwise ErrTypeAssertionError is thrown.
func AssertRecursePetRequired(objSlice interface{}) error {
return AssertRecurseInterfaceRequired(objSlice, func(obj interface{}) error {
aPet, ok := obj.(Pet)
if !ok {
return ErrTypeAssertionError
}
return AssertPetRequired(aPet)
})
}

View File

@ -0,0 +1,35 @@
/*
* OpenAPI Petstore
*
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package petstoreserver
// SpecialInfo - An order info for a pets from the pet store
type SpecialInfo struct {
Promotion bool `json:"promotion,omitempty"`
Type string `json:"type,omitempty"`
}
// AssertSpecialInfoRequired checks if the required fields are not zero-ed
func AssertSpecialInfoRequired(obj SpecialInfo) error {
return nil
}
// AssertRecurseSpecialInfoRequired recursively checks if required fields are not zero-ed in a nested slice.
// Accepts only nested slice of SpecialInfo (e.g. [][]SpecialInfo), otherwise ErrTypeAssertionError is thrown.
func AssertRecurseSpecialInfoRequired(objSlice interface{}) error {
return AssertRecurseInterfaceRequired(objSlice, func(obj interface{}) error {
aSpecialInfo, ok := obj.(SpecialInfo)
if !ok {
return ErrTypeAssertionError
}
return AssertSpecialInfoRequired(aSpecialInfo)
})
}

View File

@ -0,0 +1,35 @@
/*
* OpenAPI Petstore
*
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package petstoreserver
// Tag - A tag for a pet
type Tag struct {
Id int64 `json:"id,omitempty"`
Name string `json:"name,omitempty"`
}
// AssertTagRequired checks if the required fields are not zero-ed
func AssertTagRequired(obj Tag) error {
return nil
}
// AssertRecurseTagRequired recursively checks if required fields are not zero-ed in a nested slice.
// Accepts only nested slice of Tag (e.g. [][]Tag), otherwise ErrTypeAssertionError is thrown.
func AssertRecurseTagRequired(objSlice interface{}) error {
return AssertRecurseInterfaceRequired(objSlice, func(obj interface{}) error {
aTag, ok := obj.(Tag)
if !ok {
return ErrTypeAssertionError
}
return AssertTagRequired(aTag)
})
}

View File

@ -0,0 +1,68 @@
/*
* OpenAPI Petstore
*
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package petstoreserver
// 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"`
// An array 1-deep.
DeepSliceModel *[][][]Tag `json:"deepSliceModel"`
// An array 1-deep.
DeepSliceMap [][]map[string]interface{} `json:"deepSliceMap,omitempty"`
}
// AssertUserRequired checks if the required fields are not zero-ed
func AssertUserRequired(obj User) error {
elements := map[string]interface{}{
"deepSliceModel": obj.DeepSliceModel,
}
for name, el := range elements {
if isZero := IsZeroValue(el); isZero {
return &RequiredError{Field: name}
}
}
if obj.DeepSliceModel != nil {
if err := AssertRecurseTagRequired(*obj.DeepSliceModel); err != nil {
return err
}
}
return nil
}
// AssertRecurseUserRequired recursively checks if required fields are not zero-ed in a nested slice.
// Accepts only nested slice of User (e.g. [][]User), otherwise ErrTypeAssertionError is thrown.
func AssertRecurseUserRequired(objSlice interface{}) error {
return AssertRecurseInterfaceRequired(objSlice, func(obj interface{}) error {
aUser, ok := obj.(User)
if !ok {
return ErrTypeAssertionError
}
return AssertUserRequired(aUser)
})
}

View File

@ -0,0 +1,221 @@
/*
* OpenAPI Petstore
*
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package petstoreserver
import (
"encoding/json"
"errors"
"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
"io/ioutil"
"mime/multipart"
"net/http"
"os"
"strconv"
"strings"
)
// A Route defines the parameters for an api endpoint
type Route struct {
Name string
Method string
Pattern string
HandlerFunc http.HandlerFunc
}
// Routes are a collection of defined api endpoints
type Routes []Route
// Router defines the required methods for retrieving api routes
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) chi.Router {
router := chi.NewRouter()
router.Use(middleware.Logger)
for _, api := range routers {
for _, route := range api.Routes() {
var handler http.Handler
handler = route.HandlerFunc
router.Method(route.Method, route.Pattern, handler)
}
}
return router
}
// EncodeJSONResponse uses the json encoder to write an interface to the http response with an optional status code
func EncodeJSONResponse(i interface{}, status *int, headers map[string][]string, w http.ResponseWriter) error {
wHeader := w.Header()
if headers != nil {
for key, values := range headers {
for _, value := range values {
wHeader.Add(key, value)
}
}
}
wHeader.Set("Content-Type", "application/json; charset=UTF-8")
if status != nil {
w.WriteHeader(*status)
} else {
w.WriteHeader(http.StatusOK)
}
return json.NewEncoder(w).Encode(i)
}
// ReadFormFileToTempFile reads file data from a request form and writes it to a temporary file
func ReadFormFileToTempFile(r *http.Request, key string) (*os.File, error) {
_, fileHeader, err := r.FormFile(key)
if err != nil {
return nil, err
}
return readFileHeaderToTempFile(fileHeader)
}
// ReadFormFilesToTempFiles reads files array data from a request form and writes it to a temporary files
func ReadFormFilesToTempFiles(r *http.Request, key string) ([]*os.File, error) {
if err := r.ParseMultipartForm(32 << 20); err != nil {
return nil, err
}
files := make([]*os.File, 0, len(r.MultipartForm.File[key]))
for _, fileHeader := range r.MultipartForm.File[key] {
file, err := readFileHeaderToTempFile(fileHeader)
if err != nil {
return nil, err
}
files = append(files, file)
}
return files, nil
}
// readFileHeaderToTempFile reads multipart.FileHeader and writes it to a temporary file
func readFileHeaderToTempFile(fileHeader *multipart.FileHeader) (*os.File, error) {
formFile, err := fileHeader.Open()
if err != nil {
return nil, err
}
defer formFile.Close()
fileBytes, err := ioutil.ReadAll(formFile)
if err != nil {
return nil, err
}
file, err := ioutil.TempFile("", fileHeader.Filename)
if err != nil {
return nil, err
}
defer file.Close()
file.Write(fileBytes)
return file, nil
}
// 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, 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
}
// parseBoolParameter parses a string parameter to a bool
func parseBoolParameter(param string) (bool, error) {
val, err := strconv.ParseBool(param)
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
}

View File

@ -0,0 +1,34 @@
/*
* OpenAPI Petstore
*
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package main
import (
"log"
"net/http"
petstoreserver "github.com/GIT_USER_ID/GIT_REPO_ID/go"
)
func main() {
log.Printf("Server started")
PetApiService := petstoreserver.NewPetApiService()
PetApiController := petstoreserver.NewPetApiController(PetApiService)
StoreApiService := petstoreserver.NewStoreApiService()
StoreApiController := petstoreserver.NewStoreApiController(StoreApiService)
UserApiService := petstoreserver.NewUserApiService()
UserApiController := petstoreserver.NewUserApiController(UserApiService)
router := petstoreserver.NewRouter(PetApiController, StoreApiController, UserApiController)
log.Fatal(http.ListenAndServe(":8080", router))
}