5 ms·
Show HN: A Go web server with logging, tracing, and demo apps in a single file
- laurent123456 7y ago> all in a single file It's not really an advantage, is it? Having everything mixed up into one giant file just makes the code much harder to make sense of.
- jerf 7y agoAs feedback to the author, since the author seems to also be the HN poster, I would agree with this. If it were the only meaningful file in the project, maybe it'd be worthwhile, but at 885 lines, this could stand to be broken into segments. What I'd suggest then is adding a section to the README.md that functions as a reading guide for the code; start here, read this, here's what each file is doing, here's where this sample app is, here's that one, etc.
- Nextgrid 7y agoI agree. “Single file” projects are good for education if they’re short, but that many lines is just counter-productive.
- photon_lines 7y agoThank you for the feedback!! The main.go file has comments within it that try to explain what each component does, and I tried to structure it in a way that makes it very easy to conceptualize and understand. Whenever I write code, I do my best to make it self-documenting, although doing this isn't necessarily easy and I may have done an inadequate job in this instance. I'll see if I can find some time and include more info in the README.md - once again, if you read my previous response to the parent comment: the reason I included everything in one file was because of my preference, as I prefer to have everything in one place when learning something. The focus of this was teaching and demoing Go functionality, not shipping production ready code!
- save_ferris 7y agoI recently started learning go and I've been struggling with the lack of modularity across smaller codebases like this. For all of the great tooling around formatting go, I'm kinda surprised by some of the code organization decisions I see.
- jerf 7y agoThere's some differences in style. I take a very aggressive stance on separating my modules; my thought is that it's relatively easy to understand what any given module is doing if it is small and focused and clearly pulls in its dependencies. But it's a non-trivial challenge to keep it all so nicely isolated and avoid loops. Worth it, I think, or I wouldn't do it, but non-trivial. There are also a lot of people who pretty much just punt and put everything in one module, so they don't have to deal with circular issues. I'm not sure I see a clear community consensus.
- w0uld 7y agoI found the advice in Brian Ketelsen's 2018 GopherCon talk[1] helped my Go code organization. It helped me reason about the optimal way to abstract my code. [1] https://www.youtube.com/watch?v=MzTcsI6tn-0 https://www.youtube.com/watch?v=MzTcsI6tn-0
- deleted 7y ago[deleted]
- photon_lines 7y agoI completely agree, although that also depends on what you're going for. My personal preference when learning something is to have everything in one place. That way, I can easily scan through the components and see the whole piece rather than having to switch windows. I agree though that it's definitely not a best practice if you're focusing on writing and delivering production code. The focus of this app was actually showing some neat Go features and delivering a fully functional web server in a singe file. If you look through the code, you'll see that I added a lot of comments and even made notes stating that even though I included the raw HTML/CSS/JS components within main.go, this definitely was not a best practice and I referenced files within the repository which contain this code in case anyone decided that they wanted to refactor and clean it up. Anyways, hopefully this helps and thanks for the feedback!
- linsomniac 7y agoWe use a Go app called MailHog, which is a SMTP server for development use. It also has a web interface for management. All in a single go file (SMTP server, HTTP server, plus all web artifacts). That is a pretty convenient packaging for a dev/staging tool.
- w0uld 7y agoDo you mean a single binary file? MailHog's mail.go file pulls in a number of dependencies that round out its HTTP and SMTP servers. In OP's case, the entire project's source code is in the main.go file.
- linsomniac 7y agoYes, a single binary file is what I meant. I realize in some ways it is orthogonal here, but I guess it reminded me that sometimes a single file can be useful in surprising ways...
- user5994461 7y agoThere is a widely popular web server in python that is a single file. I find it quite readable and it's well documented. It helped me immensely on a few projects where there was no dependency management to speak of, or wasn't allowed to use external dependency. Copy a single file and done. https://github.com/bottlepy/bottle https://github.com/bottlepy/bottle
- sagichmal 7y agoNo reason to use a global int32 as a healthiness bit. Treat it as a dependency to the health middleware and the signal handler.
- Pelican 7y agoIf "in a single file" means having your html and your javascript in your go file, that's not a feature...
- mdanger007 7y agoI prefer treating a template as a constant for small projects. Trade off is it doesn't scale but vastly reduces configuration overhead.
- photon_lines 7y agoI agree! The purpose of this was teaching, and not necessarily following all of the best practices! I made raw files which contain the go HTML templates, as well as the JS and CSS files available within the repository in case anyone wanted to reference these instead of including the raw code within main.go!!
- whateveracct 7y agoYeah..the Haskell one recently at least had the HTML in a Haskell EDSL instead of raw strings.
- the_enigma 7y agoNot a fan of this juice.
- SamWhited 7y agoMight be worth structuring this like a normal Go project (eg. right now this is in a package called "src", which is not great) if it's meant for education. Also the listen address is actually a port, not an address. Might be worth making that a generic address so the user can specify an interface to listen on.
- tikkabhuna 7y agoHaving looked at writing a simple Go web service recently. I spent far more time than I'd like looking for good examples of how to structure it. Especially when many examples don't use Go Modules.
- throwaway894345 7y agoThis is really cool! One suggestion: logging to a file makes it harder for things like Docker to exfiltrate logs. Log to stderr by default, and the caller can redirect to a file on disk if they want to.
- majormjr 7y agoWhy log to stderr instead of just stdout?
- ktm5j 7y agoMaybe just convention? It's standard practice to use stdout for directly interacting with a user and stderr for log/error type messages. You can redirect stderr to a file to get all of your log messages, but keep stdout available for interacting with the user. Super useful to separate meta-messages out in this manner. Here's a good blog post with more info on stderr for those interested: https://www.jstorimer.com/blogs/workingwithcode/7766119-when-to-use-stderr-instead-of-stdout https://www.jstorimer.com/blogs/workingwithcode/7766119-when...
- anderspitman 7y agoMight be because stdout is buffered, so you don't always get output right away, while stderr is unbuffered.
- btashton 7y agoYou split the user interaction from the logging. In the case of the webserver maybe this a less of an issue, but if I'm processing text output from an application I don't want a log message inserting itself in the middle of the output.
- photon_lines 7y agoCool and thanks for the feedback - yup, I actually played around with deploying it using GCP and had issues due to the logging, so I definitely regret not using stderr/stdout!!
- aaronmgdr 7y agook but its over 800 lines. I guess that's small for everything it does? Yet it's certainly more than the size I think when i hear "single file"
- erikig 7y agoI'm enjoying these "in a single file" projects. They aren't often the paragon of best-practices but they make it easy for newbies to peep in on the syntax and see how complex problems can be solved. They are also usually a lot easier to try out, compile and deploy. Here are a few others: - Twitter Clone in Haskell in a single file - https://news.ycombinator.com/item?id=21616661 https://news.ycombinator.com/item?id=21616661 - MPEG1 in a single C file - https://news.ycombinator.com/item?id=20643336 https://news.ycombinator.com/item?id=20643336 - SingleFile CMS - https://news.ycombinator.com/item?id=18336986 https://news.ycombinator.com/item?id=18336986
- everdev 7y agoIt is an interesting idea, but it can be overkill. Just because it can be done doesn't mean it should be. For example, there are ~130 lines of CSS in the Go file. Most editors have auto-formatting and suggestions for CSS for files ending in .css, which you won't get with this setup. Also, with 885 lines of code, you have to wonder if reading the code is easier via scrolling / searching a single file or via tabs with multiple files.
- rcarmo 7y agoHave a look at http://github.com/piku/piku http://github.com/piku/piku as well :)
- deleted 7y ago[deleted]
- zubairq 7y agoHow do I see the HTML and css in the GO code? Is it inlined somewhere ?