Get, Set, Golang: A week-long test in learning.
For the longest time, I’ve wanted to dive into Go. Be it exams or other engagements, I’ve always found excuses for my laziness and complacency. Fortunately, I stumbled upon motivation in an unexpected place. During my final year in college, companies visit our campus for tests to select potential candidates. While most rely on standardized tests in DSA and Computer Science fundamentals, occasionally, companies used programming assignments.
One such company arrived offering a staggering half-crore package. Despite its notorious stress-inducing work culture and odd work hours, the student fascination persisted. I applied and, luckily, I was one of eight students selected for the second round from a pool of around 350.
To qualify for interviews, we had to choose between a data analysis and visualization task or a web development task. My understanding of data analysis was rudimentary, whereas I had substantial experience in web development, making the choice obvious for me.
The task was far from easy.
We were tasked with creating a Jira-esque website for bug-tracking, issue-tracking, and monitoring, with a list of specified features:
- Secure user registration and authentication
- Account deactivation and deletion with a mechanism for data retention policies
- Role-based and Group-based management with custom roles
- Protection against vulnerabilities like SQL injection attacks
- Support for bulk upload using CSV for both users and tasks while ensuring accurate relationship preservation
- Frontend in Next.js or React.js using TailwindCSS or MaterialUI as the CSS Library. Go for the backend. PostgreSQL or MySQL for the database. Docker for containerizing the entire application, with an appropriate reverse-proxy.
We were given a week to complete this task while balancing college commitments. Note — I took a couple of days off, and a few more were on the weekend.
The Jump-Start
Numerous aspects in the requirements were new to me — Go, docker, reverse-proxies, and the permitted CSS libraries. So, I started by splitting the work into two parts: tasks I knew I could complete within a fixed timeframe and those entirely new without any estimate.
I postponed the frontend work towards the end, confident I could develop a working frontend in a couple of days. How challenging could it be to use a different CSS library?
I dove into work with a large to-do list resembling the cartoonishly massive bills seen in movies with spend-thrift associates.
Day 1
Time for foundational work. I aimed to develop the backend API endpoints and the SQL database simultaneously and then test them together. I had to outline the features to design the database.
I got to whiteboarding and came up with various task classifications: Projects, Tasks, and Issues. I also outlined how the user groups and teams would appear, involving special users like Admins, Maintainers, Assignees, Reporters, and more. Then, I created a basic MySQL database with required tables, matching the initial table to the final table at the project’s end by only about 40%!
Next was delving into Go. First, I had to determine the suitable Go backend library. With numerous options available, I turned to LinkedIn. I sought out Go experts and community members posting about Go. Luckily, I found highly proficient IT professionals blogging about Go on LinkedIn. I sent connection requests to six people, of which four accepted. I reached out to all four for guidance and received an array of responses. The majority suggested using the Go Fiber library for backend development. The next day, a couple of them even recommended other connections to message in case I encountered challenges and needed further help.
I installed Go on my system and familiarized myself with reverse-proxies. A couple of quick YouTube videos revealed how straightforward it was to implement, with Nginx being the easiest option.
Day 2
The first half of the day was spent researching Go Fiber full-stack projects on GitHub to understand their directory structures and divisions. I found a consistent pattern and replicated it in my project.
I aimed to plan a more detailed version with additional features, including priorities, team assignments, roles, and more. It consumed most of my day but resulted in a polished design that could then lead to straight forward implementation.
I then applied 3NF decomposition to the SQL tables and sketched out the schema. However, I felt this process made my life harder, necessitating numerous joins in my SQL queries. While it might be a best practice, it was definitely not worth the time lost in this case. Additionally, I installed Docker. With the Database ironed out, I crafted mock SQL statements for backend use, preparing for Day 3’s rapid API design.
Day 3
I sat down with my design details, started writing various APIs for functionalities I had outlined. I created models and routes, generated test data on SQL, and loaded it up. I configured SQL to ensure data persistence and security. I also performed Input Validation. Most of my day was spent testing this data. I also dedicated time to researching containerization and its implications. Realizing containerizing the entire application on the last day might pose difficulties in case of errors, I decided to start implementation on Day 4. This turned out to be my worst mistake. I should’ve saved it for the end.
Nightmare on WSL Street.
Day 4
By the end of Day 3, I had written and tested most of the APIs, and I was happy with the functionality. I aimed to transfer my backend and SQL server onto a container to ensure they functioned, avoiding potential last-minute project disasters. Consulting a few medium posts and reaching out to my new connections on LinkedIn, some advised delaying this until I completed the frontend. If it failed after completing the project, I’d need to troubleshoot among four moving parts (Nginx, frontend, backend, SQL). So, I proceeded to onboard my SQL and backend onto the Docker container.
Given my preference for working on WSL rather than Windows, I encountered Docker errors. Realizing it might be easier on Windows, I replicated my entire project there and reinstalled all the components. At first, my error was simple. The backend loaded before the MySQL server loaded. Therefore, it failed to establish a connection. I stack-overflowed a shell script and then I later found an easier fix that I implemented. However, MySQL started displaying bizarre “Database doesn’t exist” errors. It dawned on me that the issue was due to case sensitivity between Linux and Windows table storage formats. It took a while, but I eventually resolved these errors, spending the entire day fixing them. Finally, my database and backend were functional!
With limited time remaining in the day, I began documentation work.
Day 5
Now, I aimed to commence work on the frontend. I felt confident as I had prior experience with React.js and its more uptight relative, Angular. I named the project “Jeera” as an Indian take on Jira and designed an extremely minimal frontend website. I created a landing page, project and task pages, pages for adding users to teams, adding teams, and more. I also developed modals, relying mostly on Material UI elements with minimal CSS. I implemented JWT authentication due to the company’s security-oriented nature and used bcrypt to hash passwords. Additionally, I dedicated more time to documentation.
Day 6
I attempted to onboard the frontend and a dummy Nginx image onto Docker. Unfortunately, equipped with a mere 8GB of RAM, my laptop struggled, resulting in frequent crashes. Despite encountering numerous bugs while fixing them amidst crashes, I stay put. Ultimately, I managed to get everything working except the nginx reverse-proxy. Then, I ran it locally outside Docker for development purposes, finally being able to code without my computer crashing. I dedicated much of this day to frontend work, designing several additional pages and modals. I established protected routes on the backend, verifying auth through middleware. I also discovered ‘PapaParse,’ a library that could convert a given .CSV file into a parseable JSON object. Utilizing this, I made ’n’ API calls to insert data, effectively solving the bulk upload feature. No hiccups encountered here. I added more comments and further documented how to set up the project on a local system.
All these efforts were tracked on the organization’s GitHub. However, the provided new GitHub link is merely a copy and doesn’t offer the same versioning overview. Attempting to revert everything to the Docker container proved difficult due to strange port issues. I had to switch React’s native port to another.
Day 7
I started the day by refining documentation, ensuring a functional project version was available on the GitHub main branch without containerization. At this point, everything functioned except for containerization. Removing nginx surprisingly worked, albeit at a markedly sluggish pace. I realized I needed to focus on core concepts like Cross-Origin Resource Sharing and HTML Requests, as they caused significant delays in my delivery. I containerized an application version without Nginx, further refining the frontend and making substantial progress. Occasionally, a seemingly innocuous change caused a breaking bug, forcing me to revert. React’s cooperation was crucial, it’s a finicky library, not as stable as Angular. Fortunately, I managed to set up everything, packaging the entire system, including the reverse-proxy, into a single container. I added a writeIssues and writeTasks permission to allow users outside of groups to add to a particular issue or task. I meticulously added comments, ensured all details were correct, and submitted before the deadline.
End-result.
The company withdrew from our college, electing not to select anyone for the next round. It could be a sign of the times or indicative of our quality. Although not the desired ending, I’m immensely satisfied with my output. I learnt a lot, and if I were to repeat the process, I’d make better decisions. I thoroughly enjoyed the learning process, especially addressing numerous security features, an area I had never previously looked into. I firmly believe these aspects should be part of college curricula, mandatory for every student to implement in their projects. They’re integral to quality engineering. I did abysmally on the UI part but that was only because of lack of time, not lack of creativity. The best part was the tremendous support I received on LinkedIn. Please feel free to reach out for further discussion!