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

File upload how to describe in annotations? #2441

Open
cedricve opened this issue Nov 24, 2020 · 7 comments
Open

File upload how to describe in annotations? #2441

cedricve opened this issue Nov 24, 2020 · 7 comments
Labels
generate spec Related to spec generation from code scanner

Comments

@cedricve
Copy link

I'm trying to describe a file upload, where the request body is used for the upload of a mp4 video. I can only find examples for multipart upload, but this is not the way we handle uploads in our API.

What I'm looking for is to translate this to annotations @.

requestBody:
content:
video/mp4:
schema:
type: string
format: binary

Anyone an idea? https://swagger.io/docs/specification/describing-request-body/file-upload/

@cedricve cedricve changed the title Fileupload File upload how to describe in annotations? Nov 24, 2020
@fredbi fredbi added the generate spec Related to spec generation from code label Nov 25, 2020
@fredbi
Copy link
Contributor

fredbi commented Nov 25, 2020

See #2105

https://github.com/go-swagger/go-swagger/blob/master/fixtures/goparsing/classification/operations/noparams.go#L28-L33

The swagger way is to use form-data for files.

For binary, I don't know. Maybe you could share a minimal bit of code that builds so we could try out some ideas.

@casualjim
Copy link
Member

I looked into this, I though it should work with specifying just an io.Reader as type, but I haven't found that code

@ShiningRush
Copy link

ShiningRush commented Sep 16, 2022

Hi, is the issue have any updates?
Now my API also need to upload file, and I documented my struct as below:

// swagger:parameters putObject
type PutInput struct {
	// name
	// in: path
	// required
	Name  string        `auto_read:"name,path" json:"name" validate:"required"`
	// scene
	// in: query
	// required
	Scene string        `auto_read:"scene,query" json:"scene" validate:"required"`
	// content-length
	// in: header
	// required
	Size  int64         `auto_read:"Content-Length,header" json:"content-length" validate:"required"`
	// ttl
	// in: query
	// required
	TTL   int64         `auto_read:"ttl,query" json:"ttl"`
	// body
	// in: body
	// required
	Body  io.ReadCloser `auto_read:"@body"`
}

then generated spec is looks like below:

consumes:
    - application/json
definitions:
    Reader:
        description: |-
            Read reads up to len(p) bytes into p. It returns the number of bytes
            read (0 <= n <= len(p)) and any error encountered. Even if Read
            returns n < len(p), it may use all of p as scratch space during the call.
            If some data is available but not len(p) bytes, Read conventionally
            returns what is available instead of waiting for more.

            When Read encounters an error or end-of-file condition after
            successfully reading n > 0 bytes, it returns the number of
            bytes read. It may return the (non-nil) error from the same call
            or return the error (and n == 0) from a subsequent call.
            An instance of this general case is that a Reader returning
            a non-zero number of bytes at the end of the input stream may
            return either err == EOF or err == nil. The next Read should
            return 0, EOF.

            Callers should always process the n > 0 bytes returned before
            considering the error err. Doing so correctly handles I/O errors
            that happen after reading some bytes and also both of the
            allowed EOF behaviors.

            Implementations of Read are discouraged from returning a
            zero byte count with a nil error, except when len(p) == 0.
            Callers should treat a return of 0 and nil as indicating that
            nothing happened; in particular it does not indicate EOF.

            Implementations must not retain p.
        title: Reader is the interface that wraps the basic Read method.
        type: object
        x-go-package: io
host: localhost:6789
info:
    contact:
        email: xxxxxxxx
paths:
    /objects/{name}:
        put:
            consumes:
                - application/octet-stream
            description: xxx
            operationId: putObject
            parameters:
                - description: xxxx
                  in: path
                  name: name
                  required: true
                  type: string
                  x-go-name: Name
                - description: xxx
                  in: query
                  name: scene
                  type: string
                  x-go-name: Scene
                - description: xxxx
                  format: int64
                  in: header
                  name: content-length
                  type: integer
                  x-go-name: Size
                - description: xxxx
                  format: int64
                  in: query
                  name: ttl
                  type: integer
                  x-go-name: TTL
                - description: xxxxxxx
                  in: body
                  name: Body
                  schema:
                    $ref: '#/definitions/Reader'
            produces:
                - application/json
            schemes:
                - http
            summary: xxxxxxxx
produces:
    - application/json
schemes:
    - http
swagger: "2.0"

It looks like the go-swagger handle the io.ReadCloser as a object instead of binary.

cc@casualjim

@hunjixin
Copy link

any support for multipart form files?

@casualjim
Copy link
Member

@hunjixin
Copy link

hunjixin commented May 24, 2023

@casualjim thansk, but how to receive multiple files like

	// UploadPluginFilesParams contains the uploaded file data
	// swagger:parameters uploadPluginFilesParams
	type UploadPluginFilesParams struct {
		// Plugin file.
		//
		// in: formData
		//
		// swagger:[]file
		PluginFile []*multipart.FileHeader `json:"plugin" form:"plugin"`
	}

or something like this

@iv-menshenin
Copy link
Contributor

The same problem I solved with following hacks:
described spec

    post:
      consumes:
        - multipart/form-data
      parameters:
        - name: Content-Type
          in: header
          type: string
        - name: data
          in: body
          description: Files
          required: true
          schema:
            type: string
            format: binary

so I got the PostAttachmentsParams struct with Data io.ReadCloser

next I just parse itself with r := multipart.NewReader(params.Data, boundary)

but there is another problem with client code =) it breaks boundary in Content-Type header

Is there any solution for the case when the names of the file fields and the total number of files are not known in advance?

@fredbi fredbi added the scanner label Dec 24, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
generate spec Related to spec generation from code scanner
Projects
None yet
Development

No branches or pull requests

6 participants