Skip to content

Response schema for []byte is always generated as array of integer rather than byte/binary string #115

@brentwritescode

Description

@brentwritescode

Hello,

I'm currently running into an issue where the Swagger generated for our service definition translates Writes([]byte{}) to an array of integer in the output Swagger spec. This is causing some issues for downstream code generation where clients are incorrectly attempting to use []int rather than []byte when forming requests I saw another user mention the same thing in another issue here: #77 (comment)

To be very specific, going by https://swagger.io/docs/specification/data-models/data-types/#file, I need a way to make this translate to "type": "string" and "format": "binary" (or "byte") in the output Swagger definition. Is there a good way to do that?

I adapted one of your previous examples to show what I mean if it helps. I made a really simple API that just returns a random byte array:

package main

import (
	"crypto/rand"
	"log"
	"net/http"

	restful "github.com/emicklei/go-restful"

	restfulspec "github.com/emicklei/go-restful-openapi"
)

func getRandomBytes(size int) ([]byte, error) {
	b := make([]byte, size)
	_, err := rand.Read(b)
	if err != nil {
		return nil, err
	}
	return b, nil
}

func WebService() *restful.WebService {
	ws := new(restful.WebService)
	ws.Path("/").Produces(restful.MIME_OCTET)

	ws.Route(ws.GET("/bytes").To(getRandomBytesTest).
		Doc("get random bytes").
		Writes([]byte{}).
		Produces(restful.MIME_OCTET).
		Returns(200, "OK", []byte{}))

	return ws
}

func getRandomBytesTest(_ *restful.Request, response *restful.Response) {
	responseBytes, _ := getRandomBytes(256)
	_, _ = response.Write(responseBytes)
}

func main() {
	restful.DefaultContainer.Add(WebService())

	config := restfulspec.Config{
		WebServices: restful.RegisteredWebServices(),
		APIPath:     "/apidocs.json",
	}
	restful.DefaultContainer.Add(restfulspec.NewOpenAPIService(config))

	log.Printf("Get the API using http://localhost:8080/apidocs.json")
	log.Fatal(http.ListenAndServe(":8080", nil))
}

When running that application and visiting http://localhost:8080/apidocs.json, it produces the following Swagger:

{
 "swagger": "2.0",
 "paths": {
  "/bytes": {
   "get": {
    "produces": [
     "application/octet-stream"
    ],
    "summary": "get random bytes",
    "operationId": "getRandomBytesTest",
    "responses": {
     "200": {
      "description": "OK",
      "schema": {
       "type": "array",
       "items": {
        "type": "integer"
       }
      }
     }
    }
   }
  }
 }
}

But what I need is to be able to produce this instead for the response:

"responses": {
     "200": {
      "description": "OK",
      "schema": {
       "type": "string",
       "format": "binary"
      }
     }
    }

Is that something that would be feasible to do with the library? And if so, would you be able to suggest how I might be able to achieve that? Thank you for your time and help!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions