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
15 Hrs
44 Min
52 Seg
Curso de Backend con ExpressJS

Curso de Backend con ExpressJS

Oscar Barajas Tavares

Oscar Barajas Tavares

Admin controllers / services

24/30
Resources

Permission and role management is a fundamental component of modern web application development. In this content, we will explore how to implement an administration system for an appointment booking application, where only users with an administrator role can create blocks of time available for appointments. This structure not only improves the security of our application, but also establishes an organized and efficient workflow.

How to structure the administration logic in a booking API?

Before diving into the code, it is important to understand the business logic behind our application. Only an administrator can add blocks of time in which users can register their appointments. This restriction requires implementing a role-based access control structure.

To achieve this, we need to create:

  1. Administrator-specific paths
  2. Controllers that handle the requests
  3. Services that implement the business logic
  4. Role-based permission validations

Configuration of administrator routes

The first step is to set up routes that will only be accessible to administrators. We start by modifying our main routes file:

// routes/index.jsrouter.use('/admin', adminRoutes);
const adminRouter = require('./admin');

Next, we create a file specifically for admin routes:

// routes/admin.jsconst router = require('express').Router();const adminController = require('../controllers/adminController');
// Route to create time blocksrouter.post('/timeblocks', adminController.createTimeBlock);
// Route to list all reservationsrouter.get('/reservations', adminController.listReservations);
module.exports = router;

These routes define two main functionalities for administrators:

  • Create new blocks of time available for appointments.
  • View all reservations made by users

Implementation of the administration controller

The controller is responsible for receiving HTTP requests, validating user permissions and coordinating with the corresponding services:

// controllers/adminController.jsconst createTimeBlockService = require('../services/adminService').createTimeBlockService;const listReservationsService = require('../services/adminService').listReservationsService;
const createTimeBlock = async (req, res) => { // Check if user has admin role if (req.user.role !== 'admin') { return res.status(403).json({ error: 'Access Denied' }); }
 // Get data from request body const { startTime, endTime } = req.body;
 try { // Call service to create time block const newTimeBlock = await createTimeBlockService(startTime, endTime); res.status(201).json(newTimeBlock); } catch (error) { res.status(500).json({ error: 'Error creating time block' }); } } };
const listReservations = async (req, res) => { // Check if user has admin role if (req.user.role !== 'admin') { return res.status(403).json({ error: 'Access Denied' }); } }
 try { // Get all reservations const reservations = await listReservationsService(); res.json(reservations); } catch (error) { res.status(500).json({ error: 'Error getting reservations' }); } } };
module.exports = { createTimeBlock, listReservations};

Administrator permissions validation

A crucial aspect of our implementation is permission validation. Notice how in each controller function we check if the user has the administrator role:

if (req.user.role !== 'admin') { return res.status(403).json({ error: 'Access Denied' });}

This simple check ensures that only users with the appropriate role can access these functionalities. If a user without permissions tries to access, they will receive a 403 (Forbidden) error.

What information do we need to create time blocks?

To create a time block, we need two essential pieces of information:

  1. startTime: The start time of the block.
  2. endTime: The end time of the block.

This data is extracted from the body of the request:

const { startTime, endTime } = req.body;

Then, these values are passed to the corresponding service, which will take care of the business logic and the interaction with the database.

Service structure for business logic

Although the full implementation of the services is not shown in the code provided, it is important to understand that these will be responsible for:

  1. Validating the data received
  2. Interacting with the database (probably using Prisma, as mentioned)
  3. Handle any specific business logic
  4. Return the results to the controller

This separation of responsibilities follows the single responsibility principle and makes our code more maintainable and testable.

Why is the separation of responsibilities important?

The structure that we are implementing follows a common pattern in application development:

  • Routes: Define the entry points to our API
  • Controllers: Handle HTTP requests and coordinate with services.
  • Services: Implement the business logic and the interaction with the database.

This separation offers multiple benefits:

  1. Maintainability: Each component has a clear responsibility
  2. Testability: It is easier to write unit tests for isolated components.
  3. Scalability: We can modify or extend one component without affecting the others.
  4. Readability: The code is easier to understand and follow.

Implementing this structure may seem like more work initially, but in the long run it greatly facilitates the maintenance and evolution of the application.

Proper management of roles and permissions is essential to ensure the security and proper functioning of any application with different types of users. Have you implemented similar systems in your projects? Share your experience in the comments and tell us what strategies you have used to manage authorization in your applications.

Contributions 0

Questions 0

Sort by:

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