Blog Structuring Your Backend for Growth: A Guide to Organizing API Calls

Structuring Your Backend for Growth: A Guide to Organizing API Calls

In my previous blog, we took a leap into setting up our very first API calls for our secure message center with DataMotion’s APIs. But as we add more features and capabilities, things can quickly get tangled. Now that we’ve got our feet wet with our initial API calls, it’s time to restructure the backend to ensure scalability […]

Image of computer with IDE coding background

In my previous blog, we took a leap into setting up our very first API calls for our secure message center with DataMotion’s APIs. But as we add more features and capabilities, things can quickly get tangled. Now that we’ve got our feet wet with our initial API calls, it’s time to restructure the backend to ensure scalability using best practices.

DataMotion’s APIs offer a secure and compliant method for messaging, ideal for applications needing reliable data exchange.

Why Organize by Feature?

Using a feature-based backend organization:

  • Focus: All related tasks for a feature in one spot.
  • Modularity: Encapsulated features ensure clean separation.
  • Easy Expansion: Introduce new features with new directories.
  • Quick Debugging: Issues? Know exactly where to look.

Let’s get started!

Backend Directory Structure

Your project should follow a clean structure to ensure clarity. Here’s a suggested setup:

server/

│── authentication/
│    ├── authController.js
│    ├── authRoutes.js
│    └── getToken.js

│── messages/
│    ├── messageController.js
│    └── messageRoutes.js

│── .env       
│── server.js   
│── package.json
└── package-lock.json
Markdown


Let’s dive into each section.

Authentication Directory: authentication/

Authentication is crucial for our app’s security. This module ensures users are who they say they are and manages the tokens for DataMotion API interaction. Grouping all authentication tasks in one place streamlines any security enhancements or updates.

authController.js

const axios = require('axios');
const getTokenUtil = require('./getToken');

// Function to get a token from the DataMotion API
exports.getToken = async (req, res) => {
    try {
        const token = await getTokenUtil();
        res.json(token);
    } catch (error) {
        res.status(500).json({ message: "Error fetching token", error: error.response.data });
    }
};
JavaScript

authRoutes.js

const express = require('express');
const router = express.Router();

const { getToken } = require('./authController');

// Endpoint to get token
router.get('/token', getToken);

module.exports = router;
JavaScript

getToken.js

const axios = require('axios');

// Utility function to fetch the authentication token from the DataMotion API
const getTokenUtil = async () => {
    try {
        const response = await axios.post('https://api.datamotion.com/SMC/Messaging/v3/token', {
            grant_type: "client_credentials",
            client_id: process.env.CLIENT_ID,
            client_secret: process.env.CLIENT_SECRET
        });
        return response.data;
    } catch (error) {
        throw error;
    }
};

module.exports = getTokenUtil;
JavaScript

Messages Directory: messages/

Our app’s core function is handling secure messages. By clustering all related tasks in the messages/ directory, we streamline the addition of new messaging features and keep the focus on message operations.

messagesController.js

const axios = require('axios');
const getTokenUtil = require('../authentication/getToken');

// Function to get message summaries from the DataMotion API
exports.getMessageSummaries = async (req, res) => {
    try {
        const token = await getTokenUtil();
        const messagesResponse = await axios.get('https://api.datamotion.com/SMC/Messaging/v3/content/messages/?folderId=1&pageSize=10&pageNumber=1&sortDirection=DESC&metadata=true', {
            headers: {
                Authorization: `Bearer ${token.access_token}`
            }
        });
        res.json(messagesResponse.data);
    } catch (error) {
        res.status(500).json({ message: "Error fetching messages", error: error.response.data });
    }
};
JavaScript

messageRoutes.js

const express = require('express');
const router = express.Router();

const { getMessageSummaries } = require('./messageController');

// Endpoint to get message summaries
router.get('/', getMessageSummaries);

module.exports = router;
JavaScript

The Heart of It All: server.js

With our organized backend, let’s take a look at the updated server.js:

const express = require('express');
const cors = require('cors');
require('dotenv').config();

const authRoutes = require('./authentication/authRoutes');
const messageRoutes = require('./messages/messageRoutes');

const app = express();
const PORT = 5000;

// Middlewares
app.use(cors());
app.use(express.json()); 

// Route middlewares
app.use('/auth', authRoutes);
app.use('/messages', messageRoutes);

// Start the server
app.listen(PORT, () => {
    console.log(`Server is running on http://localhost:${PORT}`);
});
JavaScript


With a feature-based backend, you’re primed for smooth expansion and clear management. New features? Just slot in new modules.

Conclusion

By now, your message center’s backend should be neatly structured and ready for growth. In our next posts, we’ll add more features to our secure message center and watch our structured backend pay dividends. Stay tuned and happy coding!