6 Best practices to avoid common backend mistakes

Software development is complex and thus mistakes happen all the time. It’s something that shouldn’t bother you too much since it has happened to every backend developer.

The fact is that most times, the reason for these mistakes is pressure which leads to human error. Deadlines, feedback anxiety, skipping testing, and rushing things are the four horsemen of backend mistakes. The trick is find your way around it not to ignore it.

“One who makes no mistakes makes nothing at all.” – Giacomo Casanova

We have listed down the best practices so you don’t have to cut corners at the backend of your project.

1. Don’t push the code without getting reviewed

People discussing something behind a glass wall

Pushing your code alone?

It’s always better to get your code reviewed with either a frontend developer from the same project or a backend developer from another project. As the former has domain knowledge while the latter has backend knowledge.

And if you are working with a team, then dont push code to the default branch without the code author or other backend developer reviewing it line by line. As it might create a conflict for others working on the project as they wont be able to merge their code. This leads to vulnerabilities and difficulty in maintaining the code.

Thus it becomes crucial to create a pull request which is a simple and effective way to get your code reviewed. This allows the rest of the developers to discuss changes in a branch and agree to merge them once everyone approves.

Also ensure analyzing the code by a tool like TSLint for TypeScript or ESLint for JavaScript, before pushing it to the default branch too. As these tools ensure consistent code style, and are useful when working in teams so you don’t have to disagree on topics like tabs vs spaces.

2. Avoid using too many technologies for same thing

Books beside a cactus pot

The availability of MERN/MEAN/LAMP stack models as ready solutions for medium and large project development saves so much time. As using one language (JavaScript) for both client-side and server-side development improves teamwork, simplifies collaboration, and speeds up development.

To eliminate the risk of bugs/vulnerabilities due to a higher number of dependencies and slower installation as more dependencies have to be installed, it’s best you use the same technology and the same pattern to resolve a given problem.

If you are talking about complex projects or about the projects with special requirements for security and performance such as public sector, banks, etc., then in such cases, it becomes necessary to build an individual technology stack which makes it possible to satisfy all the set requirements.

3. Test at each level with a bug fix

Door with 404 sign on the wall

Didn’t we already fix that?

It’s a question that you or your teammate often get after the product manager posts a snapshot of the bug.

The very other moment you are retracing the time you fixed that bug in the commits, but what’s the point?

You are already in the production code that is difficult to maintain as you are afraid to break anything, which increases the number of bugs. And to avoid such scenarios, writing all the tests at each level together with a new feature and regression tests together with a bug fix would help.

This ensures a higher work performance in both the long and short term, less bugs, and finally designing a better architecture.

4. Design the data model with whole team

Person drawing with a black marker on a glass

Here is an experience that nobody wants to go through – Fixing a poorly designed data model after an application is in production.

A badly designed data model can cause invalid production data, data being difficult to analyze or maintain, and very slow data queries.

It’s not only important to understand the database itself, but also how to create the right data model to fit your application’s scalability and performance requirements. If a bad data model isn’t deployed to production yet, you can just update the data model and remove the invalid data created at lower environments. Therefore, it’s better to take some time upfront to discuss with your team, and use a proven methodology.

You can break it down into five steps:

  • Understand your application workflow
  • Model the queries required by the application
  • Design the tables
  • Determine primary keys
  • Use the right data types effectively

And If a bad data model is already deployed to production, besides updating the data model, try writing a migration to fix the invalid data.

5. Monitor each production microservices

Person tying thread on pins fixed on a board

When a microservice is down, it’s likely some backend development work that needs fixing. As backend developers have to implement a status endpoint for each microservice.

Without monitoring all the microservices you might risk major bugs due to the most microservice being down.

Whereas, when you’re gradually breaking down a monolithic app to microservices or building a new system from scratch, you now have more services to monitor. Each of these will likely:

  • Use different technologies and/or languages
  • Live on a different machine and/or container
  • Have its own version control

With this, the system becomes highly fragmented and a stronger need arises for centralized monitoring as well. You’ll need to add trace information to each service, and need a tool that can monitor multiple services side by side. So you can understand how they interact with each other, and prevent bugs by figuring out which microservice is down, beforehand.

6. Avoid over-engineering and over-optimization

Person opening rotary lock

Over-engineering is like overthinking.

You’re trying to find solutions to problems that either are too early to tackle or don’t exist yet. In the end, you are left with very long functions/methods, poor commit message naming, and too much logic.

This also often means ugly code, quick hacks, abandoning programming principles like DRY, SOLID and TDD, and little to no abstraction.

It all boils down to two common reasons:

  • The What-if mentality
  • The Just-in-Case mentality

And unless absolutely imperative, this will create needless complexity, costing you significantly more than the final value delivered.

Well, it goes back to the You Ain’t Gonna Need It, syndrome. You need to constantly ask yourself if the way you’re currently writing code solves the immediate problem or program requirement OR if you’re writing it in a way to future proof it and make it more resilient to change.

Getting the right balance so that code is easy to understand AND easy to change, can be extremely challenging. It takes a lot of fine-tuning and experimentation. Implementing these best practices have always helped keep common mistakes at bay, might just do the same for you too.

For Backend related development or assistance, drop us a line.

Share

Stay up to date with latest happenings in our space