Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Correctly parse format on array fields #973

Merged
merged 1 commit into from
Aug 17, 2021

Conversation

j-sv
Copy link
Contributor

@j-sv j-sv commented Aug 11, 2021

Describe the PR
The format tag used on an array type should place the format in the items object, rather than directly on the type.

Relation issue

Additional context

Examples of this are available on the Swagger website, under Array Examples here.

components:
  schemas:
    ArrayOfInt:
      type: array
      items:
        type: integer
        format: int64
        example: 1
components:
  schemas:
    ArrayOfInt:
      type: array
      items:
        type: integer
        format: int64
      example: [1, 2, 3]

When the format directive is used on an array type the indicated format
should go under the items key.
@sdghchj
Copy link
Member

sdghchj commented Aug 17, 2021

Sorry, I haven't got your point. What on earth are you discussing, example or format ?
When I tested in swagger editor the format in items object, it didn't work.

@j-sv
Copy link
Contributor Author

j-sv commented Aug 17, 2021

I'm discussing format when used on array types.

package main

import "net/http"

// @host example.com
// @BasePath /v2

func main() {
}

type Response struct {
        Values []string `json:"values" type:"array,string" format:"uuid"`
}

// @Produce  json
// @Success 200 {object} Response "ok"
// @Router /thing [get]
func Get(w http.ResponseWriter, r *http.Request) error {
        return nil
}

This generates the following YAML.

swagger: "2.0"
host: example.com
basePath: /v2
info:
  contact: {}
  description: Example
  title: Example
  version: 0.1.0
paths:
  /thing:
    get:
      produces:
      - application/json
      responses:
        "200":
          description: ok
          schema:
            $ref: '#/definitions/main.Response'
definitions:
  main.Response:
    properties:
      values:
        format: uuid
        items:
          type: string
        type: array
    type: object

That works in the Swagger editor, but the format field is placed on array type, instead of in the items object of the definition.

The example value it shows is this:

{
  "values": [
    "string"
  ]
}

If the YAML is modified so that the format field is placed under items instead, like this:

swagger: "2.0"
host: example.com
basePath: /v2
info:
  contact: {}
  description: Example
  title: Example
  version: 0.1.0
paths:
  /thing:
    get:
      produces:
      - application/json
      responses:
        "200":
          description: ok
          schema:
            $ref: '#/definitions/main.Response'
definitions:
  main.Response:
    properties:
      values:
        items:
          type: string
          format: uuid
        type: array
    type: object

The example given is instead:

{
  "values": [
    "3fa85f64-5717-4562-b3fc-2c963f66afa6"
  ]
}

The model is also correctly given as [string($uuid)].

This also makes a difference when generating e.g. models from the spec. For the first YAML go-swagger 0.27.0 will generate this code:

// MainResponse main response
//
// swagger:model main.Response
type MainResponse struct {

        // values
        Values []string `json:"values"`
}

Where the second YAML would give you:

// MainResponse main response
//
// swagger:model main.Response
type MainResponse struct {

        // values
        Values []strfmt.UUID `json:"values"`
}

Hope this made the point of the PR a bit clearer.

@sdghchj
Copy link
Member

sdghchj commented Aug 17, 2021

OK, got it.
image
As an array and its elements can each have a format, why not support both of them?

Reserve the array format and add the element format:

type Response struct {
        Values []string `json:"values" type:"array,string" format:"uuid,uuid"`
}

or

type Response struct {
        Values []string `json:"values" type:"array,string" format:"uuid" ele-format:"uuid"`
}

@j-sv
Copy link
Contributor Author

j-sv commented Aug 17, 2021

I can't find any examples where format is used on the "top level" object with type: array.

I've only found this snippet from the Swagger docs:

Unlike JSON Schema, the items keyword is required in arrays. The value of items is a schema that describes the type and format of array items.

I've interpreted that as when type: array, format should only be placed in items, as that's what described the content of the array.

If you'd prefer keeping both, I think ele-format works best, as that allows you to choose which field you want to set. Alternatively call it items-format to be consistent with generated code?

@sdghchj
Copy link
Member

sdghchj commented Aug 17, 2021

Sorry, maybe you're right.

https://swagger.io/specification/v2/#operationObject

Primitives have an optional modifier property format. Swagger uses several known formats to more finely define the data type being used. However, the format property is an open string-valued property, and can have any value to support documentation needs. Formats such as "email", "uuid", etc., can be used even though they are not defined by this specification. Types that are not accompanied by a format property follow their definition from the JSON Schema (except for file type which is defined above). `

format is intended for primitives.

Copy link
Member

@sdghchj sdghchj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@sdghchj sdghchj merged commit 497e6e2 into swaggo:master Aug 17, 2021
@j-sv j-sv deleted the support-format-on-array branch August 17, 2021 14:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants