V
V
veryoriginalnickname2021-10-05 23:48:57
go
veryoriginalnickname, 2021-10-05 23:48:57

How to add your own method to http.ResponseWriter?

There is a route (mux router):

router.HandleFunc("", controllerPost).Methods(http.MethodPost)


and there is a controller:
func controllerPost(response http.ResponseWriter, request *http.Request)

Can I somehow add my own method to http.ResponseWriter?
For example, I want http.ResponseWriter to have a method for conveniently sending a response. I do it like this:
type HttpResponse struct {
  http.ResponseWriter
}

func (r *HttpResponse) Send(data string, statusCode int){
  r.ResponseWriter.WriteHeader(statusCode)
  _, err := r.ResponseWriter.Write([]byte(data))
  if err != nil {
    Logger.Error(err.Error())
  }
  return
}


and then change the controller:
func controllerPost(response HttpResponse, request *http.Request)


But an error occurs:
Cannot use 'controllerPost' (type func(response HttpResponse, request *http.Request)) as the type func(http.ResponseWriter, *http.Request)

Question: how to add a method to http.ResponseWriter?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
E
Evgeny Mamonov, 2021-10-06
@veryoriginalnickname

This is because you are changing the type of the function's first argument.
I think it’s worth saying right away that if the task is to log errors in sending responses, it’s better to make a separate Middleware that will do this. Both options described below will be extremely unsuccessful for solving such a problem.
There are at least two options for solving this problem:
1st and easiest - make the functions you need so that they accept an interface, for example:

func Send(w http.ResponseWriter, data string, statusCode int){
    // тут ваша реализация
    w.WriteHeader(statusCode)
    _, err := w.Write([]byte(data))
    if err != nil {
        Logger.Error(err.Error())
    }
    return
}

And call this function in the controller
func controllerPost(w http.ResponseWriter, request *http.Request) {
    Send(w, data, code)
}

This option is good when you need to write something like
func respondHTML(w http.ResponseWriter, statusCode int, body string) {
    w.Header().Set("Content-Type", "text/html; charset=utf-8")
    w.WriteHeader(statusCode)
    w.Write([]byte(body))
}

2. Use middleware
Create HttpResponse just like you do.
You create a Middleware, where you get the standard http.ResponseWriter interface as input, create your own HttpResponse instance and pass your own as a parameter to the handler call.
But in this case, when you call Send, you will need to cast the http.ResponseWriter type to your HttpResponse, and only after that you can call Send.
If you need an example - let me know, I'll write.
I do not recommend this approach for solving this problem.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question