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 });
}
};
JavaScriptauthRoutes.js
const express = require('express');
const router = express.Router();
const { getToken } = require('./authController');
// Endpoint to get token
router.get('/token', getToken);
module.exports = router;
JavaScriptgetToken.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;
JavaScriptMessages 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 });
}
};
JavaScriptmessageRoutes.js
const express = require('express');
const router = express.Router();
const { getMessageSummaries } = require('./messageController');
// Endpoint to get message summaries
router.get('/', getMessageSummaries);
module.exports = router;
JavaScriptThe 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!