I really like Mat Ryer's work, and I've applied most of the ideas in the 2018 version of this article to all of my Go projects since then. The one weak spot for me is this aspect: > NewServer is a big constructor that takes in all dependencies as arguments... In test cases that don’t need all of the dependencies, I pass in nil as a signal that it won’t be used. This has always felt wrong to me, but I've never been ab…
You can use Dependency Injection to solve this issue but in my view the added complexity is not really worth it.
How I write HTTP services in Go after 13 years
201–210 of 259 posts
Re: How I write HTTP services in Go after 13 years
#202Earlier quoted context omitted.
Except Username is not exactly the same as string, and that's important. Username is a subset of string. If they were equivalent, we wouldn't need to parse/validate. The often misinterpreted part of DRY is conflating "these are the same words, so they are the same", with "these are the same concept, so they are the same". A Username and a String are conceptually different.
DRY is just "Do not repeat yourself". And a LOT of devs take that literally. It's not "Do not repeat concepts" (which is what it SHOULD be but DRC isn't a fun acronym). Unfortunately "This is the same character string" is all a DRY purist needs to start messing up the code base. I honestly believe that "DRY" is an anti-pattern because of how often I see this exact behavior trotted out or espoused. It's a cargo cult t…
DRY applied as a dogma will eventually fail, because it's not a verified mathematical proof of infallible code, it's just a practice that gives good results inside its constraints, people just don't learn the constraints until it explodes in their faces a few times.
Like any wisdom, it's hard it will be received and understood without the rite of passage of experience.
Re: How I write HTTP services in Go after 13 years
#203Re: How I write HTTP services in Go after 13 years
#204Earlier quoted context omitted.
> you can't just look at the documentation of the type Sure you can. Option func is a constructor for option type, and constructors are auto-included above methods in the docs. PLS completion works for them as well.
The options for the thing being constructed are all separate types from the thing being constructed; the options aren’t a facet of the definition of the type they mutate.
- main constructor is easily available from the main type's docs,
- option type is easily available from the main constructor's docs,
- all option funcs are easily available from the option type's docs (because in fact these option funcs are constructors for the option type).
Excerpt from grpc godoc index:
type Server
func NewServer(opt ...ServerOption) *Server
...
...
type ServerOption
func ChainStreamInterceptor(interceptors ...StreamServerInterceptor) ServerOption
func ChainUnaryInterceptor(interceptors ...UnaryServerInterceptor) ServerOption
func ConnectionTimeout(d time.Duration) ServerOption
func Creds(c credentials.TransportCredentials) ServerOption
etc...
One more hop compared to a flat argument list, that's true. But if you only commonly use maybe 0-5 arguments out of 30-50 available, it does not look like a bad deal.Re: How I write HTTP services in Go after 13 years
#205Earlier quoted context omitted.
Except Username is not exactly the same as string, and that's important. Username is a subset of string. If they were equivalent, we wouldn't need to parse/validate. The often misinterpreted part of DRY is conflating "these are the same words, so they are the same", with "these are the same concept, so they are the same". A Username and a String are conceptually different.
DRY is just "Do not repeat yourself". And a LOT of devs take that literally. It's not "Do not repeat concepts" (which is what it SHOULD be but DRC isn't a fun acronym). Unfortunately "This is the same character string" is all a DRY purist needs to start messing up the code base. I honestly believe that "DRY" is an anti-pattern because of how often I see this exact behavior trotted out or espoused. It's a cargo cult t…
Re: How I write HTTP services in Go after 13 years
#206I've recently been playing with ogen: https://github.com/ogen-go/ogen Write openapi definition, it'll do routing, definition of structs, validation of JSON schemas, etc. All I need to do is implement the service. Validating an integer range for a querystring parameter is just too boring. And too easy to mistype when writing it manually. Anyways, so far only been playing, so haven't found the bad parts yet.
I thougt it would be boring writing the spec, but it was not nearly as bad as I thought. Also, a spec is needed, so might as well write it up front.
Re: How I write HTTP services in Go after 13 years
#207What is the value making main.go as small as possible? Whose dreams come true in this scenario?
main() is the only place where you can't return an error. In order to keep as much of the code as idiomatic as possible you just call something like run() where you can do so.
In addition there is the testing aspect. You can't invoke main() from your tests.
Re: How I write HTTP services in Go after 13 years
#208Earlier quoted context omitted.
>All the advice in the article is still helpful, but it takes the "how do I make sure X is initialized when Y needs it" part completely out of the equation and reduces it from an N*M problem to an N problem, ie I only have to worry about how to initialize individual pieces, not about how to synchronize initialization between them. I gotta say, I hate these dependency injection frameworks. In a well designed system th…
If you have ever topologically sorted 100 components connected in a complex graph by hand or found the right spot to insert the 101st, you'd quickly appreciate more help than a compiler check.
DI still has other advantages, but that’s not one
Re: How I write HTTP services in Go after 13 years
#209I've recently been playing with ogen: https://github.com/ogen-go/ogen Write openapi definition, it'll do routing, definition of structs, validation of JSON schemas, etc. All I need to do is implement the service. Validating an integer range for a querystring parameter is just too boring. And too easy to mistype when writing it manually. Anyways, so far only been playing, so haven't found the bad parts yet.
The problem with this approach is writing openapi by hand from scratch is incredibly tedious process. Writing Protobufs, capnproto or any such similar idl feels much more productive
Re: How I write HTTP services in Go after 13 years
#210Earlier quoted context omitted.
If you have ever topologically sorted 100 components connected in a complex graph by hand or found the right spot to insert the 101st, you'd quickly appreciate more help than a compiler check.
I’m sure there’s a place for them. But when micro-services are so common, it seems like people use them (Spring) because everyone else does, not because they actually provide needed value.