Skip to content

Conversation

@dbarrosop
Copy link
Contributor

@dbarrosop dbarrosop commented Aug 7, 2025

This allows uploading arbitrary files treating them as binary by specifying a schema like:

  /files/:
    post:
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                file[]:
                  type: array
                  items:
                    type: string
                    format: binary <----- this is the important bit
              required:
                - file[]

without having to add openapi3filter.RegisterBodyDecoder("some/thing", openapi3filter.FileBodyDecoder) for every particular type of file that users might be uploading and for which we may have no knowledge of ahead of time when building a service to upload arbitrary files.

I don't think this is currently supported in any other way, I don't think so.

@dbarrosop
Copy link
Contributor Author

dbarrosop commented Aug 7, 2025

I am a bit confused about the failing tests, go test ./... works without any issues but go test -count=10 ./... fails. Why is that? Do you know?

P.S: Looks like my test is creating some side-effects on the other tests as removing it fixes the problem but running it standalone works fine...

P.S2: It turns out the existing upload zip test was polluting the environment and needed a cleanup

@fenollp fenollp changed the title use FileBodyDecoder if the format is specified as binary openapi3filter: use FileBodyDecoder if the format is specified as binary Aug 7, 2025
@fenollp fenollp merged commit 6acf92b into getkin:master Aug 7, 2025
5 checks passed
@fenollp
Copy link
Collaborator

fenollp commented Aug 7, 2025

Thanks! Also, I love nhost :)

@mieltn
Copy link
Contributor

mieltn commented Sep 4, 2025

@fenollp @dbarrosop
hi guys, i think there might be an issue here
i have

...
attachment:
    type: string
    format: binary
...

it is a field of multipart form, when the attachment sent has a header of type registered in init, it will try to decode it with registered decoder, while i expect FileBodyDecoder on binary fields

maybe we could do something like

mediaType := parseMediaType(contentType)
if isBinary(schema) {
	value, err := FileBodyDecoder(body, header, schema, encFn)
	return mediaType, value, err
}

decoder, ok := bodyDecoders[mediaType]
if !ok {
	return "", nil, &ParseError{
		Kind:   KindUnsupportedFormat,
		Reason: fmt.Sprintf("%s %q", prefixUnsupportedCT, mediaType),
	}
}

@dbarrosop
Copy link
Contributor Author

dbarrosop commented Sep 5, 2025

Hello,
I think your proposal makes sense. It might complicates things a bit but IMO kin-openapi should always use the FileBodyDecoder and only use a special decoder if the spec defines a encoding. For instance:

openapi: 3.0.3
info:
  title: File Upload API
  version: 1.0.0
paths:
  /upload:
    post:
      summary: Upload a file
      description: Use always FileBodyDecoder
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                file:
                  type: string
                  format: binary
                  description: The file to upload
                description:
                  type: string
                  description: File description (optional)
              required:
                - file
            encoding:
              file:
                contentType: application/octet-stream
        ...
  /upload/known-types:
    post:
      summary: Upload known file types
      description: Use more specific decoders
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                yamlFile:
                  type: string
                  format: binary
                  description: YAML file only - server validates content type and format
                metadata:
                  type: object
                  properties:
                    name:
                      type: string
                    version:
                      type: string
              required:
                - yamlFile
            encoding:
              yamlFile:
                contentType: 
                  - application/yaml
                  - text/yaml
                  - application/x-yaml
                # This restricts what content types are acceptable
       ...

This is a big breaking change though so it might be tricky to implement

@mieltn
Copy link
Contributor

mieltn commented Sep 5, 2025

thanks for getting back, i agree that being able to add multiple content types as a list in the encoding object would be convenient, but as you said, its a breaking change

i think it might make life a bit easier if we support FileBodyDecoder by default on binary field, and as before, you will be able to specify content-type in the encoding object, that encoding content type will be used for contentType validation

could you look into the code?

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.

3 participants