Live data from Hacker News

REST Servers in Go: Part 1 – standard library

eli.thegreenplace.net

61–70 of 149 posts

Re: REST Servers in Go: Part 1 – standard library

#61

Earlier quoted context omitted.

I don't need them in Java or Typescript. The benefit is that I don't have to write these boring, but necessary pieces. As applications grow larger, especially with Go's desire to have an interface with only one method/function, DI requires a lot of boilerplate. If there was a DI for go that used generate, then I would have compile time checking of dependencies. This would satisfy the community's sense of purity while…

> The benefit is that I don't have to write these boring, but necessary pieces. The "boring, but necessary pieces" are usually just a call to a constructor. In my opinion it's almost never worth using a DI system that obfuscates dependency resolution and usually can't be checked at compile time just to avoid that.

Agreed. It seems silly to call "invoking constructors" "boring" but doing all of the same work in XML is somehow more interesting? It seems like you're just adding in a layer of indirection that does nothing besides exchange Go/Java/etc for XML/Groovy/etc at the expense that one must be familiar with the DI framework to understand how the DI files are loaded, linked together, and mapped to your application code.

Re: REST Servers in Go: Part 1 – standard library

#62
post #16

Earlier quoted context omitted.

I've never understood the value proposition of a DI framework. Why would I want one when I can initialize my objects in main()? Is XML or JSON or whatever really that much more pleasant than wiring together Go objects?

I'm with you on this. Dependency injection seems to me to replicate some of the features of interfaces while introducing complexity because the injection is indirect -- instead of having code that initializes a different object, it all happens dynamically during runtime using reflection. An antipattern as far as I'm concerned. It seems to achieve little or no gain at a very high cost.

It sounds like people just want a little bit of dynamic typing to assemble their object graph or something, but that's such a small (possibly negative) value add for such a steep price (everyone who might touch this software--new team members, system administrators, whoever takes over maintenance, etc--now needs to know the DI framework for even the most basic troubleshooting).

Re: REST Servers in Go: Part 1 – standard library

#63
post #38

Earlier quoted context omitted.

You are implying that "realistic" uses would be using multiple domains and have browser calls between them. Why would that be?

I guess I have a deeper point to make, which is.. if you're going to compare golang web libraries it's the details that are going to end up making your decision. Superficial comparisons will be misleading. Implement auth, CSRF, a "real ip" Middleware, request logging, graceful restarts, yes CORS, and then do a few REST endpoints with it to see how much boilerplate VS useful code you have to write. Maybe this is just…

I opened the article to begin with to see if it contained some argument for why using the standard library instead of a framework makes sense.

It contained no explanation or reasoning to that end. It is purely what it is titled as: An explanation of how to do it with the standard library.

In that sense I don't think there is anything wrong with it. It doesn't make any claims; it simply provides the information it said it would.

Also, one of the main selling points of Golang is that it aims to deliver functionality with minimal additional cruft/add ons. Many of the standard library things are this way and don't provide the "extra stuff" you are desiring.

You mention auth, but many of the frameworks for Golang don't even implement auth and merely provided the ability to add auth if desired.

Logging is a debatable topic because the "standard" logging method is very inadequate, and so each of the various frameworks has to just choose a random logging system to use. ( or several )

While some frameworks do offer the ability to restart without killing active connections / requests, it is a more generalized issue with any service in Golang. It is also best addressed by writing your service in a scalable fashion and doing a rolling upgrade. Stop sending traffic to an instance, wait till current requests are done, then kill it. It doesn't need to be addressed within the service itself.

Re: REST Servers in Go: Part 1 – standard library

#64

Earlier quoted context omitted.

You are implying that "realistic" uses would be using multiple domains and have browser calls between them. Why would that be?

This is common. Web apps frequently fetch data from other domains, whether internal or third party.

Agreed, but a common extension does not mean it is required, nor that it should be demanded that an example of making a REST service needs to show how to do it.

The example is simply the beginning. It can be extended as needed depending on your use case. This is how most things Golang work. You start with the basics and add what you need on a case by case basis.

If you want something with every bell and whistle out of the box, Golang is going to be a disappointment generally as that is not the Golang mentality.

There are of course sufficient frameworks in Golang these days to provide such things though. Hence the article clearly says "standard library" to indicate that it isn't the last word on how to setup a REST service in Go.

Re: REST Servers in Go: Part 1 – standard library

#65

Earlier quoted context omitted.

The purpose of DI is to allow the use of a DSL to instantiate and connect objects, with configuration for those objects embedded into the DSL so that the setup and the way things work can be changed quickly without altering code. Mocking objects for testing purposes and swapping them for the real objects is also something commonly done that is helpful. There is no "real" DI for Golang as far as I've seen. The only DI…

I guess maybe this would be useful for a language like C or old-school C++ where you had to imperatively build your maps and lists and allocate memory and explicitly type your variables and so on, but Go memory allocation and typing are implicit and maps and lists have a nice literal syntax so I don't see any value in a DSL. As for testing, you can already swap out real objects for test objects--that's a property tha…

The argument for and desire for DI is closely tied to the low code movement. It is tied to configuration as code.

It is certainly a different mentality from straight out coding everything.

I think it is important and will grow bigger in time, because low code is a type of metaprogramming.

You don't "need" to use low code stuffs or do metaprogramming, but if you know how and learn it well you can get much more complex things done quicker than coding everything.

The stuff you are objecting to is due to Spring and such seeking to be a type of generalized metaprogramming instead of focusing on custom DSLs. A custom DSL will have less verbosity, not more.

In a good low-code setup, all your logs should go to the "log" module, and there should be very simple configuration indicating where the logs go.

Re: REST Servers in Go: Part 1 – standard library

#66

Earlier quoted context omitted.

The purpose of DI is to allow the use of a DSL to instantiate and connect objects, with configuration for those objects embedded into the DSL so that the setup and the way things work can be changed quickly without altering code. Mocking objects for testing purposes and swapping them for the real objects is also something commonly done that is helpful. There is no "real" DI for Golang as far as I've seen. The only DI…

By DSL...you mean XML/JSON? Because that's literally the only thing I've ever seen used for DI purposes. And then invariably there's still just two versions of any given injectable interface; the one used in production, and the one used in testing.

By DSL I mean something like how HTML is used to make websites. HTML was derived from SGML, and is related loosely to XML, but does not contain a lot of the complexities of XML.

I do not mean JSON, as JSON is not a good generalized meta-programming notation. People use it that way but it ends up ugly and hard to read.

JSON can be used alright as a configuration notation, but does not represent itself well as a metaprogramming language, since it does not preserve order or allow mixed content. You can get order by using an array of course, but it is much more verbose than the equivalent content in XML or HTML.

You might say, by DSL, I mean "custom markup languages".

Re: REST Servers in Go: Part 1 – standard library

#67

Earlier quoted context omitted.

> The benefit is that I don't have to write these boring, but necessary pieces. The "boring, but necessary pieces" are usually just a call to a constructor. In my opinion it's almost never worth using a DI system that obfuscates dependency resolution and usually can't be checked at compile time just to avoid that.

Agreed. It seems silly to call "invoking constructors" "boring" but doing all of the same work in XML is somehow more interesting? It seems like you're just adding in a layer of indirection that does nothing besides exchange Go/Java/etc for XML/Groovy/etc at the expense that one must be familiar with the DI framework to understand how the DI files are loaded, linked together, and mapped to your application code.

The main benefit of constructing objects and tying them together via DI is to allow polymorphic handling of responsibilities.

It is more complex than simply "I just make an interface and make everyone agree on that interfere". Everyone agreeing on the interface to use is very unlikely.

The underlying data in different implementations will be different. This is something Golang fails terribly at because it doesn't have polymorphism.

This is, I believe, why there are so few DI systems for Golang, and most of them are of the sort you are referring to as silly.

The way Golang works, and the reccomended patterns for Golang are somewhat anti-DI.

Re: REST Servers in Go: Part 1 – standard library

#68

Earlier quoted context omitted.

I hope to spur conversation on this. I've seen many in the Go community argue against abstractions. Many say, "Pass the database connection in the params." Or "make the DB pool a global variable". How can you write tests for logic without having to instantiate a DB? Many gophers appear to say I should have essentially a giant transaction script for each handler ( https://martinfowler.com/eaaCatalog/transactionScript.…

> Many say, "Pass the database connection in the params." ... How can you write tests for logic without having to instantiate a DB? You define and use an interface to model the DB, and use that as the mock point. Basic stuff.

I aware of making an interface for that. I advocate that. What I see people on r/golang saying, and even in HN, is to just pass the DB connection either explicitly or in the context. I hate this. It makes things bound to DBs.

Re: REST Servers in Go: Part 1 – standard library

#69

Earlier quoted context omitted.

The purpose of DI is to allow the use of a DSL to instantiate and connect objects, with configuration for those objects embedded into the DSL so that the setup and the way things work can be changed quickly without altering code. Mocking objects for testing purposes and swapping them for the real objects is also something commonly done that is helpful. There is no "real" DI for Golang as far as I've seen. The only DI…

What makes something a "real" DI framework? Wouldn't go.uber.org/fx qualify?

I use "real" in quotes to indicate I am meaning something other than the general meaning of the word "real". What I mean by this is a specific type of DI that I view as effective and a type of meta-programming. Such a DI system does more than just auto-instantiate objects. It also provides a DSL that allows for configuration and ordering of the object instantiation during different phases of system execution.

fx doesn't do that. It is primarily just a convenience way for tying things together in the single intended way. You can provide some configuration but it is not via a DSL; it is by making calls to the fx library.

Realistically to do the sort of DI I am referring to with Golang there would need to be a preprocessing step during compilation that generates Golang code.

Re: REST Servers in Go: Part 1 – standard library

#70
post #24

Earlier quoted context omitted.

By DSL...you mean XML/JSON? Because that's literally the only thing I've ever seen used for DI purposes. And then invariably there's still just two versions of any given injectable interface; the one used in production, and the one used in testing.

DI is a decoupling technique. You might only have two interfaces to begin with, but the rough idea is that writing to interfaces and using IoC allows you to make many changes by adding code without having to change old code.

In Go, you can just use an interface which would make things mockable for testing.
Post reply on HN