Backend News API

Project Overview
The Backend News API is a robust RESTful API built with Node.js, Express, and MongoDB that provides a comprehensive solution for managing news articles. This API supports full CRUD operations, user authentication, role-based access control, and advanced querying capabilities.
Developed as part of my coursework at Penn State University, this project demonstrates my proficiency in building secure, scalable, and well-structured backend systems that follow industry best practices.
Key Features
RESTful API Structure
Complete CRUD operations for news articles following RESTful principles.
Authentication & Authorization
Secure API endpoints with JWT tokens and role-based authorization.
Data Validation
Robust request validation ensuring data integrity and error prevention.
Error Handling
Comprehensive error handling with appropriate HTTP status codes and messages.
MongoDB Integration
Efficient database operations using Mongoose with proper schema design.
Pagination & Filtering
Advanced querying capabilities for retrieving subsets of data.
Technical Challenges & Solutions
Challenge: Secure Authentication
Implementing a secure authentication system with proper token handling and role-based access.
Solution: I built a robust JWT-based authentication system with middleware that verifies tokens, extracts user information, and performs role checks. The solution includes token expiration, refresh mechanisms, and protection against common vulnerabilities.
Challenge: Advanced Querying
Providing flexible API endpoints that support pagination, filtering, and sorting.
Solution: I implemented a dynamic query builder that processes request parameters to construct MongoDB queries. This allows clients to filter by multiple criteria, sort by any field, and paginate results efficiently.
Technologies Used
- Node.js for server runtime
- Express.js for API framework
- MongoDB for database
- Mongoose for ODM
- JWT for authentication
- Express Validator for data validation
API Metrics
Code Highlights
// Article controller methods for CRUD operations
const Article = require('../models/Article');
const { validationResult } = require('express-validator');
// Get all articles with pagination and filtering
exports.getAllArticles = async (req, res) => {
try {
const { page = 1, limit = 10, category, sortBy = 'createdAt', order = 'desc' } = req.query;
// Build filter object
const filter = {};
if (category) filter.category = category;
// Calculate pagination
const skip = (page - 1) * limit;
// Build sort object
const sort = {};
sort[sortBy] = order === 'desc' ? -1 : 1;
// Execute query with pagination
const articles = await Article.find(filter)
.sort(sort)
.skip(skip)
.limit(parseInt(limit))
.exec();
// Get total count for pagination info
const totalArticles = await Article.countDocuments(filter);
res.status(200).json({
success: true,
count: articles.length,
total: totalArticles,
totalPages: Math.ceil(totalArticles / limit),
currentPage: parseInt(page),
articles
});
} catch (error) {
res.status(500).json({
success: false,
message: 'Server error while retrieving articles',
error: error.message
});
}
};
// Create a new article
exports.createArticle = async (req, res) => {
// Validate request
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({
success: false,
errors: errors.array()
});
}
try {
// Add user as author
req.body.author = req.user.id;
// Create new article
const article = new Article(req.body);
await article.save();
res.status(201).json({
success: true,
message: 'Article created successfully',
article
});
} catch (error) {
res.status(500).json({
success: false,
message: 'Server error while creating article',
error: error.message
});
}
};// Authentication middleware to protect routes
const jwt = require('jsonwebtoken');
const User = require('../models/User');
exports.protect = async (req, res, next) => {
let token;
// Check for token in headers
if (req.headers.authorization && req.headers.authorization.startsWith('Bearer')) {
// Extract token from Bearer header
token = req.headers.authorization.split(' ')[1];
}
// Check if token exists
if (!token) {
return res.status(401).json({
success: false,
message: 'Not authorized to access this route'
});
}
try {
// Verify token
const decoded = jwt.verify(token, process.env.JWT_SECRET);
// Get user from token
req.user = await User.findById(decoded.id).select('-password');
if (!req.user) {
return res.status(401).json({
success: false,
message: 'User not found'
});
}
next();
} catch (error) {
return res.status(401).json({
success: false,
message: 'Not authorized to access this route',
error: error.message
});
}
};API Testing Screenshots

API Save Endpoint
Successful POST request saving multiple news articles

Article Creation
Creating a new article with JSON payload

Get All Articles
Retrieving all articles with pagination support

Article Update
Updating article content via PATCH request

Article Deletion
Removing an article from the database

After Deletion
Verification that article has been removed from database
Lessons Learned
This project provided valuable insights into building robust backend systems:
- Designing and implementing secure authentication systems
- Creating scalable and maintainable API architectures
- Building effective data validation and error handling
- Working with MongoDB and Mongoose for efficient data operations
- Implementing role-based access control for API security
Relevance to Internship Goals
This project demonstrates skills that are directly applicable to backend and full-stack development internships:
- Building secure and scalable Node.js/Express.js APIs
- Implementing JWT authentication and authorization systems
- Working with MongoDB/Mongoose for database operations
- Creating comprehensive API documentation
- Developing custom middleware for error handling and request processing
- Testing and debugging API endpoints