Skip to content

[BUG][go-server] enforcement of minimum, maximum; application of default #14013

@davewalker-wk

Description

@davewalker-wk

Bug Report Checklist

  • Have you provided a full/minimal spec to reproduce the issue?
  • Have you validated the input using an OpenAPI validator (example)?
  • Have you tested with the latest master to confirm the issue still exists?
  • Have you searched for related issues/PRs?
    • Similar issues have been raised in grander/different scales, or targeting the client implementation
  • What's the actual output vs expected output?
Description

The go-server templates ignore defined maximum, minimum, and defaults for parameters. This is problematic for optional query parameters which have default values, and minimums higher than the languages zero value for that type.

This bug (and referenced template changes) hope to address the limitation for at least integer-type path and query parameters. This issue does not aim to address the default, maximum, minimum or required-ness of fields within models. A separate issue/code will hope to address the issues with having required fields where a 0 value is a valid value exist.

openapi-generator version
openapi-generator --version
openapi-generator-cli 6.0.0
  commit : 69f79fb
  built  : 2022-05-26T02:54:15Z
OpenAPI declaration file content or url
openapi: 3.0.2
info:
  title: Min, Max, Default
  description: >
    Expose issues with go-server templates and the lack of enforcement of min max and default
  version: 0.0.0
tags:
  - name: example
paths:
  /example:
    get:
      summary: example to highlight min max and default
      parameters:
        - in: query
          name: limit
          required: false
          schema:
            type: integer
            example: 10
            default: 100
            minimum: 1
            maximum: 200
      tags:
        - example
      responses:
        "200":
          description: OK
Generation Details

Existing api_example.go(ExampleGet) and routers.go(parseInt32Parameter)

// ExampleGet - example to highlight min max and default
func (c *ExampleApiController) ExampleGet(w http.ResponseWriter, r *http.Request) {
	query := r.URL.Query()
	limitParam, err := parseInt32Parameter(query.Get("limit"), false)
	if err != nil {
		c.errorHandler(w, r, &ParsingError{Err: err}, nil)
		return
	}
	result, err := c.service.ExampleGet(r.Context(), limitParam)
	// 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, w)

}

// parseInt32Parameter parses a string parameter to an int32.
func parseInt32Parameter(param string, required bool, minVal, maxVal, defVal *int64) (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
}

Proposed/Expected of above

// ExampleGet - example to highlight min max and default
func (c *ExampleApiController) ExampleGet(w http.ResponseWriter, r *http.Request) {
	query := r.URL.Query()
	limitParam, err := parseInt32Parameter(query.Get("limit"), false, GetInt64Ptr(1), GetInt64Ptr(200), GetInt64Ptr(100))
	if err != nil {
		c.errorHandler(w, r, &ParsingError{Err: err}, nil)
		return
	}
	result, err := c.service.ExampleGet(r.Context(), limitParam)
	// 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, w)

}

// parseInt32Parameter parses a string parameter to an int32.
func parseInt32Parameter(param string, required bool, minVal, maxVal, defVal *int64) (int32, error) {
	if param == "" {
		if required {
			return 0, errors.New(errMsgRequiredMissing)
		}

		if defVal != nil {
			return int32(*defVal), nil
		}

		return 0, nil
	}

	val, err := strconv.ParseInt(param, 10, 32)
	if err != nil {
		return -1, err
	}

	if minVal != nil && val < *minVal {
		return 0, errors.New(fmt.Sprintf(errMsgMinValueConstraint, val, minVal))
	} else if maxVal != nil && val > *maxVal {
		return 0, errors.New(fmt.Sprintf(errMsgMaxValueConstraint, val, maxVal))
	}

	return int32(val), nil
}
Steps to reproduce

The bug can be replicated by having no support today.

Related issues/PRs

Related:
(client) #4579
(server most similar) #12201

Suggest a fix

Suggested fix to implement for only path/query parameters of integer values for max/min/default

https://github.com/davewalker-wk/openapi-generator/commit/5d4595c6ee4714428c1f9b63b2e0b254279240e1

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions