I always felt a bit anxious to write about my experiences. Well, I think I can deal with it now. It was an early morning in August when I decided to write a CLI tool just to "practice" Go as I had learned the basics a few days earlier. I do not watch many tutorials nowadays but I watched Nana's Video on Golang and it was pretty awesome. So, let's jump right in.
The reason
I wanted to experiment with Go to learn the os
module. The first thought that came to my mind was to create a turborepo with Golang as a server. Yes, I know that we cannot host it in Vercel, but the idea was to create a fast and secure server with Golang. We can use an API proxy in Vercel to rewrite the requests from the client side. However, you will be required to host your Go server separately in some places like Railway or Render. This doesn't follow the rule of a mono repo architecture, it is just maintaining all the code in a single place and building a strong server. It was named turbo-g (turbo + go).
Well, after creating a template project, I realized that Turbo has some issues with hot reload and many other things. So, eventually, I dropped the idea and moved on to create something else.
When creating this template project, I saw that I had to set up the server manually and I used gofiber as it has express-like functionalities, and as a MERN stack developer, I found it very easy to use. Once I thought to make a server-project generator in Express as well, but they already have one, it is called express-generator. Then I thought there might be the same thing for Fiber as well. But when I searched in GitHub with the topic:go-backend-template
, I only found pre-made templates that you can clone and use for your projects. That's when I decided to give it a shot.
The process
Making a CLI with go is fairly simple, as go codes are compiled into a binary executable. But, I didn't know how to create files and folders using the os module. In JavaScript(NodeJs), we can use the fs
module to manage files. All thanks to the docs for helping me out. I already knew what a basic backend project looks like in Express and Fiber as well. My approach was very simple. I will create a CLI tool that will use a few flags like --init
and --name
for the project name and it will generate a project and go.mod
with fiber as a dependency.
Then I got stuck in the thing called templates
. Templates are a skeleton of a go file. A template holds the content of the file. It was interesting to learn about templates. Then it was easy to take the project name from the flag and create all file folders using os.MkdirAll
and parse the templates with the text/template
module and get the content to create the files. All the details of these modules can be found in the Golang docs I mentioned above. Then it was done! 🎉 But..
dirs := []string{"cmd", "internal/handlers", "internal/middleware", "internal/models", "internal/routes", "internal/services", "config"}
for _, dir := range dirs {
if err := os.MkdirAll(filepath.Join(projectPath, dir), os.ModePerm); err != nil {
return fmt.Errorf("❗Failed to create directory %s: %w", dir, err)
}
}
The problems
I found out soon that I wasn't using
github.com/<username>/<repo>
as the module name which was a problem I encountered when I was learning about the go modules for the first time. Then I learned about the module path from here. So, what I did to solve the problem is very simple. I just added a-gh
flag for users to add their GitHub Username to crate the module assuming the project name is the GitHub repo.Another problem that still exists that is I did not provide any code in the middleware template file and the config template file. Users can use MongoDB or PostgreSQL as a database so it was unnecessary to provide any single or both configs in the template. Well, to fix this I created an issue and anyone reading this blog can contribute to solving this problem. I already figured out a way but this comes down to the third problem.
The CLI can take a user input called
-db
to get the user's choice of databases like MongoDB or PostgreSQL to make a dummy connection in the Config template. But, as the code grows to solve these kinds of problems, the CLI will be unusable. It already has 2 required flags and one optional which are--init
,-gh
, and-name
, and if we add a-db
flag it will be a very long command. To solve this problem I am going to modify the CLI as an interactive one likecreate-next-app
. After this change, we can add many options for customization. I am already working on this. So, if you want to contribute, you are welcome. You can find the issue here.The last problem for now is a hot reload module. Whenever we create a fiber app we don't have any change listener by default. If fiber has this already and I do not know about it then forgive me for that I am relatively new to this. If you know anything about this, let me know in the comments. To solve this problem I figured out to include
air
in the project.
The end
This is the story of Optical . However, the blog intends to let you guys know about the little project and also it is an invitation to contribute to the project if you want.
The journey has just started and it has been very interesting so far. I learned a lot of things and am willing to learn more ahead. This was my first blog here, so if I made any mistake or overlooked something, please ignore that and forgive me. it will be better next time.
Thanks, everyone for reading the blog, give a ⭐ to Optical if you find it interesting. Also, share if you know anyone willing to contribute. Also, if you find any issues or have any ideas for improvement, you can create an issue here
Thanks again.
Top comments (4)
Well documented man, I read this like I was in your shoes 😅.
Not a go developer, but rooting for you 🙌.
Thanks man. It was nice hearing from you. Thanks for the encouragement!
Damn, your blog doesn't read like AI generated. Seeing someone describe so much, even the minute detail interested me to read further. 🫡
Your experience now made me thinking about learning Go.
If you like to say anything to me personally, here is my X account