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.
Go in Production – Lessons Learned
41–50 of 109 posts
Re: Go in Production – Lessons Learned
#42Why would you want to serve a 200 with an error message in a JSON response body?
Re: Go in Production – Lessons Learned
#43Earlier quoted context omitted.
I've seen this pattern before, and one can argue that it is the correct one. Your options are your http status are your application's status, which I think is what most of us are used to. The other one is http status codes are http status codes. As in the http request was done correctly, but the application code wasn't. More specifically, http layer was executed successfully, but the application layer was not.
Your options are your http status are your application's status, which I think is what most of us are used to. I used to use HTTP status codes in this way because I understood it was the correct REST way of doing things. However, one day, a sysadmin contacted me to tell me that we had broken a release because our API was returning a 404. Actually it was a problem in the checking script that was checking for data that…
There was no server-side error. The requested resource was unable to be located because it no longer existed. You should return a 404 here, and not just for non-HTML API clients.
Application-side fatal errors are in the 500 block. So yes, you absolutely can distinguish this case.
Re: Go in Production – Lessons Learned
#44Why would you want to serve a 200 with an error message in a JSON response body?
Another reason to use GraphQL. No more endless discussion about which HTTP codes to use, which HTTP action to use, how to send in data, how to format your response, ...
Re: Go in Production – Lessons Learned
#45> 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.
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", if you need more advanced set operations on custom types, you're going to need to generate code or hard code each implementation, because generics are for suckers, allegedly. Hit some issues around channels and blocking reads and buffering, but worked around them easily enough using pointers and locks where channels weren't appropriate)
But aside from the limitations of Golang, over all it was a rather straight-forward experience. Stuff worked, tools worked, Intellij IDEA integration worked, Go's module system worked (DIAF $GOPATH), code ran, no worries.
Will say though, Go logging realllllly needs some work from the community. An SLF4J equivalent at least. I used logrus as my logging library as it gave me the easiest route to making my logs go to Kafka in Logstash format, but it has some insane defaults - like the log event timestamp defaulting to "seconds since start-up".
Oh, and be very careful with named returns. Naming a return, but then assigning nothing to it, will compile. Which is, to say the least, rather contrary to how most of Go works.
Re: Go in Production – Lessons Learned
#46Why would you want to serve a 200 with an error message in a JSON response body?
2. You can return a proper HTTP status and a JSON response body detailing what happened.
Re: Go in Production – Lessons Learned
#47Why would you want to serve a 200 with an error message in a JSON response body?
Another reason to use GraphQL. No more endless discussion about which HTTP codes to use, which HTTP action to use, how to send in data, how to format your response, ...
Re: Go in Production – Lessons Learned
#48Earlier quoted context omitted.
Your options are your http status are your application's status, which I think is what most of us are used to. I used to use HTTP status codes in this way because I understood it was the correct REST way of doing things. However, one day, a sysadmin contacted me to tell me that we had broken a release because our API was returning a 404. Actually it was a problem in the checking script that was checking for data that…
404 is literally the correct response for this behavior, per the HTTP spec. There was no server-side error. The requested resource was unable to be located because it no longer existed. You should return a 404 here, and not just for non-HTML API clients. Application-side fatal errors are in the 500 block. So yes, you absolutely can distinguish this case.
I should have mentioned that the API was behind a reverse proxy. This leads to the following questions:
Which requested resource is missing? The API itself or the item requested from the API? How does a client distinguish between these?
Re: Go in Production – Lessons Learned
#49This article has almost nothing to do with Go in particular. Just...general stuff to follow when writing code. What is it here that talks specific things about "Go" + "in production"?
There’s an ongoing debate among go dev if the stdlib is enough or not to perform « real world » work (which isn‘t the case in other languages). This article is from someone who think it’s not. That’s interesting.
There's a well-trodden path of developers who were trained in PHP/Rails/JS/Django/etc starting on Go. Their first question is always "what framework should I use?" (you can see this being asked at least once a week on r/golang). They then go down that path, and find (what they think to be) Go to be clunky and boring and hard to think about. There's a minority that decide that what Go needs is another framework, because the one they tried obviously isn't working for them.
Then there's a split, and some people write articles like this one, and probably move on to Rust or whatever language is next for them. The others start understanding. They refactor their code to not use that logging library because they start to understand the understated power of the stdlib's logging functions. They refactor to get rid of the ORM that's become a problem. Slow realisation dawns and they finally get rid of the framework and go back to writing http.Handlers. This process usually takes a couple of years (well, it did for me anyway).
And then our reborn Gopher goes to the forums to spread the light: "all you need is the standard library! You don't need a framework!", and is met by derision and misunderstanding. The Go community gets a reputation for being unjustifiably anti-frameworks and a bit weird about ORMs too. Eventually our hero shrugs their shoulders and lets the newbies find their own path, contenting themselves with upvoting those who understand.
Re: Go in Production – Lessons Learned
#50Earlier quoted context omitted.
Another reason to use GraphQL. No more endless discussion about which HTTP codes to use, which HTTP action to use, how to send in data, how to format your response, ...
How does GraphQL allow you to not worry about those things?
GraphQL defines the format of the reponse in case of errors[1]
GraphQL doesn't use HTTP status codes to communicate out-of-the-ordinary conditions. You can expect to always get HTTP status 200[1]
The data response is a mirror of the query you sent in with the data present[2]
How to query for data is explicitely laid out[3]
How to send in parameters is explicitely laid out[4]
[1] https://graphql.org/learn/serving-over-http/ [2] https://graphql.org/learn/ [3] https://graphql.org/learn/queries/#fields [4] https://graphql.org/learn/queries/#variables