The following an unformatted brain dump:
re: everything in one package, Yes, that is what I was trying to say. In the MVC case, it’s possible you might import a model for use elsewhere, it is highly unlikely that you will import controllers and views anywhere else. Separating them into different packages adds only more complexity. Then again, views aren’t anything but marshaling JSON most of the time, and so this point doesn’t matter. If it isn’t being imported separately and elsewhere, then it probably doesn’t belong in a different package.
re: interfaces, IME it can’t be stressed enough. Large interfaces become a huge burden. Small interfaces are wonderful. The 1 method goal of io.Reader, io.Writer are good ones. It’s very easy to compose interfaces, hence, io.ReadWriter and the often re-implemented io.ReadWriteCloser.
My rule of thumb is around 4 or 5 methods. Around there or larger, I start questioning if this is the right way to do whatever I’m doing. So far I’ve had no exceptions. I’ve been able to keep things small. The dozen to two dozen method interfaces that are so common in Java and C# typically don’t exist in Go. If I see them, they are almost always created by code generation tools and aren’t actually intended to be reimplemented, but are instead an artifact of the design of the code generation system. Docker and Kubernetes, especially their client APIs, come to mind.
Interfaces in Go are weird. You can use them everywhere, but that doesn’t mean you should. The stdlib is the best guidance there is for when and where, and it really shows that it shouldn’t be used unless it must. e.g. net/http Request is not an interfaces. ResponseWriter is. Why is a good question to try and answer.