-
Notifications
You must be signed in to change notification settings - Fork 488
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use of global variable to store DB connection #15
Comments
Ok, I'll bite :) IMHO the use of global variables should indeed be discouraged. But in this case, I think a global database connection is a perfectly valid decision. Before I explain why perhaps some background on how I came to be here. I just discovered this awesome concept of "real world apps". I am on the lookout for a new frontend framework that doesn't make me crazy. Looks like elm fits the bill. And being a Go developer, I was pleased to see this repo. As it turns out, I use Gin as well. And all my Gin projects have a global DB connection. As with all software, there are tradeoffs. I think there are plenty of reasons documented that recommend against the use of global variables, articles that you have pointed out. And I have tried the middleware approach. I use a global database connection for these reasons;
During the init phase of my apps is when I connect to the database. The global has been declared already, and during init, I connect. Incidentally, this is also where I define all of my routes. And therefore, I defer the close of the database as the first line in I also favour deployment to serverless cloud platforms, in Docker containers if I can. Some serverless implementations recommend connecting to a database within your http handler. Which can result in poor scaling (too many database connections at once) So connecting in
So you might be able to avoid having to pass your database connection into your handlers by using middleware or some other approach, but what about functions that those handlers may call? Again, a single, global variable is easier. The most common argument I hear about the use of global variables is that in a large codebase they make things messy, complicated, and potentially dangerous. I agree with this view. But let's remember, you don't go "modifying" the content of this variable. So it could also be considered a constant. So I don't see any risk of it being blatted. And in my 20 years of software, that has never occurred. And in the microservice world, apps are just not that big anymore.
Globals go out of scope in other packages. But I keep my API/Service code in I like a global database connection/handle. It's simple to set up and use, works, and very readable. In my view, this is what I strive for in all the code I write. While we are on the topic of global variables in a web API / microservice, I also have a global logger. At the end of the day, I can talk to the database, and log messages anywhere in my code, and so far, nothing bad has ever happened. |
Hello @camstuart, thank you for the exhaustive answer. Thinking about this awesome concept of "real world apps"... You've got a point with that life is not that simple to make reusable feature "packages". IMHO, it might be easier to implement it as configurable reusable microservice with API contract (and maybe client library / package to implement connectors). In the end, in modern development, things tend to get away from monoliths connecting to multiple databases. With YAGNI principle, it is valid point to think about database as a constant for whole application / microservice. What about testing? Do you do automated tests? If so, how do you deal with having DB connection as global variable? I'm coming from Java world, and DI helps to create temporary and isolated unit/integration test environment, which is completely isolated from others test. I'm not quite sure, how to accomplish isolation of individual tests, when there's a global variable holding database connection. |
Global variables are bad behavior, but global utils/middlewares are not bad which could help us reduce code repeating. A better practice might write some utils in global, then managing the database connections in a very small & obvious scope. For example, initializing a database connection might slow, we just initialize once in one place. Or we don't want too much clients connect to the database at the sametime, we write a manager to do the job. Those codes could be share to all apps in your project.
This idea sounds like 'Functional programming', it was good practice in most scenes(easy to write ut, not need to worry break down other function behavior, no state inside function, one input will always have one certainly output), but some time it will lose some flexibility(consensus logic/info might repeated everywhere). Depends on your tradeoffs.. For this small project, I just want to offer a comfortable way to write curd logic for newcomers. A important requirement is that a newcomer should easliy find a place to insert own code, putting similar codes together & making main workflow simple will make it more easier to read. :) |
Hit the nail! Offering a bigger context in main workflow will bring convenient for most time in real world. @kravemir |
I'm currently learning go, and I was looking for material about structuring go applications and found this repository. However, it uses global variable to store connection to DB, which I subjectively don't like. So, I was searching this topic on internet,...
I've found article https://peter.bourgon.org/blog/2017/06/09/theory-of-modern-go.html, which is also is against use of globals, because:
I've found it via reddit discussion https://www.reddit.com/r/golang/comments/9i7ipd/passing_through_layers_vs_global_variables/, where are another examples how to structure application without using global variables.
So, my questions are:
I'm asking this, as I want to learn. I'm biased against global variables in all programming languages (except few special cases for low-level system access). However, I might be persuaded to use global variables in go, if it's strongly encouraged as the "right way" to do things.
PS: thank you for taking your time and sharing the example as public git repo.
The text was updated successfully, but these errors were encountered: