Ask HN: How are you using Go to write production-grade back end services? - <AUTHOR> As the title suggests. Interested to see how (and what) companies are using Go to make production grade backend services.
- What are you using for tests?
- Do you use dependency injection or any mocking frameworks?
- Are you using any routing frameworks?
- HTTP web frameworks?
Would love to know the ins and outs! What is good, what do you not like about Go, any pain points? Anything you would want to improve?
Thanks! <comment><USER2> For our backend[1],

\- We are using the default test framework that comes with Go; go test.

\- We usually follow Postel's law which translated to Go, would be: `Accept interfaces, return concrete types`[2] This enables us to pass in fake interfaces during tests. I haven't checked what kind of performance cost(if any) we may be paying by passing around interfaces instead of concrete implementations; but performance has not been a problem so far so we are just happy with our approach.

\- We do not use any http web frameworks, we are just using stdlib's net/http. We pair that with certmagic[3] for automated TLS certificate issuance and renewal.

I like the performance of Go, it is easy to pick up and it comes with a pretty great stdlib.

What I do not like is the fact that it has nil pointers, and you tend to run into one or two nil pointer dereference errors once in a while.

1\. [https://errorship.com/](https://errorship.com/)

2\. [https://blog.chewxy.com/2018/03/18/golang- interfaces/](https://blog.chewxy.com/2018/03/18/golang-interfaces/)

3\. [https://github.com/caddyserver/certmagic](https://github.com/caddyserver/certmagic)

</comment><comment><USER3> \- Web: No framework, I mostly use [https://goswagger.io](https://goswagger.io) but for basic stuff then just the standard http library + [https://github.com/julienschmidt/httprouter](https://github.com/julienschmidt/httprouter)

\- Testing: [https://golang.org/pkg/testing/](https://golang.org/pkg/testing/) \+ [https://pkg.go.dev/mod/github.com/stretchr/testify](https://pkg.go.dev/mod/github.com/stretchr/testify)

\- Mocks: [https://github.com/golang/mock](https://github.com/golang/mock)

\- Dependency Injection: None, current user of [https://github.com/uber- go/dig](https://github.com/uber-go/dig) and I regret it.

</comment><comment><USER4> I've built a pretty complex and high performance go-based microservice architecture (~12 services) as backend with testify and gomock for testing. Pretty happy with those choices, never had any issues. The backend doesn't use HTTP, so no opinion there.

I recently started migrating some of the services to Rust for performance reasons. I would say that Go's biggest strength is perhaps its biggest weakness as well: It "just works". Types are loose (no generics), concurrency is extremely easy. This means I can write working Go code really quickly, but as project complexity grows, code tends to become kind of a mess.

For example, channel-based concurrency can become hard to reason about if you have a complex service. A few times I ended up putting mutexes at various places just to make it work despite knowing that it's not the "right" thing to do. Mutexes then come with their own issues. Once you have a deadlock or race condition, good luck debugging it. There exist multiple packages and tools to detect race conditions and deadlocks, so this seems to be a common problem. I must've spent days or weeks worth of time looking at pprof output. You may say it's my fault as a developer to write sloppy code, and that may be true, but the Go language encourages such code with the decisions it made.

The same goes for types. I never needed generics, but the fact that typing is so loose means you can get away with a lot of sloppy code without being punished for it. This can be great for moving fast, but may come to bite you later on.

</comment><comment><USER5> My work mainly involves setting up internal enterprise applications.

\- The standard testing package

\- Manually setup dependency injection. Generally a flow like config=>databases=>models=>routes=>server.

\- [https://github.com/gorilla/mux](https://github.com/gorilla/mux) for routing and [https://github.com/swaggo/swag](https://github.com/swaggo/swag) for documentation

\- As for HTTP frameworks I just use the standard package and I really enjoy [https://github.com/sirupsen/logrus](https://github.com/sirupsen/logrus) for logging

We use IIS. I really wanted to use go so, I found a way to run go applications on top of it. That was not fun to figure out, but I can make use of the windows authentication underneath IIS. Required a custom module that forwards some headers to my go applications. Also the version of IIS we use doesn't even support http2 which sucks.

<comment><USER6> I remember setting up Python to run under IIS.. what a ballache that was.

</comment></comment><comment><USER7> \- Ginkgo and Gomega for tests, though sometimes just stdlib on smaller projects. I like Gomega very much, great matchers, lots of useful helpers.

\- Manual DI, passing in values and objects. We've hand mocked a handful of components: just what's essential for testing.

\- Mostly not using HTTP. But a few projects do, some simply use basic stdlib, others use Echo.

</comment><comment><USER8> At a previous job we did a 'tech experiment' to write a Go REST service. As far as I'm aware it's still in use in a production-level capacity. It used the following:

\- gotest

\- No DI, but in hindsight this would have been the right thing to do. The dev team is 100% Python, so mocking was more the talk of the office than DI/IoC.

\- For routing and HTTP the service used httprouter [https://github.com/julienschmidt/httprouter](https://github.com/julienschmidt/httprouter)

I think it's a fantastic language, gofmt and gotest are both great utilities, and the short time to create an executable made development turnaround a breeze.

However, I think for the purposes of a simple REST service I would probably use Python/Flask. Less boilerplate and for a Python team, it would have made more sense ...

</comment><comment><USER9> Testify for assert and require. GoMock for mocking, but only when it really adds value over a handwritten fake. Table driven tests wherever possible. Don't need heavyweight test frameworks.

Plain HTTP/JSON encouraged for edge-facing services only, typically not in Go. Between services, GRPC, integrated with our metrics, distributed tracing, and auth. When plain HTTP does happen, gorilla/mux.

Wire or FX for DI.

Implicit satisfaction of interfaces is the core of the language. The type system will feel maddeningly obtuse until you learn to use them effectively. It took me a few days to learn the language's structure and start shipping code, but a few years to grok the implications of that simple structure and design software in harmony with it. Interfaces are the key. Think Haskell typeclasses, not Java.

</comment><comment><USER10> I'm using Go with Redis for various aggressive caching needs. I batter Redis and Go performs very well. A few other languages will work mostly fine for my purposes, however I like working in Go and have always had a great experience with its performance.

No traditional testing. Standard library and Redigo. That's it.

No pain points for what I'm using it for. I usually try to avoid complexity in anything I build. This is a rather simple system that is only meant to take a high volume beating, cache to Redis (content later retrieved & presented by another part of the application via another language) and be reliable.

</comment><comment><USER11> I've been using standard router and Gorilla Mux for about 5 years now and have so many snippets that I can compose apps with.

I recently built an lru based rate limiter [0] that is compatible with both - it might be useful! Obviously it would need love for multi host but PRs welcome

[0] [https://github.com/17twenty/gorillimiter](https://github.com/17twenty/gorillimiter)

</comment><comment><USER12> I'm using gotest for testing, my testing is really primitive right now, no mocking frameworks. The only non-standard library I'm using is gorilla/mux for routing. Go feels a little verbose and restrictive coming from Python, but after being acclimated, I love it. It's extremely productive, performance is nice, deployment is so easy. The pain points for me were understanding the package system and structuring my project, which I worked through eventually.

</comment><comment><USER13> I've been wanting to do a blog series on how we use Go. Here is a short version.

Tests:

We use the testing package for unit tests and (maybe too much) use interfaces as arguments so we can create test fakes that behave the way we want so we can validate error paths, logs (yes, we assert on logs), metrics, and, of course, green/good expected behavior.

We then have acceptance level testing. These are ensuring the system works as expected. We leverage docker-compose to spin up all our dependencies (or, in some cases, stubs - but only rarely). We then have a custom testing package built atop the stdlib one. It behaves very similarly, but allows for the registering of test suites, pre and post test suite methods, pre and post test methods, and generates reports in json/xml for QA to keep track of test cases, when they ran, pass rates, etc. As part of our SOC2 compliance, we have these to back up our thoroughness in testing. Tests also can have labels so we can run all tests for a given feature only, or a given suite. These tests hit the running binary of our service under test, so if it works here, it will work when deployed.

Before a service makes it to prod, it lands in staging. There, a final suite of tests go through user features and ensure that things are ok one last time. Total black box.

Dependency Injection / Mocking:

I am very, very much against mocking. For that, I did write a blog post; though, I think the thing it highlighted most is I need to write more :). You can goolge "When Writing Unit Tests, Don't Use Mocks" if you want to read it. When you mock, you create brittle tests that are tied to the assumptions in your mock. Instead, we use "fakes." These are test structs that match an interface and allow us to control their behavior. You might ask how that is different than a mock. Mocks have assumptions and make your tests more brittle and subject to change when you update the code (which is what Martin Fowler concluded in Mocks Aren't Stubs). People tend to write "thing called 4 times, with arguments foo and bar, and will return x, y, z... blah blah blah." Instead, when you use a fake struct that matches an interface, you can make them as simple or complex as needed, and usually simpler is better. Return a result or an error. Validate the code does what you need. We also avoid functions as parameters for just testing. IE, your test code uses a custom function that is not the function used in prod. These are easy to cause nil panics and are kludgy. Fakes get us what we need 99 times out of 100.

Routing frameworks:

We have folks who don't use them, or use gorilla mux, or chi (my fav). They are convenient and make things easier for passing URL parameters. You can, of course, do this without a customer router. I like Chi because it is stdlib compatible.

HTTP Frameworks:

Nope. I could see, maaaayyyybee if we were writing a bunch of CRUD apps, but we don't. The services my team makes tends to have few routes and not all the CRUD stuff. Even then, if we do a lot of CRUD work, it will only eat up a few days. What we do have, however, is a project skeleton generator so our projects all start out with the same basic directory structure and entry points. Everyone knows that your app starts in cmd/appname/main.go for example.

Logging (and errors):

The other one we leverage in place of HTTP Frameworks is a custom logger and an experiment we are doing with custom error types. We have logging requirements to play nice in our ecosystem at work. Logs all are structured json and have some expected keys. The logger generates all that. We looked at all the log packages and none matched exactly what we needed. We can store key value pairs on the logger and pass that logger around (so you only have to do logger.Add("userid", userID) once and now all logs going forward in a request will have it. You get timestamps, app name, and a few other fields for free. You can create a child logger that will have its own context kv pairs so you don't pollute its parent (helpful for when you go into a function and want to add more details to logs based on errors specific to that function). The other one that we are playing with now on our new project is a custom error type that stores a map of key value pairs so we can just bubble up our custom error type, wrap it with more kv pairs on each bubble up, and then only log at the top, and then when the error is logged, we use our logger to extract the KV pairs and bingo, structured logs with context for each error bubble up point with potentially relevant kv pairs that are only known down in deep levels.

BuildPipe:

We run our tests locally usually. But when we create a PR, a build is kicked off using BuildKite (plugin system is really nice). A PR cannot be merged to master until the test suite passes, which includes the acceptance tests from earlier. After merging to master, a fresh build is run again and that creates artifacts that are then used by ArgoCD so we can roll our code out to our kube cluster.

I love Go. It is my favorite language I've worked in. There are warts, for sure. You can get that list anywhere. There are some oddities when assigning to structs in maps, nil interfaces, shadow variables, non-auto-checked discarded errors, and others. The biggest wart right now is the module system. I think that will improve over time.

<comment><USER14> Appreciate the thoroughness of your comment (if you expand further in blog posts, I'll read em). How did you settle on your standard project structure and what does it look like?

<comment><USER13> Here is a fairly typical project structure you would find in one of our projects

        /.buildkite
        /.github
        /acceptance # for housing the acceptance level tests
          /bin # scripts to help
          /config # an anti-pattern, but we like a config package
            /config.go
          /tests
            / # misc go files for testing
          /$foo # any other packages directly related to tests or the environment
        /bin # any scripts to help with anything
        /cmd
         /$appname
            /main.go
          /$bar # any other installable binaries
        /config # an anti-pattern, but we like a config package
          /config.go
        /$raz # packages that support our service
        /internal # stuff we want to import but not let others import. Seldom used.
        /server # or $appname, our main service code
        .gitignore
        .Dockerfile
        README.md
        docker-compose.yml
        go.mod
        go.sum
        makefile

</comment></comment></comment><comment><USER15> \- Test -> stdlib + testify/assert + vektra/mockery

\- Dependency injection -> manual DI passing values and objects down

\- Routing framework -> gorilla/mux

\- HTTP web frameworks -> stdlib + go-kit for the general architecture

We then have a pretty large internal library for all things shared

</comment><comment><USER16> Heh, production grade depends more on the people in charge than the tech choices. The lack of exceptions in Go is the biggest stupid thing in software. Exceptions have always been a much less risque feature than multiple return values. In Go every single "function" has multiple return values and the code is litered everywhere with if err != nil... garbage. It will never change because it is apparent that exceptions are to Go as collection literals and operator overloading are to Java.

<comment><USER13> I've worked in exception based code bases such as Python (Twisted specifically) and Go. Unlike many, I've used both in the same organization working on similar problems for nearly a decade while the scale of number of engineers working in the code and the number of requests it serves have gone up considerably. Hundreds of contributors. Billions of daily requests.

I humbly suggest that indexing on the lack of exceptions as a quality measure is a poorly lacking criteria. Ditching exceptions in Twisted Python and porting code to Go has created vastly more readable, maintainable, and performant code in multiple cases for us.

<comment><USER16> I understand golang was an attempt to fix c's shortcomings and not to create the next c++ or java. But I also understand programmers get their way of doing things that are bad. Case in point, people who do println("entering function doit()"); println ("exiting function doit()"); for every function in the entire codebase because it's how they learned to "debug" and they never tried anything better. Error returns in golang are like that. It has to be for every function in the codebase and balloons the code by a non-trivial percent.

As for performant, as of at least ten years ago it became impossible for a person to perceive a performance increase by removing exception handling. A human can't perceive the microseconds.

<comment><USER13> > As for performant, as of at least ten years ago it became impossible for a > person to perceive a performance increase by removing exception handling.

You are really hung up on the exception handling. I never claimed that the error handling made Go more performant. I wrote "performant" as in "there are other things that are important that should be taken into consideration aside from use of exceptions". It might not be as apparent to others now as you edited your original response that was along the lines of "not using exceptions is the worst software decision of all time." (note I don't recall the exact thing you wrote, but that feels close).

As for the new edit you have:

> litered everywhere with if err != nil... garbage

I just grepped one of my Go code bases. It is 40,636 lines of code. It has 326 "if err !=" lines. Less than 1% of the lines are for error handling preamble, and we take our error handling very serious. In fact, a lot of those error checks don't directly bubble up. They perform fallback logic, logging and/or metrics, or set sane default values. Sure, some bubble up, but it is less than half as grep suggests 134 bubble up.

What I value about local error checking is that everything you need is right in front of you as a reader of the code. When I worked in Twisted Python, one particularly bad case of exception handling made it so I literally could not use ErrBacks in one part of the code because in some other module someone used an exception for a non-exceptional error.</comment></comment></comment></comment>


New Social Networking Website - <AUTHOR> http://www.zubby.com

<comment><USER2> Not to be mean, but yeah... you guys missed this boat a long time ago.

Unless you can tell me how you're better than Facebook or MySpace or offer something different from them, then I don't think you'll get past the high barriers to sign-up.

</comment><comment><AUTHOR> Just about 2,000 members and growing...</comment>


Giving up the Chromebook - <AUTHOR> http://betanews.com/2011/10/02/im-giving-up-google-chromebook/

<comment><USER2> as a chromebook user, i find this article disappointing. what it really summed up to was flash is not working well -> chrome os is doomed, instead of maybe chromebooks need a hardware boost. By that theory iphones/ipads are worse because flash doesn't work at all. I will also say that i have found flash to be working better on the device as the upgrades have progressed.

The biggest flaw with chrome os has been google not educating users on new features as they come out. for instance the average user has no idea that they can open apps in panels.</comment>


Ask HN: Why do I get so much traffic from random spam websites - <AUTHOR>

Looking at my GA, I see I'm getting lots of traffic from random spammy websites. Do you know why this is?
e.g. floating-share-buttons.com and 100dollars-seo.com
How can I stop this?
Thanks, http://cl.ly/image/1K2Q1r381f2l <comment><USER2> This is a technique called referrer spam. It's not real traffic just a way to get you as the owner of your site to visit theirs and "hopefully" purchase whatever they're trying to sell.

If you wish to clean up your reports the only real way to do it is using filters[0]. Or optionally switching to a different analytics provider.

[0] [http://blog.analytics-toolkit.com/2015/howto-fix-ghost- traff...](http://blog.analytics-toolkit.com/2015/howto-fix-ghost-traffic-spam- rubbish-google-analytics/)

<comment><AUTHOR> I see. I can filter it out but is there any way to stop it? Thanks,

<comment><USER3> Yes, you can filter it at the GA level or block it server-side but some of it can only be blocked at the GA level (because they are sending a fake ping to Google with your GA ID, rather than crawling your website)

<comment><USER4> They are actually hitting the website. I don't use GA (I wrote my own analytics) and that's what i see in logs.

</comment></comment></comment></comment><comment><USER5> Really long time ago I found a similar behavior in one of my sites. And it was because I had Awstats publicly accessible and they were interested in put their link in the page as it was indexed by Google.

</comment><comment><USER6> They hope you will publish the URLs (which you have) :-(</comment>


This post on uBeam nailed it. @msuster should read this - <AUTHOR> https://ludwitt.wordpress.com/2016/05/13/what-mark-suster-missed-in-his-blog-post-defending-ubeam/ <comment><USER2> Please use to original title of the submitted article ("What Mark Suster Missed In His Blog Post Defending uBeam"), see [https://news.ycombinator.com/newsguidelines.html](https://news.ycombinator.com/newsguidelines.html)

EDIT: also see discussion about this topic currently on the front page: [https://news.ycombinator.com/item?id=11693184](https://news.ycombinator.com/item?id=11693184)</comment>


Ask HN: Lisp / functional programming freelance experiences? - <AUTHOR>

Are there any Lisp freelancers doing projects in this lovely language? Or is it all hobbyists?
I'm coming from a C# background but for a while now my love was with functional programming and particularly Lisp. C# / SharePoint gigs earn good money, whereas Python seems to be less in demand and rather valued about as low as PHP, maybe a little higher. Maybe Ruby is closest to providing a "healthy" (for the programmer), strong-demand freelance market when wanting to work functional... any freelancers out there being able to work on projects they love, other than their own? My C# / SharePoint projects pay the bills but I increasingly loathe them. I don't want to get trapped in the "deferred life plan" where I get to do what I love only nights and weekends and do things I don't really like doing any more for a living.
Maybe it's unrelated to the actual technology and just the "someone else's project" that is the cause for the bad flavour of project work. But that would require some psychological analysis I don't care to indulge in; right now I'm interested in how Lisp and/or functional freelancers are faring! <comment><USER2> If you follow the link: <http://www.software-lab.de/download> you will find a Lisp that the author (and I) has used in many projects. I believe he has been freelancing for over 30 years, and at least the last 12-15 have been using this (or predecessors of it) language. I have also been freelancing for 19 years and "doing what I want". I did python for 7 years and have now switched to using picolisp. randix.net

<comment><USER3> Perhaps you meant: <http://www.software-lab.de/down.html>

</comment></comment><comment><USER4> I recommend that you get in touch with Clozure (www.clozure.com). They know more about contract Lisp work than just about anybody. There are many consultants who work, via Clozure, for companies doing work in Lisp.

Or, apply for a job at www.itasoftware.com. I love working there. See <http://dlweinreb.wordpress.com/2007/12/24/16/>.

</comment><comment><USER5> I've done a few paid projects using Lisp. It's usually not too hard to talk people in to when they aren't committed to a particular technology already and are hoping to get the best combination of cheap/fast/good. I have a project coming up involving small-business networking for a particular company's customers and I'm planning to use Common Lisp for that.

</comment><comment><USER6> We do much of our web development at <http://bitfauna.com> in Lisp. Most of our clients don't care what language we use, and wouldn't know Lisp from Ruby or Python. At the end of the day, the client cares about whether the site is a) working b) economical.

Lisp is not all we end up doing for clients, and we have the odd job where we maintain and update legacy applications in C# or ColdFusion. But, we have never found an issue using Lisp for new projects.

</comment><comment><USER7> Have you considered joining a company that uses Lisp? Why do it on the side?

I have a new theory about getting what you want. Just do it. It has worked splendidly for me so far.

I would imagine freelance Lisp would be a good way to learn as well. Rather than toy problems, you can solve someone's real problem.</comment>


Coronavirus Data Visualizer from Germany's Best Kept Secret - <AUTHOR> https://www.germanysbestkeptsecret.com/corona/?ref=hn <comment><USER2> Nice! I kind have a python package that generates something similar to what your website shows ([https://github.com/AaronWard/covidify](https://github.com/AaronWard/covidify))

</comment><comment><AUTHOR> After submitting this, I discovered:

If you click the coronavirus icon in the top left a few times, the data doesn't seem quite that bad...</comment>


Don't Trust Anyone Who Doesn't Drink - <AUTHOR> http://www.businessinsider.com/dont-trust-anyone-who-doesnt-drink-2010-1

<comment><USER2> im going to cite this on all my expense reports from now on.</comment>


Tips for Success in Undergraduate Math Courses (2002) - <AUTHOR> https://web.stanford.edu/class/math53/jasp.html <comment><USER2> I mostly aced my math degree. The keys for me were:

1\. Read and get a basic understanding of the material before lecture.

2\. Attend every lecture and take notes very few if any notes. Most of what you need is in the book and math is about understanding. You cannot grok and write at the same time, and it's better to try to grok while an expert is explaining it to you.

3\. Do a shitload of problems / proofs, depending on the class. Be honest with yourself when you don't fully understand something and stick with it until you do.

Math is different from other subjects, and you need to treat it that way.

<comment><USER3> I agree with this, except for 2. I need to write things to internalize them, and I get a lot more out of lectures I take notes in because it keeps me focused.

<comment><USER4> > I need to write things to internalize them.

Have you tried air writing? Or just "doodling" some notes when in a lecture? It worked for me.

<comment><USER5> This. By not worrying about whether your notes are actually complete / sensible, you get the cognitive advantages of writing stuff down without the distraction. You can still make a proper summary after class if need be.

</comment></comment></comment></comment><comment><USER6> Haha, this is very similar to the list I came up with when I was flunking at Caltech:

1\. attend all the lectures

2\. attend all the recitation sessions

3\. do 100% of the homework, and on time

4\. make sure to understand every homework question and how to solve it.

5\. write legible notes

This was good enough to get a baseline B. To get an A, you had to put in much more work.

I know this stuff seems obvious. But it took me a while to figure out I couldn't just coast and wing it like in high school, and many other students had the same experience.

<comment><USER7> I'll got a bit further if I may, but its mostly a tip for the instructors:

Start from the basics. This makes such a tremendous difference I think, because we have these pre-conceived ideas about math, numbers, calculus, etc. (due to usually shitty high school education) that must be shattered and rebuilt from the ground up.

Here are the example notes that my undergrad (in fact, first college math class) professor used:

Lecture 2: Numbers [https://www.math.ualberta.ca/~xinweiyu/117-118.14-15/2014090...](https://www.math.ualberta.ca/~xinweiyu/117-118.14-15/20140904.pdf)

Lecture 3: More Numbers and Rationals [https://www.math.ualberta.ca/~xinweiyu/117-118.14-15/2014090...](https://www.math.ualberta.ca/~xinweiyu/117-118.14-15/20140905.pdf)

Lecture 4: Irrational Numbers [https://www.math.ualberta.ca/~xinweiyu/117-118.14-15/2014090...](https://www.math.ualberta.ca/~xinweiyu/117-118.14-15/20140908.pdf)

As you see there is a very clear and natural progression from fundamental assumptions of mathematics to common day objects, with justifications.

From this you introduce the notions of infinity, again with historical developments (math didn't just come about in the last 50 years!)

Lecture 5: e [https://www.math.ualberta.ca/~xinweiyu/117-118.14-15/2014091...](https://www.math.ualberta.ca/~xinweiyu/117-118.14-15/20140910.pdf)

And so on; By rebuilding your knowledge in this deliberate way it becomes easier to work with more difficult topics later on.

<comment><USER8> I went to the UofA 20 years ago. The math profs at that time were so bad I got turned off math forever and went into business school for finance. I have many stories, but the worst was when one prof quit half way through the semester because he demanded silence in class but didn't get it. Then the math dean said we could learn the rest of the course by reading the textbook with no lectures and the entire grade would be from the final exam. Seems like they have improved since then.

</comment></comment></comment><comment><USER9> My math grades had some ups and downs, and the key variable was doing the problems / proofs over and over. Likewise for physics courses, which involved a lot of the same kind of stuff.

I think it's important to get the "mechanical" work, e.g., step by step derivations, so it can be done quickly and accurately. For me, this is also resulted in committing the definitions, axioms, theorems, etc., to memory. During exams, being able to speed through this work gave me the spare time I needed to sit back and think about each problem, especially the one "surprise" problem in the set.

Oddly enough, I kind of treated the humanities courses in a similar way. I signed up for courses that were known to be graded based on mostly written work -- essays, papers, etc. Because all of these courses involved the same "mechanical" work, e.g., writing a paragraph supporting a concept, I also got very quick at it, which compounded itself in terms of getting assignments done quickly and writing fairly lengthy, coherent answers, in blue-book exams.

Note: It also helps a lot to actually enjoy the stuff. Attending the lectures helped me later in life, as I observed the teaching styles -- good and bad -- of my teachers. That experience has helped me with presentations and other kinds of interactions in my regular job.

</comment><comment><USER10> (Other useful strategies not mentioned)

* Watch video's on Khan Academy/youtube * Use Wolfram Alpha to confirm/deny yr solutions * Get a tutor who can explictly show you how they approach solving any arbitrary problem you bring them * Accumulate a list of math tricks that you can use and how to use them (example: how to long divide polynomials) * Print out old exams and pretend to take them ~3 days before final * Rewrite your lecture with each example problem on it's own page(s) * Create an index on your lecture notes so that you can quickly identify what type of problems and topics were covered in each lecture. * Identify yr strenghts - we can't all be good at everything - knowing yr strenghts will give you a foundation of confidence to build upon * Queue cards for memorizing all those trig identities * Expect to spend a lot of time - this is not always possible

<comment><USER11> HN really needs 'bulletpoint' markup...

<comment><USER12> HN can do

      * bullet
      * points

<comment><USER13> True. As you've noted elsewhere, this is intended for code. It doesn't work very well for text. You have to break the lines yourself rather than relying on the browser. If you break wrong, those with small viewports end up with nasty side scrolling.

<comment><USER12> _Videos_

Watch video's on Khan Academy/youtube

 _Wolfram Alpha_

Use Wolfram Alpha to confirm/deny yr solutions

 _Tutor_

Get a tutor who can explictly show you how they approach solving any arbitrary problem you bring them

 _Tricks_

Accumulate a list of math tricks that you can use and how to use them (example: how to long divide polynomials)

 _..._

<comment><USER13> That would be one way to do it.

</comment></comment></comment></comment></comment></comment><comment><USER14> For my first classes this was true. Now I'm getting courses that fewer students take, and it goes like this

1\. Skip lectures because the professors barely speak english and can't teach

2\. Barely rush through the homework before its due, it doesn't matter if you understand it as it has no relation to the rest of the class

3\. Find last semester's exam and study that for a morning, as the questions are pretty much the same.

Its a shame that the higher level courses that should be more interesting and useful end up being the most painful and disregarded.

<comment><USER15> Strange. That was the case for my first couple years, in classes with hundreds of students, where the university hadn't yet shed its "look to your left, look to your right" mentality. Later classes had fewer students and engaging professors, since they'd weeded out many of the worse students.

<comment><USER16> Universities sabotage undergraduate education by conducting lectures in foreign languages. Interesting.

<comment><USER17> Its more a side effect. Everyone knows everyone cheats on the TOEFL yet it would be incredibly awkward in academia to discuss that issue, so its kinda glossed over to avoid massive interpersonal drama. But, yeah, any prof or TA you have who doesn't know English is a known cheater, violation of honor code, etc. It does make you wonder if their CV or transcript or reference letters or published papers are as fabricated as their obviously fake TOEFL scores.

<comment><USER18> Toefl is a surprisingly easy test to pass even with a strong non-native accent. I know people with mediocre to bad command on English who achieved scores of over 100 on the online test. There is no reason to cheat the system.

<comment><USER15> That may be, but several of my classmates in grad school told me that they regularly wrote their papers in Chinese and sent them to a translating service for English. These were students who were conversational in English. It makes you wonder how much the translator changed the content.

<comment><USER18> I am not acquainted with the Chinese system, but here in India, you have to personally go to the designated test centers and take the test. At the center there is some Airport level frisking before you get to see your computer and you need to have your passport with you to prove your identity (if I remember correctly). You are also not allowed to wear jackets/overcoats/caps while taking the test. Really very little chance for gaming this system.

<comment><USER15> That's for standardized tests. I was referring to homework assignments in the US.

</comment></comment></comment></comment></comment></comment></comment></comment><comment><USER19> For the memorization aspect, I would say use spaced repetition software:

[https://en.wikipedia.org/wiki/Anki_(software)](https://en.wikipedia.org/wiki/Anki_\(software\))

Source: I actually did this and it improved my grade 55% in Calc I.

<comment><USER20> I've used Anki for some of my courses but I don't know how I should use it for math courses. Can you maybe share your calc Anki cards?

<comment><USER19> My calc anki cards have copyrighted material in them so not off hand no.

But generally what I would do is use them to memorize anything I needed to know while I was solving a problem but couldn't remember.

The important thing is to know how to write mathematical expressions in LaTeX syntax, because this lets you make non-crap cards. You might do something like:

\frac{d}{dx} \cos x = ?

On the front and then

\- \sin x

On the back.

The important point is that between the front and the back you actively recall the information you're trying to remember. Undergrad mathematics can be thought of as a context free grammar with a set of production rules, memorizing those production rules is a major pain in the ass and this helps.

(Maybe other people don't have trouble with this, I nearly failed every math class in high school and am decidedly not a math prodigy. Your mileage may vary.)

</comment></comment></comment><comment><AUTHOR> There is some pretty obviously advice in here; basically take notes and do your homework for the sake of comprehension and not merely completion. But, "keep a list of hard problems" is pretty good advice that, I think, most people do not adhere to.

</comment><comment><USER21> My breakthrough in math came when I started studying with other people. Best way to learn something is to explain it to somebody else. And you're a lot less likely to get stuck on something for half an hour if you have other people to help you. By studying with people I aced calc just by going to class and keeping up on homework.

<comment><USER22> Depends on who you are. I can't listen to other people talk about math without getting confused myself. Other people think about math differently and often throws my own thinking into a loop. I need to study alone and ask questions if truly stuck.

</comment></comment><comment><USER23> The issue I have with lists on how to be successful in a class is that they rarely provide much guidance on how to prioritize the work. Of course students are successful in a class when they read & understand the material before the lecture, follow the lecture attentively, redo all example problems, solve & understand all assignments and maybe read a few textbooks on the subject. The difficult part, at least for me, is how to decide what learning activity will help your understanding in the most any given moment and how to split your time between the different classes and other activities.

</comment><comment><USER24> I'm a math major.

This list reads like my strategy to do well in a math class without learning the material (literally; this method got me through numerical methods and advanced calculus, both classes that I had no interest in and took only to satisfy the degree requirements).

My thoughts on the particular points:

>Keep a list of THINGS TO MEMORIZE.

If this list is anything but empty you should feel bad. "Memorizing" something in math is a way to act (and test) like you understand it without understanding it. The one exception is in computationally heavy classes, where you memorize the completed solution of common forms. However, if your goal is to understand the material, you should be able to derive everything you are memorizing without thinking. The memorization is only to save you time on the exam by skipping the computation. Having said that, as I mentioned above, if you do not understand something but still want a good grade; memorize it. The professor will never see the difference.

>Watch for example problems.

Because these will be the problems on the test.

>Know how to do every homework problem assigned!

Yes. Also, know how the book/teacher wants you to do the problem. It is often times hard to write a problem that can only be solved one way, so it is sometimes possible to avoid using a method you don't like or understand.

> Start the homework at least a few days before it is due.

Yes. Also, if possible, consider homework due at the last office hours before it is actually due. Otherwise, you can't go to office hours for help.

>Keep a running list of HARD PROBLEMS.

Good advise if you are going the memorization route; otherwise, this is just memorizing the solution to a particular form of questions. Also, in my experience, if you are going for the understanding route, this list just does not stay relevant long enough to justify keeping it.

>When you get your homework back: Look over the things you got wrong.

Always good advice. Having said that, if you got a problem wrong (for reasons other than computational/algebraic mistakes), the bigger issue is that you thought you got it right. This means that you not only did not know how to solve the problem, but that you have misunderstood some concept that you need to learn.

>Find a quiet place, set a timer for the amount of time you'll have in the exam, and take the practice test. Don't look at the practice test before you do this.

Good test prep advice in general.

>If a problem is hard, skip it and come back later.

I triage problems much more aggressively. If a problem looks time consuming I skip it. If a problem looks like it involves thinking, I do enough work to verify that it actually involves thinking then skip it.

>Do a quick check of each problem to be sure your solution is reasonable. E.g. if the problem asks for a distance, is your solution positive?

Do this check after you finished the test. If you got something wrong, but didn't finish the test, then knowing you got it wrong doesn't help; you still didn't have a chance to correct it. Also, you are more likely to notice an incorrect answer after spending time away from the problem.

Having said that, sometimes you answer "feels" wrong as you are solving it. If this happens and you see where you went wrong, correct it. Otherwise, complete the incorrect solution (if feasible), and mark it. This gives you the chance for partial credit; and sometimes your feeling is just wrong, and the answer is weird.

>Write SOMETHING on every problem. The grader really wants to be able to give you some partial credit.

If you have time. If you really have no idea how to approach a problem, then your time would be better spent doing better on the rest of the exam instead of producing a plausible looking solution. Mark these problems, and, if you have time at the end, come back and look at them again.

Having said that, this is still good advice. If you think you know how to solve part of the problem; do it. If the part you know how to do requires you having computed something that you do not know how to compute, then clearly write "let a = thing I can't compute". Graders don't have time to look closely at your answer; make it easy for them to give you partial credit.

If you are answering a proof based question, and cannot figure out how to prove a particular fact that you need for your proof, consider writing "it is clear that". You will be amazed how often this works.

>When you've tried everything, go back to the problems worth the most points first.

Triage. Go back to the problems that you think you got wrong and can improve first.

>Given time, double check your algebra carefully!

If possible, verify your answers using a different method. For example, if you are asked to find the integral, verify your answer by taking its derivative. You are less likely to make the same mistake, and for many problems it is easier to verify an answer is correct then to find the answer

>After the Exam

Write down what you can remember about the problems you could not solve (including ones where you put down something that might be correct, but were not sure about). Solve these problems (using book/notes/TAs/etc if needed).

When you get the exam back, compare it to the list of problems you knew you didn't get. You don't care about these problems at this point; you already knew you missed them and worked through them. You learn nothing new by the grader telling you that you missed these.

The problems that you did not know you got wrong are where you should focus your attention. If you just forgot about them, then work through them like you did the ones you already knew about. If it was a computational/algebraic error, don't worry about it (but do do more practice if these errors cost you a significant amount of points). Pay special attention to problems that you thought you got right but didn't. These highlight the areas where you have a misunderstanding of the material.

Final remarks:

HARD PROBLEMS list:

As you might have noticed, I don't like this. What I do like is a concepts list. When you go to study, read through the list and make sure you understand all the concepts. It should be small enough that there is no point in creating a separate list for hard concepts; and what you consider to be an easy/hard concept will change as you get more practice with some things, and never see other things between the first month of class and the final.

Studying for the test:

As you probably noticed, my opinion is that many of these points are techniques to study for the test. This is a valid thing to do in school (after all, you are graded on the test, not understanding), but be aware when this is what you are doing. If you plan on taking another class that builds on this one, then this method will come back to bite you then.

In class notes:

Do not make them. The only reason you should be writing during a math lecture is to use the paper as a scratchpad to think about what is being said. Anything else is a distraction from the lesson. All the material should be in the book. If it isn't, you can ask the professor for a copy of his notes. If you want your own notes (which can be a good idea), write them after class. If you do take notes, keep them in a separate notebook. Interspersing them with problems and scratchpads just makes it more difficult to use them.

LaTex:

If you are taking math as a gen-ed requirement, ignore this. If you are going into a math heavy field, learn LaTex as early as possible. Write you notes in LaTex. Do your proof based homework in LaTex. This will pay off down the road, when you A) know LaTex and B) have a digital record of you previous math classes. Plus, turning in proofs written in LaTex make them feel far more correct, so you might get graded easier.

Study groups:

Form a study group of people with similar skills as you. If you try studying with people far better than you, then you will end up just having them give you the answer; in which case you are better off talking to a TA (who is probably better at explaining things). In a study group, you want to be part of finding the answer. Along the same note, if part of your group just gets the answer (and you are in the part that does not), start by talking with the other people who do not know the answer. That way you can figure it out together, instead of just being told what the answer is.

<comment><USER25> As a math PhD student who is supported through teaching undergraduates, I have to spend a lot of time convincing my students that they have misunderstood what math is and they do in fact have to memorize the definitions of the words. It used to be in high school that many of them could ride right through a course relying only on their native intelligence to derive or deduce everything, but this tends to bite them when they refuse to believe that each word has a specific definition in the subject --- and many times they are defined the way they are due to a few hundred years of effort by many smart people trying to figure out the best way of expressing some mathematical phenomena. For instance, "continuous" doesn't mean "can be drawn with a pencil" \--- while that is a fine intuition, if you need to prove something is continuous from first principles you had better remember that it means the function equals its limit at each point. Another is "linearly independent," though the usual error students make is wishful thinking that you only need to check that no vector is a scale multiple of any of the others.

For my own studies, there are many many definitions and theorems I just have to memorize. It is true that I have familiarity with how the theory is all proved, but in the end I have to remember what all the main theorems say. For instance, there is no way you can figure out what "Alexander duality" is or the axioms of a "group" are by their names alone.

Re computational errors: a lot of times they tend to be hidden conceptual errors, since if you had understood the concepts better you would have detected the error!

Re hard problems list: I disagree that keeping such a list amounts to memorizing certain kinds of solutions. I try to keep one mentally, which I use to try to figure out what about the problems seem hard. The hope is that the hardness of the problems dissolves, leaving me with fewer problems and more insight. Even better is when the hard problems suggest other hard problems.

Re "it is clear that": I recommend you find a grading job on campus. The usual reasons this "works" is that the grader is overworked and forgets it is only clear to them, or the student didn't say any nonsense elsewhere so they've earned the benefit of the doubt. But don't delude yourself outside the exam. (The worst are students who make their work intentionally messy to try to throw off the grader. Believe me, the mess is transparent.)

I used to have a distaste for memorization, believing in an ideal of "real math" which was some fountain of pure understanding we might come to know, but over the years I realized that to even begin approximating that ideal you need fluency in the various languages of mathematics --- and to learn a language you need to memorize its vocabulary at the least!

<comment><USER22> As a math PhD student I concur. I got through most of my undergrad memorizing nothing. It was easy back then. The definitions were simple and intuitive. what's a group? I hold an intuitive picture in my head which can be translated into words if I want. What's the Taylor series of cosine? If you want to do serious work in applied math you'd better have that on the back of your hand. You can derive it every time of course. You'll just take WAY longer. What is are the homology groups of a group with integer coefficients? Ha. Good luck doing anything with it if you haven't memorized it. Not memorizing might work in undergrad. I've reluctantly come to the conclusion that it doesn't work anymore. In fact not memorizing anything is biting me in the ass. It seriously hampers my workflow to have to look up the definition of Calc iii stuff. If you don't have some things mmeorized you won't even understand lectures. They don't take the time to let you get used to a definition in grad school. They give it to you and just RUN with it. They expect that out of you. They don't remind you. They expect that they can just give you the definition and start using it to prove theorems right away. Most of the time they don't give you the intuition for it either. No examples. You need to get used to the language of math and do it fast.

<comment><USER26> >What is are the homology groups of a group with integer coefficients? Ha. Good luck doing anything with it if you haven't memorized it. //

I feel you're missing the point the parent was making. The point as I see it is not to try not to know the answer without deriving it but to not set out to simply memorise the answer.

Of course through use you'll commit certain proofs, formulae, corollaries or what have you to memory; but that's not what people generally mean by "memorising". When studying [undergrad honours, UK] I didn't set out to memorise things and often relied on working out formulae/results/theorems from first principles or from some other theorem. [Perhaps this is a physicist thing, I did joint honours in Phys/Maths]

Remembering and memorising are different approaches that lead to a similar result; however IME remembering when you didn't set out to is often much better. For me I could cram and memorise some results, but then that subject matter never stuck around long afterwards.

</comment></comment></comment></comment><comment><USER27> The most useful thing that I did in any of my undergraduate courses was to make a point to go to all of the office hours offered. No matter whether the office hours were with the professor or a TA, I made a point of going, asking any questions that I had, and showing them the methodology that I was applying to a project/assignment/etc...

While I can't guarantee that this resulted in better grades, I know for a fact that the professors who I built relationships with during my undergrad have been incredibly helpful during my career!!

</comment><comment><USER28> I'm curious how many of these are also on the list of 'tips for success as an aspiring mathematician'. I just finished reading Benoit Mandlebrot's memoir and he repeatedly talks about how poor academic standing is in predicting a person's ability as a researcher. As someone who is not a mathematician I'm genuinely curious.

</comment><comment><USER29> Find a section of the math course that is being taught by a professor that is actually fluent. Math is rather infamous, particularly in introductory undergraduate courses, for having professors, brilliant though they may be, who speak broken, incomprehensible English.

</comment><comment><USER22> I'm still trying and most of the time failing to apply all of these things as a grad student.

</comment><comment><USER30> What worked for me: 1\. Get a solutions companion to your calculus book. 2\. Solve everything twice.

</comment><comment><USER31> Terry Tao (Field Medalist) has a lot of great writing on this subject: [https://terrytao.wordpress.com/career- advice/](https://terrytao.wordpress.com/career-advice/)

</comment><comment><USER32> Imho, you only need motivation. And where to get it, that's the question.

</comment><comment><USER33> I love GeoGebra, [https://www.geogebra.org/](https://www.geogebra.org/). What a (free) resource to explore Math for oneself!</comment>


Ask HN: Would you migrate from GitHub if it gets merged into Azure DevOps? - <AUTHOR> Would you migrate from GitHub if it gets merged / absorbed into Azure DevOps?
1. For your professional projects?
2. For your open source projects?
Related Q: Would you abandon VS Code if becomes primarily Azure Cloud focused? <comment><USER2> Github exists only by it's community. It's a kind of social network for the opensource. bitbucket or gitlab are equally valid for private projects. If github gets merged into Azure DevOps, a few peoples will leave by principle. If the mass do follow, everyone will leave it. if the mass does not follow, everyone will stay on it. That's what happened when github was acquired by Microsoft, and that's probably what will happen again.

So yes, i would like to migrate from Github if it gets merged into azure, but reallity is I will stay on it if there's no global migration of opensource projects</comment>


Show HN: Zero – A fast, zero-configuration server for React, Node.js, Markdown - <AUTHOR> https://zeroserver.io/ <comment><USER2> > File-system Based Routing: If your code resides in ./api/login.js it's > exposed at [http://<SERVER>/api/login](http://<SERVER>/api/login). Inspired > by good ol' PHP days.

> Auto Dependency Resolution: If a file does require('underscore'), it is > automatically installed and resolved. You can always create your own > package.json file to install a specific version of a package.

This sounds like a security nightmare.

EDIT: to be clear, I don't meant he combination of both is a security concern, that each one of them separately is problematic.

<comment><USER2> Putting my money where my mouth is - use this to leak any file accessible by the running user of zero from the filesystem:

        # curl -v --path-as-is 127.0.0.1:3000/../../../../../etc/passwd
        root:x:0:0:root:/root:/bin/bash
        [...]

<comment><AUTHOR> Thanks for pointing this out. Fixed this particular bug!

<comment><USER3> Seems like your fix[1] for this is a bit fast. You are already importing `path` in that file. Also, you can do this with just one `path.relative`. Lastly, the url package method you are using is deprecated[2].

[1] [https://github.com/remoteinterview/zero/commit/b4af5325c388e...](https://github.com/remoteinterview/zero/commit/b4af5325c388e21a9bba4c9305c9a61693c73578) [2] [https://nodejs.org/api/url.html#url_legacy_url_api](https://nodejs.org/api/url.html#url_legacy_url_api)

<comment><USER4> A simpler fix might be to canonicalize (i.e. no "..") the public folder path and the requested file path and then ensure the public path is a prefix of the other.

<comment><USER5> Any fix also needs to be sure to resolve any symlinks before doing a prefix check.

</comment></comment></comment></comment></comment></comment><comment><USER6> My first thought is it doesn't have enough features or too much magic BUT that is EXACTLY why it shines. I'm not going to build the next FAANG company on this but it will let me get a backend up and running VERY quickly to test out an idea. The number of ideas of mine that have been killed in the cradle by decision paralysis is higher than I would like...

<comment><AUTHOR> Exactly this. One of the aims to start this project was to reduce one more friction when testing an idea. Project configurations and set up is a big time suck.

<comment><USER6> Thank you for creating this! I often find I had an idea and then spend 1-2 hours doing NOTHING towards the idea trying to future-proof what I'm writing to the max. That is a trait of mine I need to work on by itself but "zero" should help let convince me to "just try it with zero before you setup TypeScript/Angular/Vue/React/Cordova/Express/etc...". I saw your other comment about making it Apache/PHP level easy and as someone who came from that background and when I first saw a query param displayed in the response from the web (ie: localhost?name=Josh -> Hello Josh!) I was hooked (you can imagine my reaction when I learned what a database was ).

In that vein do you think TypeScript is on the horizon for support? It's not a dealbreaker by any means but it would be nice to just write .ts files and have them automatically compiled (transpiled?). I can write JS just fine but TS's types are a nice sanity check for me.

<comment><AUTHOR> Thanks! I will def move .ts up the list. It should be easy to add.

<comment><USER7> Great work, if you need any help with it just add requestes on github and tag as help needed.

<comment><AUTHOR> I just added typescript support. Check it out!

</comment></comment></comment></comment></comment></comment><comment><USER8> "Zero configuration"

But, you can install express, copy paste the getting started code and be up and running at a similar level in 5 minutes. I...guess I don't understand why I should trade something super simple and easy to use for this additional level of abstraction magic.

There is such a thing as too much abstraction.

<comment><USER9> No, you cannot, not in an easy way. I've taught many people Node.js/express and they always struggle with all of those copy/pasted configuration bits. Now if I add them, I tell them something along the lines _This is just magic, copy /paste it to make your app work. Some day you will understand_.

Once you get used to them it's easy, but to get started it's a nightmare. I started with PHP back in the day, and even though it's hated around here the bar to getting started there is amazingly low in a good way.

<comment><USER10> That feeling of discomfort and tinge of frustration means you're learning. I feel like this is helping people to skip over a really useful lesson.

<comment><USER9> It means you are getting frustrated, evaluating your life choices and whether Node.js is really for you. The lesson they get is that Node.js is not for them!

I prefer those who are new to any webdev to get started by creating a simple CRUD, not with the grunt details like parsing a JSON body or what is this session stuff. Those IMHO should be optional optimization details to apply later on if you wish, but not mandatory for everyone.

</comment></comment></comment></comment><comment><USER11> Rule 35: Every year, someone somewhere will reinvent PHP or CGI or some combination of the two.

<comment><USER12> Where can I find the other rules?

<comment><USER13> These will carry you over until the "real" ones appear: [https://spacecraft.ssl.umd.edu/akins_laws.html](https://spacecraft.ssl.umd.edu/akins_laws.html)

<comment><USER14> I want to print these out and share them with past teams I've worked on.

</comment></comment></comment></comment><comment><USER15> This is exactly what I needed. However with great abstraction comes great responsibility: you are now the gatekeepers of keeping things efficient in the backend. If I write "require('moment')", will you blindly require, or will you require, tree-shake, minify, etc?

I guess my question is: can I trust Zero to always strive for optimum efficiency, or is it just convenience?

<comment><USER16> If your requirements include "optimum efficiency", you almost certainly are not in the sweet spot for a general purpose zero configuration product.

<comment><USER15> I guess optimum/optimal efficiency is a lot to ask for, of anyone, let alone a convention over configuration framework, but you get my point!

</comment></comment></comment><comment><USER17> Zero configuration... read "We made choices for you, just trust us. Read our documentation to see what your missing. Oh, also since you didn't configure it we'll change (the defaults) on our next release".

<comment><USER18> > Oh, also since you didn't configure it we'll change (the defaults) on our > next release

That doesn't really matter, since I'll only use the next release for my next release, and the previous prototype has either been thrown away or turned into a proper stack.

<comment><USER19> I wonder if this what the people who made the things I have to inherit and patch and secure believed.

Current app is EOL Framework Release in an EOL Language Release running on an EOL Distro Release on an unmonitored server without any patches applied... so business as usual.

</comment></comment></comment><comment><USER9> I did something very similar but arguably with even less configuration, [https://serverjs.io/](https://serverjs.io/)

        const server = require('server');
        server(() => "Place your Node.js API here.");

However my project doesn't have the automatic routing/installing/React, which looks great! Keep it up, I like the direction where this is going.

<comment><USER20> Hey, that looks cool too. Thanks for sharing it!

</comment></comment><comment><USER21> Make a RealWorld.io implementation or it doesn't exist!

[https://github.com/gothinkster/realworld](https://github.com/gothinkster/realworld)

<comment><USER14> This is wonderful. Great antidote to toy framework fatigue.

</comment></comment><comment><USER22> Minimalism has a cost. [http://npm.broofa.com/?q=zero](http://npm.broofa.com/?q=zero)

<comment><AUTHOR> Standing on the shoulders of giants :)

You will eventually be adding all those packages when you develop a production-grade React / Node app anyway.

<comment><USER22> Perhaps this should be done gradually and thoughtfully, rather than pulling half the internet into each minimalist app out there.

<comment><USER23> Welcome to the world of node.

<comment><USER3> This is nothing to do with node. This is poor programmer decision making. You can build great node apps with a real minimalist approach. Holding up projects which pull in half of npm as "the world of node" is like holding up a hot and ready 5$ pizza and saying all Italian food is bad.

<comment><USER13> I think the point is that this is almost encouraged in the node ecosystem, while in most other language ecosystems I know of it wouldn't be.

<comment><USER3> Encouraged by who? I see the same people which used to install jQuery or WordPress plugins and were able to get janky but working sites. But prolific module authors and node core contributors don't promote these approaches.

Maybe if you listen too much to twitter "thought leaders" you might get this impression, but we are all aware of the problems with social media platforms...

<comment><USER13> Well, considering the amount of dependencies in popular projects like CRA that was highlighted here a few days ago I don't think it's unreasonable to extrapolate to the general ecosystem. Of course there are module authors and devs doing it differently, but in general most node projects I see are more dependency-happy than projects I see in other languages.

<comment><USER3> Give people a useful tool (npm) and they will muck it up. This is both the best and worst part of the general node ecosystem. The issue is people saying things like "that's just node". It is not node, it is the ease of use and popularity meaning there will be more of these examples. If you care to make high quality use of the platform and tools you can, but that means not following the crowd.

<comment><USER13> Agreed, but for whatever reason it seems more prevalent in the node ecosystem than in others (even when comparing high-profile projects).

</comment></comment></comment></comment></comment></comment></comment></comment></comment></comment><comment><USER3> Wow, I love that people can wrap express and many of its components and end with something so different from its foundation. That being said, this level of "batteries included" approach has a cost.

In this example, it is the complexity of this file[1] and the fact that if you were to write this as a single express middleware you could probably write it in less than 20 lines.

Guess this is just not my cup of tea?

[1] [https://github.com/remoteinterview/zero/blob/master/packages...](https://github.com/remoteinterview/zero/blob/master/packages/core/lib/router/index.js)

Edit: also looks like the author decided to wrap their own multi process model? [https://github.com/remoteinterview/zero/blob/master/packages...](https://github.com/remoteinterview/zero/blob/master/packages/core/lib/router/index.js#L140-L182)

<comment><USER23> Yes, writting an express backend is really simple, some plugins, error- handling etc. and you can run it in less than 1 hour.

But the Frontend with webpack needs definitely more time, hours and hours to fiddle webpack to your needs. This project has a definded strucutre and support defined modules (react), so it could save you a lot of webpack config time, but you can not do everything with it. You have to use it as it is.

<comment><USER3> Lol, if the setup on the FE takes hours to fiddle something is wrong with the choice of tooling. I don't use webpack, so I guess I am just spoiled?

<comment><AUTHOR> The alternative is using parcel. Zero is a server equivalent to Parcel (and uses parcel internally)

</comment></comment></comment></comment><comment><USER6> People in this thread are way overly negative. I understand this tool as something to be used for prototyping and locally-only but everyone is jumping on how insecure it is or how it's got a bunch of dependencies, or it's just express, etc. None of that matters if you aren't exposing this to the internet. This is a really neat project that lets you play with something right away and a lot of you all are bashing the author for things not even in the scope of the project.

Lastly this has so many upvotes and is #1 on the front page because it's cool, fun, and perfect for a little prototype or POC. There are a number of positive comments buried at the bottom but the highest comment is about how this is a "Security Nightmare".

Edit: Typo and I wanted to add: Not everything posted on HN has to be battle- tested, scalable, parallelizable, profitable, cloud-ready, secure, etc. It's the kind of attitude in this thread that keeps people from posting their own work at all. No one want's to get torn apart, back off and provide constructive criticism or keep quiet. (Note: advice I have not always practiced in the past)

Edit 2: Show HN rules ([https://news.ycombinator.com/showhn.html](https://news.ycombinator.com/showhn.html)), I think this makes my point better than I can.

Show HN

> Show HN is a way to share something that you've made on Hacker News. The > current Show HNs can be found via show in the top bar, and the newest are > here. To post one, simply submit a story whose title begins with "Show HN".

What to Submit

> Show HN is for something you've made that other people can play with. HN > users can try it out, give you feedback, and ask questions in the thread.

> A Show HN needn't be complicated or look slick. The community is comfortable > with work that's at an early stage.

> If your work isn't ready for people to try out yet, please don't do a Show > HN. Once it's ready, come back and do it then.

> Blog posts, sign-up pages, and fundraisers can't be tried out, so they can't > be Show HNs.

> New features and upgrades ("Foo 1.3.1 is out") generally aren't substantive > enough to be Show HNs. A major overhaul is probably ok.

In Comments

> Be respectful. Anyone sharing work is making a contribution, however modest.

> Ask questions out of curiosity. Don't cross-examine.

> Instead of "you're doing it wrong", suggest alternatives. When someone is > learning, help them learn more.

> When something isn't good, you needn't pretend that it is. But don't be > gratuitously negative.

<comment><USER24> I agree with you about the over-negativity, but I have to disagree about the value of the "security nightmare" comments. Nowhere on the marketing page (that I saw) does it say, "prototype/development use only!" In fact I got the opposite impression. It seems to want to be a new framework. It's critically important to surface security issues early and often.

There's already a cultural anti-pattern in the js world of just `npm install`ing stuff and shipping to prod without auditing well (I've heard a number of times, "well it has like 60 stars on github").

If the project marketed itself as a "development only" or non-production framework then I'd agree with you 100%. However as it stands it's dangerous and could lead to extreme compromise of a system if it gets deployed to a production environment.

That said security-minded people are often inconsiderate and horribly untactful in their approach. That needs to change. You don't need to be overly negative to point out a security issue. Something like, "Cool start, but might want to point out that it's not meant for production!" would be a lot better IMHO.

<comment><USER6> > That said security-minded people are often inconsiderate and horribly > untactful in their approach. That needs to change. You don't need to be > overly negative to point out a security issue. Something like, "Cool start, > but might want to point out that it's not meant for production!" would be a > lot better IMHO.

Agreed, and I also agree that maybe it should have a tagline about "not production ready" or even "never production ready". Not sure what the end goals of Zero are. I will say I thought it was pretty evident that this was not for production (if only to the sheer amount of "magic" inside) but maybe that's just me and it should have a disclaimer to that effect.

<comment><USER22> Maybe security people are getting tired of inconsiderate developers that keep shipping bazillions of insecure packages all over mission critical applications.

Devs need to change their culture. This behavior is actively harming end-users through repeated data breaches.

<comment><USER6> Do you honestly think it is developer's "inconsiderate" behavior that the root cause or even a main factor in the "repeated data breaches"?

<comment><USER22> Partly yes. They certainly have a professional responsibility to write applications that resist well known attacks, such as directory traversal, xss, sqli, etc.

This isn't new, and not knowing how to deal with it is like a builder not knowing how to safely stand up a wall.

</comment></comment></comment></comment></comment></comment><comment><USER25> My God, the people on this thread. There are people out there, working as software "engineers," who think that if they can't personally find a vuln in 5 seconds, the system must be secure. How is this #1 on the site right now?

<comment><AUTHOR> I thought that was 'banter' in your username.

</comment></comment><comment><USER26> That's pretty cool to quickly put together a POC app. There should be an "eject" command that would export everything to a "real" Node application, with package.json and so on, so that the POC can be converted to a real app easily.

<comment><USER27> Check out Reframe: [https://github.com/reframejs/reframe](https://github.com/reframejs/reframe)

It's a web framework like Zero Server and Next.js but everything is ejectable.

<comment><USER28> Or alternatively, check out re-frame: [https://github.com/Day8/re- frame](https://github.com/Day8/re-frame)

It's a web framework with a well-thought-out architecture that you don't need to "eject" from.

</comment></comment></comment><comment><USER29> As others have said before, I think this is amazing for small one offs and maybe for beginning programmers. I'm afraid that, like all frameworks, people will start to misuse it eventually. Someone will make a little app with that, because it's so fast, simple and amazing, right? Later, however, the app will grow and it will become a maintainability nightmare. The only good thing about it is that you can easily get out of this framework and migrate to managing express/node/react yourself, or so it seems. It isn't like rails, where if you get into it, your app is so highly coupled to it that any escaping is impossible, even if your app becomes very complex.

<comment><AUTHOR> Escaping and writing a custom node+express+React SSR server for a zero-based app should be easy. But zero isn't a 'platform' anyway. It's just an abstraction on common config and some glue code, all open-source so you can easily fork and improve.

</comment></comment><comment><USER30> Who is this for? Is the goal to enable people who don't know what they're doing at all to make applications?

Maybe at a glance that is a laudable goal, but surely there is a point where, if you need so much handholding, you should consider either sitting down and learning what you need or making someone else is build it for you.

Newbies? I guess that is possible, but I personally think that actually learning to use your tools and the libraries that are available should be the goal. Handing the control of everything to some 3rd party component is eventually going to leave the beginner with issues they have no way of solving because they've never had to learn anything.

<comment><USER31> There's a lot of value in removing all the plumbing you typically find at the start of node project to handle basic things like routing. I'm a big fan of moving all that "outside" the app

This might seem silly if all you're use to is working on some startup's big app with a dozen other people, but for small orgs that need to run small programs for a long time it's a mess to maintain that stuff over the long term and to count on lone coders in small engagements to get right.

> Handing the control of everything to some 3rd party component

In the cases I describe, this ^^ is a great idea. Keeps maintenance of the common stuff in a common place. Everyone freaked out in this thread about there being a way to get at files outside the project root. Well the author fixed that in one place and now it's fixed for everyone. How many times does an error like that come up and go undetected and uncorrected when even an experienced node coder has to copy pasta so much stock plumbing for the 1000th time to spin up a small service for a small org?

</comment></comment><comment><USER32> I think this is really nice for when I want to hack together a quick front-end for something. Once I have a working React/Node.js set up I can really quickly build something, but what usually stops me is the dozens of packages and things I need to wire together before I can actually start building something.

`create-react-app` is also pretty good, but this seems to do a bit more. I really like the simplicity of the set up and the fact that you can also just whip up an API call or something.

<comment><USER33> I find that the best thing about create-react-app is the eject feature.

It's an instant tutorial on how this damn mad hatter of an ecosystem works. They heavily commented the thing too !

Honestly, any lecture on react should have a part where people ejects and read the source code.

</comment></comment><comment><USER34> I am so confused why the 'good old days' of php is a good example of how to do application development.

Every php framework got away from that for really good mesure, including not having your logic in the server document root.

<comment><USER35>
      Every php framework got away from that for really good mesure, including not having your logic in the server document root.

IMHO unless you are building a http daemon, "your logic" should probably not include routing http requests. Using directory tree, url rewriting or generally leaving the controller part of your logic to the underlying httpd is probably fine in most php projects. Note: php frameworks can't do microservices

</comment></comment><comment><USER36> Why is this any different than say, next.js?

<comment><USER37> server is down (yay for proof of scalability ;)) so i can't tell for sure, but it looks like it's derived/based on next.js and comes from the same authors

<comment><USER37> server is up again and it wasn't the case.

the page and code styling misleaded me

</comment></comment></comment><comment><USER38> this is impressive! I would absolutely reach for this first when scraping something together quickly. I'd be super interested in seeing numbers for just how far this can scale before falling over.

<comment><AUTHOR> Currently this is as scalable as a normal node+express app. The aim for now is to improve development experience for now.

<comment><USER38> Love it, that's what I figured, and I agree with the aim!

</comment></comment></comment><comment><USER39> Not to sound adversarial, but configuring a web framework tends to be one of the last difficult or time consuming parts of building a web app or backend in my experience.

<comment><USER27> If you need SPA then yea it's easy. But when you need SSR it becomes a whole different story.

Now imagine you want parts of your app to be SPA and some other parts of your app to be SSR. This becomes super complex. Frameworks like Reframe allow you to do that. (I'm Reframe's author ([https://github.com/reframejs/reframe](https://github.com/reframejs/reframe)).)

Admittedly, mixing SPA and SSR views in one app is uncommon today but that's because people are not aware that they can do that. This will change.

</comment></comment><comment><USER40> Looking through the code on github found a .py file handler in the works: [https://github.com/remoteinterview/zero/blob/master/packages...](https://github.com/remoteinterview/zero/blob/master/packages/handler- python/handler.js)

Any idea of a timeline on this feature? I think it could be really awesome to be able to prototype with python in addition to js.

<comment><AUTHOR> The js part (React, MDX, Node) is almost complete. I will put out a basic handler for python ASAP if that's going to be useful to you :)

<comment><USER27> Reframe author here ([https://github.com/reframejs/reframe](https://github.com/reframejs/reframe)).

This is super interesting, what are you plans regarding this? Super curious.

</comment></comment></comment><comment><USER41> Supports the new hotness MDX. JSX/React components _inside_ markdown. This is awesome for standing something up quickly. Thanks for creating this!

</comment><comment><USER42> This is very cool framework and I will certainly use it for small to medium sized apps or website. However, just going through the doc there doesn't seems to be a way to split components since any file is assumed to be a page. Any way around that?

Lastly, it's a shame that the doc link points to github. The doc, as layed out in github is a perfect use case for zero.

<comment><USER43> It seems to me that you should have a folder (www?) that is served by zero, and a folder (lib?) that isn't. Then files in the www folder can import from the lib folder.

</comment></comment><comment><USER44> Is there any way to "ignore" specific files or directories? For example, I want to reuse React components across different routes (exposed as jsx files). However, I don't want `mysite.com/components/Container` to be a valid endpoint.

<comment><AUTHOR> Yes. It's not written in docs yet but any file or folder starting with _ (underscore) is not exposed publicly. This feature spec is still open for discussion as on how to tackle it the best.

<comment><USER44> Check my reply to this comment. The underscore idea was one of the first things to come to mind too, but I think having a specific file makes it clear to others who might not understand Zero internals.

<comment><AUTHOR> You are right. A .zeroignore file seems like a good idea.

<comment><USER45> Would that not count as a configuration file though?

<comment><USER46> You can still configure zero conf frameworks, it's just not explicitly required for it to function

</comment></comment></comment></comment></comment></comment><comment><USER47> For markdown based sites, why not statically generate the site? Why render it on each request?

<comment><AUTHOR> As markdown can be dynamic in this case. (see [https://mdxjs.com](https://mdxjs.com)). Static 'export' can be a good feature though.

</comment></comment><comment><USER48> The time example reminds me of WSGI for Python. Neat that it supports templates too.

</comment><comment><USER29> > Zero reads credentials from environment variables. Zero also loads variables > from .env file in your project root, if it's present.

Security nightmare? Can I do myapp.com/.env and read the credentials from the wider internet?

<comment><USER49> Why would you assume that they have this bug? If you're actually curious if the bug exists go read the code or try it yourself.

<comment><USER50> Another common on this page documents this bug on their production website.

</comment></comment></comment><comment><USER51> Having Markdown rendered as HTML is basically all I want when I'm standing up a single web page or a small website. This is definitely something I'll bookmark for later.

<comment><USER52> Caddy also has native Markdown functionality, by the way. [https://caddyserver.com/docs/markdown](https://caddyserver.com/docs/markdown)

</comment></comment><comment><USER53> While I embrace less configuration, you can't really avoid TLS these days. There is always configuration, many of configurations. Some implicit, some explicit.

</comment><comment><USER54> Great job! Took 2 minutes to install and run.

</comment><comment><USER55> Maybe a silly question, but is there anything one needs to consider before deploying this to, let's say, Heroku?

<comment><USER56> As others have pointed out, make sure to mark files that are not supposed to be exposed to the client by prefixing them with a underscore, otherwise you'll have a bit of a security issue. Otherwise, you're good to go.

<comment><USER55> Ace! but in terms of running it, how would Heroku know how to, ie. if there's no `package.json`, there'll be no `npm run start` defined?

<comment><AUTHOR> This should help: [https://github.com/remoteinterview/zero#running-on- cloud](https://github.com/remoteinterview/zero#running-on-cloud)

</comment></comment></comment></comment><comment><USER57> I for one think this looks great! Keep up the good work and don't get discouraged!

<comment><USER58> I agree. Fun idea and keep up the good work!

</comment></comment><comment><USER59> So cycle repeats, PHP reborn?

</comment><comment><USER60> I thought we moved away from this sort of structure as an improvement?

</comment><comment><USER61> Are there any plans to make this support Typescript in the future? :)

<comment><AUTHOR> Yes. Should be easy! As we are not a typescript shop yet, we might need a hand with that. Otherwise, I will try to figure it out soon.

</comment></comment><comment><USER62> Nice work bro. Seems pretty solid. Congrats from fellow Karachian :)

</comment><comment><USER63> Apart from the security concerns this actually looks awesome.

</comment><comment><USER64> Weird how does it knows what certificate to get for https

<comment><AUTHOR> You probably need nginx in front of this.

</comment></comment><comment><USER65> Where have I seen this before... CGI scripts?

</comment><comment><USER66> How to override default routes, then ?

<comment><AUTHOR> Can you give me an example of a rewrite? Zero already does some rewrites: [https://github.com/remoteinterview/zero#route- rewrites](https://github.com/remoteinterview/zero#route-rewrites)

</comment></comment><comment><USER67> How's this different from Koa?

</comment><comment><USER68> So... 2019's PHP?

</comment><comment><USER69> At quick glance. Cool. Dig the idea, going to have to take a deep dive to see how things work later.

I still have to have a giggle at the similarities between what you produced and what is essentially a PHP/Dom/Apache setup.

The Async wait for initial props before what is essentially a template render just drove it home.

One key thing missing is an easy wrap around running tests. What would it take to add this?

<comment><AUTHOR> I started with PHP / Wordpress themes myself and the aim here to bring back the simplicity of web development. Def inspired by PHP/Apache setup.</comment></comment>