controller imports a default structure from custom, if in the controller package I create a function that already exists in custom then ServeHTTP from custom should execute the controller function and not the original one.
Your code cannot compile because there is no Controller type for method func (c *Controller) Sample(), did you mean func (c *PageController) Sample()?
I condensed all packages into one for simplicity - Playground link
package main
import "fmt"
type PageController struct{}
func (c *PageController) Sample() {
fmt.Println("from custom")
}
type Service struct {
PageController
}
func (c *Service) Sample() {
fmt.Println("from controller")
}
func main() {
s := Service{}
s.Sample() // "from controller"
s.PageController.Sample() // "from custom"
p := PageController{}
p.Sample() // "from custom"
}
s.Sample()always calls func (c *Service) Sample(). In order to reach method Sample() of the embedded field PageController, you need to make the calling path explicit: s.PageController.Sample().
@Massimo.Costa’s example with interfaces is a good way of implementing dynamic behavior of this kind.
Thanks to your answers I could get an idea of what I had to improve in my code, apparently if I want to overwrite Sample() I must first overwrite ServeHTTP(w http.ResponseWriter, r *http.Request) in the controller package but that would then move away from my goal, or of course I could also use some of your suggestions but I have read that the way of working I was looking for is similar to inheritance in other languages and that Go should not be used that way, so I will change my project design.
But now then I would like to know your opinion of when it is better to use these two options: router.Handler("GET", "/service", &controller.Service{}). router.GET("/service", othercontroller.Service()).
As you can see the difference is that the second one receives a function from the othercontroller package and the first one a struct and both comply with the signature: ServeHTTP(w http.ResponseWriter, r *http.Request).
My question in case it wasn’t understood boils down to when should I use a function and a struct to handle client requests.
to be really honest I don’t have a strong opinion about that.
Usually for non-trivial apps/services I use go-kit for the business logic and go-chi as HTTP router, in that case both toolkits impose some constraint.
A “nice” thing about go-kit (no just one) is that it enforces the use of Dependency Injection with interfaces.