You don't have access to this class

Keep learning! Join and start boosting your career

Aprovecha el precio especial y haz tu profesión a prueba de IA

Antes: $249

Currency
$209
Suscríbete

Termina en:

0 Días
12 Hrs
37 Min
18 Seg
Curso de Backend con ExpressJS

Curso de Backend con ExpressJS

Oscar Barajas Tavares

Oscar Barajas Tavares

Arquitectura

21/30
Resources

The structuring of backend applications is a fundamental element to guarantee the scalability and maintainability of our projects. When we start developing, it is common for all our code to be in a single file, but as the application grows, this practice becomes unsustainable. Learning to properly organize our code will allow us to work more efficiently, especially in collaborative environments where multiple developers interact with the same project.

Why is it important to properly structure a backend application?

When an application starts to grow, keeping all the code in a single file can generate several problems. If we analyze in detail, we will see that we have many lines of code that, although they work to learn and integrate functionalities, are not optimal for a real product or service.

To ensure important features such as:

  • Scalability: ability to grow without compromising performance.
  • Maintainability: ease of making changes and fixes
  • Collaboration: allowing several developers to work simultaneously.

It is necessary to separate our application into different components, each with a specific responsibility. This practice not only improves code organization, but also reduces conflicts when multiple developers work on the same project.

Creating a proper folder structure

The first step to properly structure our application is to create a folder called src (source), where we will incorporate the key elements:

project/├── src/│ ├── middlewares/│ ├── utils/│ ├── controllers/│ ├── services/│ ├── routes/│ ├── app.js│ └─── server.js├── prisma/├── node_modules/├── .env├── .gitignore├── package.json└─── package-lock.json

It is important to note that folders such as prism are not part of the source code of our application, but are resources that we use in development mode for migrations and other tasks. For this reason, we do not include them inside src.

How to separate the logic of our application into components?

To structure our application correctly, we are going to separate the logic into different files and folders according to their responsibility:

Separating the server from the application.

First, we create two main files:

  1. server.js: it will be exclusively responsible for raising the server and configuring the port.
const app = require('./app');constport = process.env.PORT || 3000;
app.listen(port, () => { console.log(`Serverrunning at http://localhost:${port}`);});
  1. app.js: will contain the Express configuration and the connection to the routes.
const express = require('express');const routes = require('./routes');
const app = express();
app.use(express.json());app.use('/api', routes);
app.get('/', (req, res) => { res.send('Hello World');});
module.exports = app;

Organizing the routes

Inside the routes folder, we create an index.js file that will serve as the entry point for all our routes:

const express = require('express');const router = express.Router();const authRoutes = require('./auth');
router.use('/auth', authRoutes);
module.exports = router;

Next, we create specific files for each group of routes. For example, for authentication:

const express = require('express');const router = express.Router();const { register, login } = require('../controllers/authController');const authenticateToken = require('../middlewares/auth');
router.post('/register', register);router.post('/login', login);router.get('/protected', authenticateToken, (req, res) => { res.json({ message: 'This is a protected route', user: req.user });});
module.exports = router;

What are the advantages of using controllers and services?

Separating logic into controllers and services is a best practice that offers multiple benefits:

Controllers

Controllers are responsible for:

  • Receiving HTTP requests
  • Validating the input data
  • Calling the corresponding services
  • Formatting and sending responses

Services

Services contain:

  • The business logic
  • Communication with the database
  • Complex operations
  • Application-specific rules

This separation allows:

  • Greater clarity: each component has a specific responsibility
  • Ease of testing: we can test each component in isolation
  • Reusability of code: services can be used by different controllers
  • Simplified maintenance: changes in business logic do not affect the API interface.

By structuring our application in this way, we are following the single responsibility principle, where each component has a single reason to change.

Implementing controllers

In the controllers folder, we create specific files for each group of functionalities. For example, for authentication:

const authService = require('../services/authService');
const register = async (req, res) => { try { const user = await authService.createUser(req.body); res.status(201).json(user); } catch (error) { res.status(400).json({ error: error.message }); } } };
const login = async (req, res) => { try { const { token, user } = await authService.loginUser(req.body); res.json({ token, user }); } catch (error) { res.status(401).json({ error: error.message }); } } };
module.exports = { register, login};

Proper structuring of a backend application is a critical step in ensuring its long-term success. By separating our code into components with specific responsibilities, we not only improve organization, but also facilitate maintenance and collaboration between developers. Have you had experiences with poorly structured applications? What other organization patterns have you used in your projects? Share your experiences in the comments.

Contributions 0

Questions 0

Sort by:

Want to see more contributions, questions and answers from the community?