There is a common trap that we fall into as developers, and it is believing that because some code “worked” that the code was written “correctly”. In reality, for most technical problems, a good developer can likely point out several different solutions. Any of those solutions might be perfectly reasonable, while none of them is the single “correct way”. Different solutions optimize for for different things You can only optimize for a few things at once, and there are always tradeoffs.
In this world, nothing can be said to be certain, except death, taxes, and migrations. Earlier in my career, I would come to a new project and inevitably a hectic migration would be underway. It’s not always a “stop the world” change, it can be as simple as switching from NPM to Yarn, but something is always changing. I used to naively believe my managers when they said cute things like “just this once” or “we’ll finally have our dependencies up to date.
A universally unique identifier (UUID) is a 128-bit format for creating IDs in code that has become popular in recent years, especially in relation to database keys. By using UUIDs, you ensure that your ID is not just unique in the context of a single database table or web application, but is truly unique in the universe. No other ID in existence should be the same as yours. It is important to note that while the probability that a UUID will collide with another is not zero, its practically zero.
“Dead Poet’s Society” is a classic film, and has become a recent favorite of mine. There’s a scene in particular that I enjoy, where Robin William’s character explains that it’s bad practice to use terms like “very tired” or “very sad”, instead we should use descriptive words like “exhausted” or “morose”! I wholeheartedly agree with what’s being taught to the students in this scene. It’s tiresome to read a novel where the author drones on within the bounds of a lackluster vocabulary.
I recently had a ticket opened on my team’s backlog board requesting the ability to bypass our API’s caching system. For context, our front-end team uses my team’s API to make fairly heavy requests to ElasticSearch, and one of the features of our API gateway is to cache the results of heavy aggregations for ~30 seconds. It turns out, every once in a while they need to run two of the same query within the ~30-second caching window and want an updated result set.
Too often I neglect the idea of UX design in backend work. The goal of user experience design is to give users a product that’s easy to use. In the world of front-end development, that typically means making it obvious how to navigate your site, using commonly-understood icons, or implementing well-contrasted colors for foreground and background, making your site easy to read. I’m here to contend that UX is extremely important in backend development as well, the difference is simply that our users are typically other developers, sometimes even internal employees, rather than users of the final product.
I’ve noticed that bugs introduced into an existing code base are often due to poor variable naming more than one might suspect. For example, a developer uses a rateLimit variable expecting it to be denominated in seconds while it really represents minutes, resulting in a 6x slower schedule. Another developer expects dbConnection to be an open database connection, but instead, it’s just the connection URI. Using descriptive, concise, and conventional variable names often set apart a senior from a junior developer.
Functional programming is a way to writing code where programs are created strictly through functions. Functional programming has gained quite a bit of traction in recent years among the development community, mostly because of the benefits it provides. Functional programming is a declarative way to write provably correct code. Function definitions are expressions that simply map inputs to outputs, rather than a sequence of statements that update the state of the application.
Clean code is like clean garbage - it’s only clean if it doesn’t exist. In other words, the only clean code is no code. Let’s start with an acknowledgment that a perfectly clean (empty) codebase is useless, that is, without code, we can’t provide value to our users. With that in mind, our pursuit of “clean code” will necessarily consist of tradeoffs. We’ll trade usefulness for cleanliness, complexity for speed, ownership for ease of development, and abstractions for reusability.
Unit tests are incredibly important to us as developers because they allow us to demonstrate the correctness of the code we’ve written. More importantly, unit tests allow us to make updates to our code base with confidence that we haven’t broken anything. However, in our zeal to achieve 100% code coverage, we often write tests for logic that we may not even want to test. I’m here to assert that creating mock database abstractions to write unit tests is almost always a bad idea.