Skip to content

Routing

Jeffery Zhan edited this page May 17, 2022 · 3 revisions

In the frontend, routing is what allows us to display different components at specific URLs. Routing in this case is mainly implemented using the react-router package along with a few extra components to handle authentication for the routes.

In the backend, routing is what allows us to make requests at specific request URLs and allows us to access controller functions which in turn allow us to access the backend.

Frontend

App.jsx

Within App.jsx is where our routing is mainly handled. We have different types of route components, each for a different level of authentication, but the props for each are essentially the same.

<AdminProtectedRoute
    exact
    path="/usercrm"
    render={(props) => <CRM {...props} />}
/>

As for the specific route components themselves, there are three:

Route

Part of the aforementioned react-routing package, routes using this component are accessible to all users.

AuthProtectedRoute

This component first checks if the session has expired by comparing the timestamp at that moment to the expiry timestamp. Otherwise, it will then check for authentication from Redux and if not authenticated, the user will be redirected to the /login route.

Both clients and admins have access to the routes using this component as long as they are logged in.

AdminProtectedRoute

This component checks the role ID of the current user. If it doesn't match the proper admin or super admin role IDs, then access to the page is not provided.

Only logged-in admins and super admins have access to the routes using this component.

Backend

In the backend directory, navigate to ./app/routes/ which is where the backend routes are located. The routes are separated into different files here and the routes specific to each file are pretty self-explanatory based on the filename. For example, routes specific to admin users are most likely found in partner.routes.js.

Each file has its own controller and validation schema which can be seen at the top of each file. For example, the first 4 lines in partner.routes.js:

const partnerController = require('../controllers/partner.controller');
const validationSchema = require('../validators/partner.validation');
const validationErrorHandler = require('../middleware/validation-error-handler');
const { isSuperAdmin } = require('../auth/helpers');

The purposes of validationErrorHandler and isSuperAdmin are explained below.

As for each route itself, the structure will generally look something like this:

app.post(
    '/partners/create',
    isSuperAdmin,
    validationSchema.createPartnerSchema,
    validationErrorHandler,
    partnerController.create
);

Each route typically has its own schema within the aforementioned file-specific schema and its own method in the aforementioned file-specific controller. All routes use the validationErrorHandler to handle errors with validation - this is universal.

As well, optionally, it may be necessary to restrict access of a certain route to certain group(s) of users, which is where authentication helpers like isSuperAdmin come into play.