Golang Basics - How to get a flat project structure - Part 1

Mar 04, 2019 by - Category - Backend

There is a certain hype and surge in popularity of Go and as a result it’s attracting both seasoned programmers and freshers. I’ve got a chance to interact with both types (as in humans not data types etc). During these numerous interactions there are few questions which keep on popping up.

Though, the kind of lazy I am when it comes to writing. I decided to write a series to help people understand the basics which they tend to miss especially when trying to fast-forward through docs and books. I’ll start from simple project structure to directory based to mysql to mongodb/nosql’s to API’s to gRPC, webassembly etc etc.

This first post in the series is about creating a flat structure with introducing MySQL as a backend and having a single package. Our objective is to see how we can segregate and separate different functionalities into different files for simplicity and maintainability of code.

At the end of the post our project structure will look like this:


Flat Project Structure

We have divided our project into four files assuming that we will need a .go file to keep/maintain our database connection information.

Another file named config.go to keep/maintain other configurations like site url, some paths etc.

Assuming we need to segregate functions into a separate file or files we create functions.go and finally main.go to string all these files together. Just by looking at the image I’m sure you will feel that it looks quite better as compared to single file unless you are a lazy coder as once I was :).

Now, coming to the point where we make all this work. I won’t go into details of installing various packages and will straightaway come to the point and that too an important one. Always keep in mind that we have to start all files with `package main`. This is the secret sauce of keeping flat file structure and to include functions and variable in files. We cannot have different package names in each file and expecting the code to work. That’s not how Go works. This brings me to another important point — capitalization of first letter of variable of function which we need to call/include/inherit/use. I think a little code example will help here.

Lets change the db.go to

package main

import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
)
//function to create a connection to our database

func DbConn() (db *sql.DB) {
database := "mysql"
dbUser := "<db user name>"
dbPassword := "<database password>"
dbName := "<database name>"
db, err = sql.Open(database, dbUser+":"+dbPassword+"@/"+dbName)return db
}

and utilize this db connection in functions.go this way:

package main

import (
"fmt"
)
//notice the first capital letter of function name "Foo"

func Foo() {
db, err := DbConn()
if err != nil {
//handle error
}
fmt.Println(db)
}

And finally main.go

package main

func main(){
Foo()
}

And Run….I mean go run main.go or go build.

This is a very basic introduction to flat project structure and I know I have deliberately missed few things here and there as my whole point is to keep posts simple and clear, we will bring in complexities as we move forward…and in next part we will enhance the code further to include more robust error handling and functions that do a bit more.

Till then happy goinnnnggg.

PS – https://medium.com/@vineetdaniel/golang-basics-how-to-get-a-flat-project-structure-part-1-6ca7234c46d3

Leave a Reply

Your email address will not be published. Required fields are marked *

2 × three =