Live data from Hacker News

Go in Production – Lessons Learned

tdom.dev

21–30 of 109 posts

Re: Go in Production – Lessons Learned

#22
post #19
post #17

Why would you want to serve a 200 with an error message in a JSON response body?

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.

But there's response codes for those situations. If the request is malformed you should send a 400 bad request. If the application errored, send something in the 500 range.

Re: Go in Production – Lessons Learned

#23
post #19
post #17

Why would you want to serve a 200 with an error message in a JSON response body?

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.

I just had an issue today in which customer deleted a service account (which they shouldn't touch) required by our API to process their entities. Right now I send a 5xx server error but as is a customer misconfiguration problem, and problem is not on the server side and is not a bad request, but a setting client changed I would use this pattern. This will avoid triggering our alerts.

Re: Go in Production – Lessons Learned

#24
post #8
post #6

Earlier quoted context omitted.

What path to this enlightenment would you recommend to one who has cut his teeth and delivered many projects (over many years) in Rails/Django?

This is a side effect of go’s lack of meta programming to be honest. So much magic that is possible in rails/django/etc is just not possible in golang. This leads to go web frameworks being sort of semi-hard mountainous turds of code generation. You’ll want to stick to stdlib after sifting through them and deciding they aren’t worth it.

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. Middleware patching attributes directly into the request object? Python's sad excuse for incremental typing? Ignoring the database bits of Django I struggle to find anything that I don't enjoy doing more in Go. I was a HUGE fan of Django REST Framework and assorted boilerplate for a long time, but I am so extremely glad to be off that ride. Yeah, it lets you do really cool, complex things succinctly and cleverly. The problem is that it lets you do really cool, complex things succinctly and cleverly. The cleverness becomes the enemy. I now have learned to appreciate code that is utterly stupid, obvious, nearly braindead. Every codepath is screaming at you. That is Go in a nutshell. if err != nil { ... } ad nauseam. Sounds terrible... but it kind of isn't.

There are some things I would not use Go for. Game development is one of those things. Web servers, though? If you are going to be doing serious work in production environments, Go is absolutely among the best choices.

I am still, however, looking forward to trying Rust more and more. My initial impressions with Rocket.rs have been lukewarm. (One thing that is bothersome but not quite a deal breaker is compile times. A lot of crates make the experience bad almost immediately.)

Re: Go in Production – Lessons Learned

#25
post #4

The more you get to know Go's stdlib the less and less youll think a web framework is necessary. Youll find that utilizing http Round Tripper along with the Handler interface in the http library will make middleware easy. Youll eventually dig into filepath and path methods for extracting path parameters from url paths. And logging and recovery will be a concept youll need to extend outside of just http and into the r…

It sounds like what you've done is used a bunch of tools that weren't designed with web development in mind and made them do those things. That seems like not only a security issue but also an absolute mess to get into after you're done.

Re: Go in Production – Lessons Learned

#26
post #4

The more you get to know Go's stdlib the less and less youll think a web framework is necessary. Youll find that utilizing http Round Tripper along with the Handler interface in the http library will make middleware easy. Youll eventually dig into filepath and path methods for extracting path parameters from url paths. And logging and recovery will be a concept youll need to extend outside of just http and into the r…

It sounds like what you've done is used a bunch of tools that weren't designed with web development in mind and made them do those things. That seems like not only a security issue but also an absolute mess to get into after you're done.

You're not getting it.

Re: Go in Production – Lessons Learned

#27
post #20
post #11

You almost certainly don't need a web framework. Over the long term, it's easy to find yourself boxed in with how opinionated many of them are. Instead, if you build on the standard library, you can compose your application from there- a good muxer, some standard middleware that are generic http.Handler's, a session library, etc.

So, you chose a good muxer. Now, which of hundreds of logging, cors, sessions, jwt and permissions middlewares work with said mud and with each other best? Or, and bear with me here, you can outsource those decisions to other folks, and just write your business logic.

Why write code at all? I only think about stuff and outsource it _all_.

Re: Go in Production – Lessons Learned

#28
post #19
post #17

Why would you want to serve a 200 with an error message in a JSON response body?

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.

This is more RPC style. I used to prefer this approach because that way you're not constrained to the Nxx error codes of http; it's just request, response. Having worked in a few companies since then, it seems odd to me now. Besides, all your middleware etc is probably going to use status codes conventionally, so your application code's 2xx error responses will stick out like a sore thumb.

Re: Go in Production – Lessons Learned

#29
post #24
post #8

Earlier quoted context omitted.

This is a side effect of go’s lack of meta programming to be honest. So much magic that is possible in rails/django/etc is just not possible in golang. This leads to go web frameworks being sort of semi-hard mountainous turds of code generation. You’ll want to stick to stdlib after sifting through them and deciding they aren’t worth it.

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.

Re: Go in Production – Lessons Learned

#30
post #19
post #17

Why would you want to serve a 200 with an error message in a JSON response body?

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.

That is simply a 500 error. Or a 422 if request was semantically wrong.

No, this pattern is not the right one for REST. Don't call it REST, call it command/action RPC. The 90s called - they want their architecture back.

Post reply on HN