Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

net/http/httptest: document ResponseRecorder.Header method as an internal implementation detail, point to Result method #32136

Closed
dmitshur opened this issue May 19, 2019 · 2 comments
Labels
Documentation FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.
Milestone

Comments

@dmitshur
Copy link
Contributor

(This is a continuation of #25763 and #16717.)

The httptest.ResponseRecorder.HeaderMap struct field was deprecated in CL 117675, with the deprecation notice pointing users to the Response.Header map as returned by the Result method. This was to resolve issue #25763 (which provides rationale for why that was done).

However, there's also a ResponseRecorder.Header method which does little more than provide direct access to the HeaderMap field (it also initializes the map if it's nil):

// Header returns the response headers.
func (rw *ResponseRecorder) Header() http.Header {
	m := rw.HeaderMap
	if m == nil {
		m = make(http.Header)
		rw.HeaderMap = m
	}
	return m
}

This puts users in an awkward position. If they read the deprecation notice on the HeaderMap field (and understand the rationale for why it was deprecated by reading through issue #25763), and also know the internal implementation details of the Header method, they'll know that they shouldn't be using the Header method either.

If they don't know the internal implementation details of the Header method, they won't know how it differs from the Response.Header map as returned by the Result method and how to decide which one to use.

Users shouldn't have to read the internal implementation of methods and make these kind of deductions. If the HeaderMap field is deprecated, the current Header method should be too:

-// Header returns the response headers.
+// Header returns the response headers explicitly set by the Handler.
+// It is an internal detail.
+//
+// Deprecated: Header exists for historical compatibility
+// and should not be used. To access the headers returned by a handler,
+// use the Response.Header map as returned by the Result method.
 func (rw *ResponseRecorder) Header() http.Header {

/cc @cespare @bradfitz @dominikh

@dmitshur dmitshur added Documentation NeedsFix The path to resolution is known, but the work has not been done. labels May 19, 2019
@dmitshur dmitshur added this to the Go1.13 milestone May 19, 2019
@dmitshur
Copy link
Contributor Author

dmitshur commented May 19, 2019

I just realized that the Header method exists so that *httptest.ResponseRecorder implements the http.ResponseWriter interface, so it can't be outright deprecated.

Still, I think it's worth finding a way to clarify its documentation to make it clear it's not meant to be used by users (just like HeaderMap field) for the purpose of testing what headers the handler set, and point to the Result method for that purpose instead.

Perhaps something like this instead:

-// Header returns the response headers.
+// Header implements the http.ResponseWriter interface.
+//
+// To access the headers returned by the handler, use
+// the Response.Header map as returned by the Result method.
 func (rw *ResponseRecorder) Header() http.Header {

@dmitshur dmitshur changed the title net/http/httptest: deprecate ResponseRecorder.Header method as well net/http/httptest: document ResponseRecorder.Header method as an internal implementation detail, point to Result method May 19, 2019
@gopherbot
Copy link

Change https://golang.org/cl/178058 mentions this issue: net/http/httptest: update docs, remove old inaccurate sentence

dmitshur added a commit to shurcooL/home that referenced this issue Jun 16, 2019
In tests, use the Result method. It produces output more representative
of what the handler actually responded with, making tests more accurate.

In legacy non-test usage as a temporary buffer, use Header() method
instead of relying on directly setting the deprecated HeaderMap map.
It was deprecated primarily for test-focused usage, but it's still
deprecated, and makes tools report using it as a problem.

Updates golang/go#32136
Updates golang/go#32144
@golang golang locked and limited conversation to collaborators May 19, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Documentation FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.
Projects
None yet
Development

No branches or pull requests

2 participants