Repository: danielgtaylor/huma (Go)

Issue:
How to explicitly define response for a route
I want to return a binary image response from one of my routes. 

https://go.dev/play/p/YlsBFq25iaK

But the generated openapi schema has few definitions I do not want. 

```json
"paths": {
    "/image": {
      "post": {
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "contentEncoding": "base64",
                  "type": "string"
                }
              },
              "image/png": {
                "schema": {
                  "format": "binary",
                  "type": "string"
                }
              }
            },
            "description": "Image response",
            "headers": {
              "Content-Type": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        }
      }
    }
  }
```

Is it possible to change the success response to this? (remove the json response and content-type header)

```json
  "200": {
    "content": {
      "image/png": {
        "schema": {
          "format": "binary",
          "type": "string"
        }
      }
    },
    "description": "Image response"
  }
```


Discussion:
@amsal the fact that `application/json` is present appears to be a bug, thanks for reporting! I'll fix this ASAP.

As for the `Content-Type` header, Huma will document every header in your response and that is by design. I recommend keeping it, but if you absolutely want to remove it you can do so:

```go
delete(api.OpenAPI().Paths["/image"].Post.Responses["200"].Headers, "Content-Type")
```

https://go.dev/play/p/8OR1Ft4BYAY
@amsal the extra `application/json` response should be fixed in #247, and I'll publish a new release with the fix soon.



Patch:
diff --git a/huma.go b/huma.go
index 5219847c..dd277b99 100644
--- a/huma.go
+++ b/huma.go
@@ -612,10 +612,10 @@ func Register[I, O any](api API, op Operation, handler func(context.Context, *I)
 			if op.Responses[statusStr].Content == nil {
 				op.Responses[statusStr].Content = map[string]*MediaType{}
 			}
-			if _, ok := op.Responses[statusStr].Content["application/json"]; !ok {
+			if len(op.Responses[statusStr].Content) == 0 {
 				op.Responses[statusStr].Content["application/json"] = &MediaType{}
 			}
-			if op.Responses[statusStr].Content["application/json"].Schema == nil {
+			if op.Responses[statusStr].Content["application/json"] != nil && op.Responses[statusStr].Content["application/json"].Schema == nil {
 				op.Responses[statusStr].Content["application/json"].Schema = outSchema
 			}
 		}


Test patch:
diff --git a/huma_test.go b/huma_test.go
index d52f844a..0892b379 100644
--- a/huma_test.go
+++ b/huma_test.go
@@ -508,6 +508,42 @@ func TestFeatures(t *testing.T) {
 				assert.Equal(t, `hello`, resp.Body.String())
 			},
 		},
+		{
+			Name: "response-image",
+			Register: func(t *testing.T, api huma.API) {
+				type Resp struct {
+					ContentType string `header:"Content-Type"`
+					Body        []byte
+				}
+
+				huma.Register(api, huma.Operation{
+					Method: http.MethodGet,
+					Path:   "/response-image",
+					Responses: map[string]*huma.Response{
+						"200": {
+							Description: "Image response",
+							Content: map[string]*huma.MediaType{
+								"image/png": {
+									Schema: &huma.Schema{Type: "string", Format: "binary"},
+								},
+							},
+						},
+					},
+				}, func(ctx context.Context, input *struct{}) (*Resp, error) {
+					return &Resp{ContentType: "image/png", Body: []byte("abc")}, nil
+				})
+
+				// Ensure the OpenAPI spec is correct.
+				assert.Len(t, api.OpenAPI().Paths["/response-image"].Get.Responses["200"].Content, 1)
+				assert.NotEmpty(t, "binary", api.OpenAPI().Paths["/response-image"].Get.Responses["200"].Content["image/png"])
+			},
+			Method: http.MethodGet,
+			URL:    "/response-image",
+			Assert: func(t *testing.T, resp *httptest.ResponseRecorder) {
+				assert.Equal(t, http.StatusOK, resp.Code)
+				assert.Equal(t, `abc`, resp.Body.String())
+			},
+		},
 		{
 			Name: "response-stream",
 			Register: func(t *testing.T, api huma.API) {