Skip to content

render.Render() writes to writer unexpected data of aliased type #56

Description

@Archirk

Hello,
During my work I faced unexpected behaviour on calling render.Render() when I was implemented Renderer interface on struct, which occured to be alias. Honestly, I have no clue why it's happening.
But it appears that render calls implicitly some default renderer IN ADDITION to my implementation.
It seems like it should exit here but it does not.

package main

import (
	"fmt"
	"io"
	"net/http"
	"net/http/httptest"

	"github.com/go-chi/render"
)

type (
	PublicProfile Profile
	Profile       struct {
		Name string
		Age  int
	}
	ProfileResponse struct {
		Name string `json:"name"`
	}
)

func (p PublicProfile) Render(w http.ResponseWriter, rq *http.Request) error {
	render.Status(rq, http.StatusNoContent)
	render.JSON(w, rq, ProfileResponse{Name: p.Name})
	return nil
}

func main() {
	w := httptest.NewRecorder()
	rq := httptest.NewRequest(http.MethodGet, "/", nil)
	someProfile := Profile{Name: "John", Age: 42}
	wrappedProfile := PublicProfile(someProfile)
	render.Render(w, rq, wrappedProfile)
	responseBody, _ := io.ReadAll(w.Body)
	fmt.Println(w.Code, string(responseBody))
}

Output:

204 {"name":"John"}
{"Name":"John","Age":42}

On go-playground

The only way around I have found is setting default responder to empty func. Is this expected way to it?

render.Respond = func(w http.ResponseWriter, rq *http.Request, v interface{}) {}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions