DEV Community

Cover image for Your code architecture sucks if …
Kalkidan Tesfaye
Kalkidan Tesfaye

Posted on

Your code architecture sucks if …

These are mistakes I did before I learn to develop the right software architecture mindset and I usually see some of them in 90% of projects. Avoiding these mistakes and knowing the right approach when you structure your project can help you build high-performing, scalable, robust, and maintainable software.

1. Your controller is dependent on the database

Image description

I noticed this in a lot of codebases, the database logic and functions getting mixed with the controller business logic. If you change the database, the controller will fail to run. Controllers should be independent of the database. Instead of using the controller to access and manipulate data directly, it is best to add another layer that is responsible for providing functions to communicate with the database. Let’s say you have an API to register users, the method to store the data in mongo db, mysql or postgres might have a different name and implementation and if you directly call the ORM function in the controller, you are still making it dependent on the database or the ORM you use. Instead, you can add data or a model service that defines the create method or other database functions used by the controller. So the model will be responsible for providing functions for the controller. Depending on the language and framework you use you can either define the function on the model together with the data type and structure or you can create a separate data service.

2. You don’t have an automated independent module for development processes.

Image description

When building software, there are certain processes that seem to appear in every project. Things like database migration, data seeding, dependency management, clean up and management shouldn’t be mixed with your business logic and it is always best to create a development process module you can use on multiple projects. These can include developing a dashboard to automate creating test data, migrating a table, or doing necessary crud operations instead of manually executing a script on the database itself.

3. You don’t manage and tracklogs

Image description

An application can have different messages such as errors, warnings, information, user interaction data, etc. When the application gets bigger, data and error management can be overwhelming and you need to have a separate process for routing and storing log data. Storing information about where the bug source is, who sent the request, successful and failed requests and the time it took will help you to do analytics and improve your application

4. You don’t separately store, serve and deploy static files

Image description

Static files such as images, documents, or even your frontend code should be separately stored and deployed. You should never store images or documents uploaded by the user to your code base and also you shouldn’t manually store files together with your codebase. Instead, it is best to use cloud storage such as Amazon S3 or google cloud storage to store and manage files separately. Most backend technologies such as Node.js is not designed to serve static assets, if you use your node js server to serve your static files you will end up overwhelming the CPU. Thus it is suggested to use cloud storage together with a proxy CDN to serve your frontend application. This will make sure to deliver the content efficiently and make it quickly available to users. You can also optionally use Nginx to serve static files. Another important point is if your application is heavily dependent on files and assets you might consider using or creating an asset management dashboard.

5. You don’t have a separate configuration file

Image description

Configuration information such as port number, URL, paths, statuses, and API keys should be defined in an independent configuration file such as a .env file and injected into the runtime environment as environment variables and it shouldn’t be stored or mixed with your code. The benefit of keeping configuration settings separate from your application logic is that you can apply configuration settings according to the deployment path development, test, and production. Moreover, the .env file should be git ignored to not expose information about the application.

6. You don’t use a secret manager

Image description

Having a separate configuration file is important and helpful to write maintainable and robust applications but it is not enough to keep the app secure. Storing sensitive information such as passwords and API keys needs a bit different approach than storing insensitive data. Most cloud services provide a secret manager that lets you save and manage credentials. These add an additional layer of security and you can limit access to the credentials by specifying who can view and alter the credentials.

7. You mix background tasks with your main code logic

Image description

Background tasks are operations that can be done later and don’t need to be executed right away. Such kind of tasks are executed outside of the request-response cycle and don’t need the presence or interaction of the user for example sending a thank you email after the subscription or tracking a user activity that isn’t relevant to a user or that doesn’t need to be available to a user right away. First of all, you need to identify things that can run in the background in your application and you need to remove them from your main logic. Instead, you can create a queue of jobs that will later be executed separately from the user request. Some frameworks have an excellent implementation of it but the idea is you will have a table containing a list of jobs(tasks) containing information needed to perform the job such as user id, status whether it is in progress or it is done, name or type of the job, date, etc. Then you will have a command to retrieve from the job table and execute it in an orderly manner. These can be tedious to implement from scratch but there are plenty of libraries that are very easy to work with depending on the language you use. The right implementation of queue/job can significantly improve the performance and usability of your application by reducing the waiting time and latency.


A new course coming soon on creating an architectural mindset in node js. Join the 6.8k community on Facebook or follow up on linked in to get the advanced node js course I will release soon.

Top comments (0)