OpenAPITools / OpenAPITools/openapi-generator
[BUG][golang] 'isCollectionFormatMulti' flag not being set to true on multiple file uploads
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 26.8k
- Forks
- 7.7k
- PR merge metrics
- PR metrics pending
Description
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?
- What's the actual output vs expected output?
- [Optional] Sponsorship to speed up the bug fix or feature request (example)
Description
A generated Golang client for an OpenAPI 3 spec that includes multi-file uploads fails to build because the array of files is generated as a single file. For example, the following snippet is from the generated api_default.go:
localVarFormFileName = "files"
var localVarFile []*os.File
if r.files != nil {
localVarFile = *r.files
}
if localVarFile != nil {
fbs, _ := _ioutil.ReadAll(localVarFile)
localVarFileBytes = fbs
localVarFileName = localVarFile.Name()
localVarFile.Close()
}
openapi-generator version
I have tried with the following versions:
| Version | Install Method |
|---|---|
| v0.5.0 | Homebrew |
| Docker | |
| v4.3.1 | Docker |
| HEAD | Homebrew |
OpenAPI declaration file content or url
openapi: 3.0.1
info:
title: API
version: "1.0"
servers:
- url: https://example.com
tags:
- name: default
description: Default namespace
paths:
/bug/{bug_id}/attachment:
post:
tags:
- default
summary: Upload a file
operationId: post_res_attach
parameters:
- name: bug_id
in: path
required: true
schema:
type: integer
requestBody:
content:
multipart/form-data:
schema:
type: object
properties:
files:
type: array
description: One or more files to upload
items:
type: string
format: binary
responses:
200:
description: Success
content: {}
401:
description: Unauthenticated
content: {}
Generation Details
openapi-generator generate --input-spec spec.yaml \
--generator-name go \
--template-dir ./generator-template \
--output ./openapi
The generator-template directory contains a single file, partial_header.mustache:
// Copyright (c) 2020 VMware, Inc. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
/*
{{#appName}}
* {{{appName}}}
*
{{/appName}}
{{#appDescription}}
* {{{appDescription}}}
*
{{/appDescription}}
{{#version}}
* API version: {{{version}}}
{{/version}}
{{#infoEmail}}
* Contact: {{{infoEmail}}}
{{/infoEmail}}
{{^withGoCodegenComment}}
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
{{/withGoCodegenComment}}
*/
{{#withGoCodegenComment}}
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
{{/withGoCodegenComment}}
Steps to reproduce
-
Switch to a temporary directory:
cd $(mktemp -d) -
Create a spec file:
cat <<EOF >spec.yaml openapi: 3.0.1 info: title: API version: "1.0" servers: - url: https://example.com tags: - name: default description: Default namespace paths: /bug/{bug_id}/attachment: post: tags: - default summary: Upload a file operationId: post_res_attach parameters: - name: bug_id in: path required: true schema: type: integer requestBody: content: multipart/form-data: schema: type: object properties: files: type: array description: One or more files to upload items: type: string format: binary responses: 200: description: Success content: {} 401: description: Unauthenticated content: {} EOF -
Create a generator template:
cat <<EOF >partial_header.mustache // Copyright (c) 2020 Company, Inc. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 /* {{#appName}} * {{{appName}}} * {{/appName}} {{#appDescription}} * {{{appDescription}}} * {{/appDescription}} {{#version}} * API version: {{{version}}} {{/version}} {{#infoEmail}} * Contact: {{{infoEmail}}} {{/infoEmail}} {{^withGoCodegenComment}} * Generated by: OpenAPI Generator (https://openapi-generator.tech) {{/withGoCodegenComment}} */ {{#withGoCodegenComment}} // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. {{/withGoCodegenComment}} EOF -
Generate the Golang code using the Open API Docker image:
docker run --rm \ -v $(pwd)/spec.yaml:/openapi/spec.yaml:ro \ -v $(pwd):/openapi/output \ -v $(pwd):/openapi/generator-template \ openapitools/openapi-generator-cli:v5.0.0 \ generate --input-spec /openapi/spec.yaml \ --generator-name go \ --template-dir /openapi/generator-template \ --output /openapi/output -
Print lines 106-116 of
api_default.goto see the incorrectly generated client:$ sed -n '106,116p' api_default.go localVarFormFileName = "files" var localVarFile []*os.File if r.files != nil { localVarFile = *r.files } if localVarFile != nil { fbs, _ := _ioutil.ReadAll(localVarFile) localVarFileBytes = fbs localVarFileName = localVarFile.Name() localVarFile.Close() }
I imagine the same lines should treat the property as a slice/collection similar to the related issue in the next section.
Related issues/PRs
The following issue and PR seemed promising:
- https://github.com/OpenAPITools/openapi-generator/issues/8093
- https://github.com/OpenAPITools/openapi-generator/pull/8103
However, it seems the fix was for the server-side handling only.
Suggest a fix
Issue https://github.com/OpenAPITools/openapi-generator/issues/8104 seems to be the same as this one, but for typescript. I believe the same fix, but for Go, should work.
Sponsorship
I'm willing to pay $100 for a quick fix on this and $150 if there's a subsequent v5.0.1 patch release with the fix (both for home-brew and the Docker image).
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the issue with the supplied spec.yaml and Go generator command, then inspect the generated api_default.go and the Go generator templates or entry points responsible for multipart file parameters. Done means the generated client treats the files property as a collection, builds successfully, and handles multiple uploaded files rather than one file.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- api, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100