swagger-api / swagger-api/swagger-codegen
text/plain results in an undefined response type with Golang Swagger
Nobody has claimed this yet.
- Dominant language
- Mustache
- Stars
- 17.8k
- Forks
- 6k
- PR merge metrics
- No merged PRs in 30d
Description
Description
Hello, when im generating Golang code for a simple endpoint that returns plain text the generated client runs in an error:
undefined response type . I added the code snippets below.
Swagger-codegen version
2.0
Swagger declaration file content or url
---
swagger: "2.0"
info:
description: "something"
version: "v2.6"
title: "something"
contact:
email: "something@something.de"
host: "something.de"
tags:
- name: "administration"
description: "Meta services"
schemes:
- "https"
- "http"
consumes:
- "application/json"
produces:
- "application/json"
security:
- basicAuth: []
paths:
/about/version:
get:
tags:
- "administration"
summary: "current software version"
description: "Returns the current something version"
produces:
- "text/plain"
parameters: []
responses:
"200":
description: "successful operation"
schema:
type: "string"
example: "1.9.44-04345"
"400":
description: "bad request"
schema:
$ref: "#/definitions/ErrorMessage"
"500":
description: "internal server error"
schema:
$ref: "#/definitions/ErrorMessage"
securityDefinitions:
basicAuth:
type: "basic"
definitions:
ErrorMessage:
type: "object"
properties:
errorMessage:
type: "string"
Command line used for generation
Steps to reproduce
Generate Go Client with Swagger generator
Related issues/PRs
https://github.com/swagger-api/swagger-codegen/issues/7751
Suggest a fix/enhancement
When it now comes to decoding the response of the endpoint the generate Golang code looks like:
func (a *AdministrationApiService) AboutVersionGet(ctx context.Context) (string, *http.Response, error) {
var (
localVarHttpMethod = strings.ToUpper("Get")
localVarPostBody interface{}
localVarFileName string
localVarFileBytes []byte
localVarReturnValue string
)
// create path and map variables
localVarPath := a.client.cfg.BasePath + "/about/version"
localVarHeaderParams := make(map[string]string)
localVarQueryParams := url.Values{}
localVarFormParams := url.Values{}
// to determine the Content-Type header
localVarHttpContentTypes := []string{"application/json"}
// set Content-Type header
localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
if localVarHttpContentType != "" {
localVarHeaderParams["Content-Type"] = localVarHttpContentType
}
// to determine the Accept header
localVarHttpHeaderAccepts := []string{"text/plain"}
// set Accept header
localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
if localVarHttpHeaderAccept != "" {
localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
}
r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
if err != nil {
return localVarReturnValue, nil, err
}
localVarHttpResponse, err := a.client.callAPI(r)
if err != nil || localVarHttpResponse == nil {
return localVarReturnValue, localVarHttpResponse, err
}
localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
localVarHttpResponse.Body.Close()
if err != nil {
return localVarReturnValue, localVarHttpResponse, err
}
if localVarHttpResponse.StatusCode < 300 {
// If we succeed, return the data, otherwise pass on to decode error.
//added by issue author: normal cast form byte to string would be enough if Content-Type is plain-text
err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
return localVarReturnValue, localVarHttpResponse, err
}
if localVarHttpResponse.StatusCode >= 300 {
newErr := GenericSwaggerError{
body: localVarBody,
error: localVarHttpResponse.Status,
}
if localVarHttpResponse.StatusCode == 200 { //added by issue author: is this even reachable?
var v string
err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
if err != nil {
newErr.error = err.Error()
return localVarReturnValue, localVarHttpResponse, newErr
}
newErr.model = v
return localVarReturnValue, localVarHttpResponse, newErr
}
if localVarHttpResponse.StatusCode == 400 {
var v ErrorMessage
err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
if err != nil {
newErr.error = err.Error()
return localVarReturnValue, localVarHttpResponse, newErr
}
newErr.model = v
return localVarReturnValue, localVarHttpResponse, newErr
}
if localVarHttpResponse.StatusCode == 500 {
var v ErrorMessage
err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
if err != nil {
newErr.error = err.Error()
return localVarReturnValue, localVarHttpResponse, newErr
}
newErr.model = v
return localVarReturnValue, localVarHttpResponse, newErr
}
return localVarReturnValue, localVarHttpResponse, newErr
}
return localVarReturnValue, localVarHttpResponse, nil
}
The problem here is that the decode() function only is able to decode xml or JSON data.
What we need is cast from byte to string if the contenttype is text/plain
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 using the Swagger declaration and generated Go client shown in the report, then trace the generated client's decode() call for the text/plain response. Done means the plain-text response is returned as a string while existing JSON and XML decoding continues to work.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- api, tooling
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100