Live data from Hacker News

Go in Production – Lessons Learned

tdom.dev

101–109 of 109 posts

Re: Go in Production – Lessons Learned

#101
post #15

Earlier quoted context omitted.

Especially since caught panics amount to exceptions and most Golang code isn't exception safe. It's a recipe for leaking database connections, deadlocks, etc.

Go error handling is awful, but this isn't a fair. In go, if you write code like the following: conn, err := db.Connect() defer conn.Close() That defer will be run during a panic. Same thing as 'defer mutex.Unlock()' Yes, like most of go, it's manual and painful and poorly thought out, but most people do follow these patterns, so for the most part go code will safely unwind from a panic.

Most of the time, sure, but there are lots of cases where `defer` being function scoped leads to manual unlocks, e.g. inside loops or short critical sections in the middle of a function. Yes, you can use closures/otherwise, but few codebases are that disciplined. Those edge cases are plentiful enough that catching panics is dangerous.

Re: Go in Production – Lessons Learned

#102
post #39

> I recently got a DevOps job that mostly involves writing a new backend system in Go completely from scratch. If this wasn't on the front page of HN I'd have stopped reading here, but it is, so I didn't, then I regretted it.

Can you at least explain why?

For the same reason as if it had said “I recently got a React dev job which mostly consists of writing Kubernetes deployments.” It sounds like the beginning of an article which uses buzzwords without a lot of depth.

Re: Go in Production – Lessons Learned

#103

Earlier quoted context omitted.

> How are GET requests a crutch? They were not in the original spec IIRC. URL's are limited in legth (it's not in the spec, but most clients have a limit) etc. > Which is what any caching proxy must do anyway? Nope. A caching proxy can benefit from HTTP Cache Headers [1]. But cache headers don't work well with GraphQL's GET requests, and don't work at all with the default, which is POST. > This problem is not limited…

> They were not in the original spec IIRC. URL's are limited in legth (it's not in the spec, but most clients have a limit) etc. They were not in spec because the spec doesn't say anything over which medium it should be transported. In fact the spec [1] only mentions the word HTTP 5 times: 4 times in example data and one time discussing implementation details when sending data over HTTP. GraphQL can't be faulted for…

> They were not in spec because the spec doesn't say anything over which medium

If not the spec, then original documentation. GET is a late add-on.

> How do cache headers not work well with GraphQL GET requests?

In REST:

- a resource is uniquely identified by it's URI

- when the server sends back cache headers, any client in between (any proxies, the browser, any http clients in any programming language etc.) can and will use these cache headers to cache the request

In GraphQL GET:

- http://myapi/graphql?query={user{id,name}} and http://myapi/graphql?query={user{name,id}} are two different requests

- it gets worse for more complex queries, especially if they are dynamically constructed on the client

- each of those is viewed as a separate query with separate caching

- cache normalisation and query normalisation are a thing in the graphql world (and non-existent in REST) because of that.

That's a yet another layer of complexity that you have to deal with

> And what exactly are those benefits? I'm here defending GraphQL yet none of the downsides of REST are being taken into account.

I wish anyone was willing to discuss the downsides of GraphQL. Bashing REST is the norm, but GraphQL is the holy grail that accepts no criticism.

Benefits of REST over GraphQL, off the top of my head:

- it's HTTP, plain and simple. So everything HTTP has to offer is directly available in REST. See this HTTP decision diagram [1]

- caching doesn't require you to normalise and unpack every single request and response just to figure out if something is cached

- You know your requests, so you can provide optimised queries, resolution strategies, necessary calls to external services as required by the call

> There are tools like Postgraphile that solve this. It converts your GraphQL query into one efficient database query.

I'd love to see that proven for any sufficiently complex and large database.

> And what prevents anyone from hammering a REST API?

No ad-hoc queries prevents anyone from hammering a REST API that you can specifically tune to the specific request and data you need.

GraphQL requires significantly more care especially if you're not running it on just one database. And even then, oops, joins: https://news.ycombinator.com/item?id=25014918

And we're back to requiring the graphql server to be able to limit recursion depth, query complexity, etc. etc.

[1] https://github.com/for-GET/http-decision-diagram/tree/master...

Re: Go in Production – Lessons Learned

#104
post #87
post #59

To those who say frameworks are needed because the stdlib is not enough: No, the stdlib defines very clear interfaces that libraries can implement. The result is that you can drag and drop middlewares from multiple packages into your codebase, because they all conform to the universal middleware signature `func(http.Handler) http.Handler`. Want CSRF? Want Sessions? Want Auth? They all exist as separate packages (chec…

Came in here to say this. I helped many teams move from Java to Go, and came across this so many times. Everyone wanted to find the Spring equivalent for Go (or Django, Ruby on Rails, etc) when it doesn’t actually exist. That’s by design. No ill feelings toward the developers of Echo, or other similar frameworks (Go Micro specifically). However, touting their framework as the way to build APIs in Go is disingenuous a…

I think it's only a matter of time before there's a solid choice full featured Go web framework that rivals Rails/Django.

Re: Go in Production – Lessons Learned

#106
post #80
post #40

Earlier quoted context omitted.

Here is the thing, I have been doing Web development alongside native for a couple of decades now. This Go enlightment seems to only touch those that don't realize that programming to interfaces was already a thing back in Objective-C and WebObject days, or using Smalltalk categories (later formalized as traits in Pharo). Also that languages like Java and .NET also have a similar Http server on their standard library…

Could you explain what you mean by things start getting hard? Why did the languages you mentioned stop using their HTTP interfaces?

Because that is just the basic, when doing web applications, besides handling HTTP requests you need:

- workload distribution - security and authentication - role management via some form of directory services like LDAP or AD - running tasks in background in response for certain events - mapping into various kinds of databases and information sources - handling caching - have a way to manage reusable components of html/css/js + respective backend code

Yep one can make use of libraries to achieve all of that, but then most likely they don't compose in an easy way, nor make an eco-system.

Re: Go in Production – Lessons Learned

#107
post #24

Earlier quoted context omitted.

Admittedly I liked Django's database layer but using it in Real World production has also left me feeling kind of... eh. Having automigrations and an ORM is fantastic 90% of the time. The other 10% of the time almost ruins the magic entirely. The ORM is not a panacea like SQLAlchemy nearly is. Issues with migrations in production can get surprisingly tricky surprisingly quick. The rest though I do not miss at all. Mi…

Using SQLAlchemy has been my biggest (technical) regret in my current project; it was great at first, but overtime it's made testing a lot harder and session/object management has led to subtle bugs.

Speaking from experience, session/object management is always tricky with ORM's. SQLAlchemy has been good for us; but the usage has been very, very disciplined and doesn't look idiomatic.

Re: Go in Production – Lessons Learned

#108
post #87

Earlier quoted context omitted.

Came in here to say this. I helped many teams move from Java to Go, and came across this so many times. Everyone wanted to find the Spring equivalent for Go (or Django, Ruby on Rails, etc) when it doesn’t actually exist. That’s by design. No ill feelings toward the developers of Echo, or other similar frameworks (Go Micro specifically). However, touting their framework as the way to build APIs in Go is disingenuous a…

I think it's only a matter of time before there's a solid choice full featured Go web framework that rivals Rails/Django.

I might be wrong but it seems that Go needs to have a proper generic support for that ever to happen and that's one of the main reasons why there is no equivalent of RoR in the C world.

For a very good perspective on this check out this excellent article by the creator of Stanza language responding to his friend's request of not creating any more new languages but just libraries:

https://jaxenter.com/stop-designing-languages-write-librarie...

Re: Go in Production – Lessons Learned

#109

Earlier quoted context omitted.

What offends you in that statement? FWIW, I, who is usually writing JVM apps in Java/Kotlin occasionally Scala, had an app to write that that extensively used K8s APIs, and I found that the best client API was (naturally, considering the makeup of the K8s ecosystem) the Go one, so I wrote the app in Go. I had to overcome some common Go issues (use a map[t]interface{} when you need "is x in a list of unique elements",…

> Naming a return, but then assigning nothing to it, will compile. This, I believe, comes down to Go having sane default values i.e. if you name a return of type string and assign nothing to it, you'd get "", which is a valid string value and something you can check against. But I agree it should at least be a lint warning.

Yeah, I didn't quite realise it actually initialised the variable when I first started using it. I mean, as far as footguns go, it's a pretty minor one, and over all, I quite enjoyed my Go experience, it was very easy as a Go beginner to write code that worked.
Post reply on HN