In a nutshell
- Learning cloud technologies such as Docker, GCP, Kubernetes
- Developed CI/CD with Github Actions
- Learned more about Shell and UNIX
- Modernized a .NET REST API backend into a Go microservice and scaled it up for the cloud
Why are we doing this?
In short, .NET is having some performance issues in the cloud. Our manager wants to see if a backend written in Go would help alleviate some of these issues. There’s an API with a good amount of endpoints that we’re looking to rewrite in Go, and we’re meant to mimic the functionality so we can quickly plug in the old frontend into our work, maintaining backwards compatability.
We should use Go and reevaluate if .NET is the right choice for this service, looking at metrics such as memory, cpu, etc. What would it take with a small number of people (interns) if we took a portion of it in Go and checked from a performance perspective if it meets the criteria? It’s in .NET simply because they took a non multi-tenant, not cloud sale project and scaled it up for large-scale deployments.
Thoughts on work
During the first week we simply had orientation for 2-3 days then set up the laptops. We also had some mandatory corporate trainings. I noticed that we had a lot less trainings than the previous internships I worked, possibly because manufacturing has a lot of safety requirements. For some reason cartoon animations/videos have showed up in all my orientations, so I wonder if alternative methods of teaching such as reading papers or articles would make it more effective. I’ve reading Working Backwards where they describe Amazon’s method of deep thinking in meetings, not just surface-level Powerpoints.
There is this event on Thursday where they get the upper management outside to hang out with employees, kind of like an after work happy hour. We got a picture with the CEO, but I wouldn’t be surprised if it’s lonely at the top.
APIs, Documentation
For creating our project’s documentation I did a lot of research into REST API specs. You can kind of think of the API as translating business logic into models/structures, which get transmitted into documents in our MongoDB database. Thinking about how to design an API from the ground-up, creating the JSON and structures that represent your business logic, is something I look forward to. Query, path, and body parameters all contribute to the design.
REST APIs nowadays fall under OpenAPI 3.0, formerly known as Swagger. There’s also tooling around each language which may or may not be updated—in particular, we used Go Swagger to generate a YAML specifying our API routes and then used ReDoc to host the design. There isn’t quite a commercial application that produces things on the highest tier of documentation such a Stripe’s, but Postman Collections provide a decent way to publish APIs since we use it so much for testing. The organization that made ReDoc made a commercial API service too, though I’m not totally sold on it considering what’s available using open source tools. The Swagger documentation generated it using Go annotations, but we didn’t have automatic formatting support so they got a bit messy. I suppose generating it from the code itself is a great option, but I didn’t find any custom solutions like that out there. I don’t think manually writing the API documentation is a great idea; it decouples the underlying functionality from the docs too much.
When considering creating documentation it’s important to look at the available tooling out there and what gets one closest to clear, concise, and good looking docs. I like Gitbook for non-API docs, Markdocs by Stripe seems promising, and I suppose OpenAPI generators are a decent solution for now. Specifically, we picked the Go framework fiber
over gin
because it had better documentation. Makes sense. Better docs = easier to build things and less time looking through source code.
Project Management
We had daily scrums in the morning where we described what we did the previous day. A trend I’ve seen in Computer Science is consistent work, as a coworker said this: internet companies have high hours because what is the moat against others? You have to put in a ton of time just to keep pace. The low cost of creating software applies also to your competitors. Compare this to a doctor I met, where she had just a few appointments one day and a lot of appointments the other day. In CS it might be hard to find some time just to relax.
One important thing in daily scrums is for people not to be competitive with each other: I felt an undercurrent to produce and describe what you had done each day, but I know this type of tension isn’t healthy for a team. How can a team focus on expanding the pie, rather than competing for limited work and impact when there isn’t necessarily an easily-splittable section of work such as frontend components.
Github Actions
Github Actions was easy to get started yet powerful in functionality. We used it for our code linting with SonarQube, checking to see if builds worked, autogenerating our docs, and pushing it to GCP’s artifact registry. Overall, it’s a straightforward process configuring environment secrets and writing YAMLs, but edge cases will arise.
Here are two sources I liked a lot when learning it:
- https://www.edwardthomson.com/blog/github_actions_advent_calendar.html
- https://www.actionsbyexample.com/
Docker, Shell, UNIX, misc.
I’ve developed a good understanding of Docker during my time interning at NCR. This means writing Dockerfiles and building optimal image sizes using techniques such as binary compression, multi-stage builds, and alpine images. Naturally, I also picked up some shell scripting while working with Docker. What’s crazy to think about is that tools such as awk
and sed
are programming languages onto themselves, and are just a small component of POSIX commands. I’m beginning to realize how many fundamental things are based on Linux, UNIX, and so on. Some worthwhile leads I got during my internship are to look at NixOS and the Linux Filesystem Hierarchy (FHS).
Go, Kubernetes, GCP
I got the impression that Go is a great language to learn. It’s what Docker is written in and is used for cloud related things such as Kubernetes, which is becoming ubiquitous. The module and import system is a bit weird because it’s globally based rather than project based, unlike Node, so I could imagine the Go folder becoming bloated over time. Another weird thing is the interaction of GOMODULE111
, go get
, and go install
. It’s a bit like Git where it seems like multiple commands do the same thing, so it’ll take me a while to understanding all the edge cases of using Go.
A teammate worked more on the Kubernetes and GCP, but my understanding is that they’re mostly YAML based configurations. GCP has some difficulties with setting up enterprise specific things such as the DNS and URL, while Kubernetes just has a lot of tooling around it. Both have tons of features that would take a single person a long time to learn.
Random thoughts
- Capitalizations, as Go structs require caps to be seen in other packages, MongoDB turns it into negatives, and edge cases where “Cart ID” may be
cartID
orcartId
, causing issues with the frontend JSON payloads. - REST APIs follow a common structure, and it’s much easier for me to read other companies’ REST APIs now that I’ve written my own
Postman is a great tool for testingUpdate 2024: Postman and Insomnia have gotten enshittified.
, though limit team sizes to 3 if you’re using the free plan- Computer networking is something I’ll have to pay greater attention to—this is highlighted to me with GCP setup and certs
How would I build a project?
There’s a lot of complexity in cloud providers and Kubernetes. If I was designing a simple personal project, I’d focus more heavily on the frontend and use serverless functions through Vercel or Netlify. They’d abstract away the CD process and the complicated parts at a slightly higher price. I’d use my new understanding of Docker and Github Actions for code linting and other features when necessary.