This guide teaches how to build a simple Blog Article CRUD API using:
- Node.js โ runtime to run JavaScript on the server
- Express โ web framework for building APIs
- MongoDB โ NoSQL database
- Mongoose โ MongoDB ODM (object-document mapper)
๐ ๏ธ Step 1: Setup the Project
1. Create a folder and initialize npm:
mkdir blog-crud && cd blog-crud
npm init -y
2. Install required packages:
npm install express mongoose body-parser
-
express
: Web framework -
mongoose
: Connect and interact with MongoDB -
body-parser
: Parse incoming JSON request bodies
๐ Step 2: Project Structure
Organize your project files like this:
blog-crud/
โโโ models/
โ โโโ Article.js # Mongoose schema
โโโ routes/
โ โโโ articles.js # Route handlers
โโโ server.js # Main app entry
โโโ package.json
๐ Step 3: Create the Express Server (server.js
)
const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const articleRoutes = require('./routes/articles');
const app = express();
// Middleware to parse JSON
app.use(bodyParser.json());
// Route prefix: All article routes will start with /api/articles
app.use('/api/articles', articleRoutes);
// Connect to MongoDB
mongoose.connect('mongodb://localhost:27017/blog_crud', {
useNewUrlParser: true,
useUnifiedTopology: true
}).then(() => console.log('โ
MongoDB Connected'))
.catch(err => console.error('โ DB Connection Error:', err));
// Start the server
app.listen(3000, () => console.log('๐ Server running at http://localhost:3000'));
Explanation:
- This is your main app file.
- It sets up Express, connects to MongoDB, and loads article routes.
๐ฆ Step 4: Create the Article Schema (models/Article.js
)
const mongoose = require('mongoose');
const articleSchema = new mongoose.Schema({
title: String,
content: String,
author: String,
createdAt: {
type: Date,
default: Date.now
}
});
module.exports = mongoose.model('Article', articleSchema);
Explanation:
- Defines the structure of each Blog Article in the database.
- Includes fields like
title
,content
,author
, andcreatedAt
.
๐ Step 5: Create CRUD Routes (routes/articles.js
)
const express = require('express');
const router = express.Router();
const Article = require('../models/Article');
๐น 1. Create a new Article (POST /api/articles
)
router.post('/', async (req, res) => {
try {
const article = await Article.create(req.body);
res.status(201).json(article);
} catch (err) {
res.status(400).json({ error: err.message });
}
});
Accepts JSON
{ title, content, author }
and stores it in the database.
๐น 2. Read All Articles (GET /api/articles
)
router.get('/', async (req, res) => {
try {
const articles = await Article.find();
res.json(articles);
} catch (err) {
res.status(500).json({ error: err.message });
}
});
Returns all articles stored in the database.
๐น 3. Read a Single Article by ID (GET /api/articles/:id
)
router.get('/:id', async (req, res) => {
try {
const article = await Article.findById(req.params.id);
if (!article) return res.status(404).json({ message: 'Not found' });
res.json(article);
} catch (err) {
res.status(500).json({ error: err.message });
}
});
Fetches a specific article using its ID.
๐น 4. Update an Article (PUT /api/articles/:id
)
router.put('/:id', async (req, res) => {
try {
const updated = await Article.findByIdAndUpdate(
req.params.id,
req.body,
{ new: true } // return the updated document
);
if (!updated) return res.status(404).json({ message: 'Not found' });
res.json(updated);
} catch (err) {
res.status(400).json({ error: err.message });
}
});
Edits article details like title or content.
๐น 5. Delete an Article (DELETE /api/articles/:id
)
router.delete('/:id', async (req, res) => {
try {
const deleted = await Article.findByIdAndDelete(req.params.id);
if (!deleted) return res.status(404).json({ message: 'Not found' });
res.json({ message: 'โ
Article deleted' });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
Deletes the selected article from the database.
Finally routes/articles.js
const express = require('express');
const router = express.Router();
const Article = require('../models/Article');
// โ
Create an article
router.post('/', async (req, res) => {
try {
const article = await Article.create(req.body);
res.status(201).json(article);
} catch (err) {
res.status(400).json({ error: err.message });
}
});
// ๐ Get all articles
router.get('/', async (req, res) => {
try {
const articles = await Article.find();
res.json(articles);
} catch (err) {
res.status(500).json({ error: err.message });
}
});
// ๐ Get a single article by ID
router.get('/:id', async (req, res) => {
try {
const article = await Article.findById(req.params.id);
if (!article) return res.status(404).json({ message: 'Not found' });
res.json(article);
} catch (err) {
res.status(500).json({ error: err.message });
}
});
// โ๏ธ Update an article
router.put('/:id', async (req, res) => {
try {
const updated = await Article.findByIdAndUpdate(req.params.id, req.body, { new: true });
if (!updated) return res.status(404).json({ message: 'Not found' });
res.json(updated);
} catch (err) {
res.status(400).json({ error: err.message });
}
});
// โ Delete an article
router.delete('/:id', async (req, res) => {
try {
const deleted = await Article.findByIdAndDelete(req.params.id);
if (!deleted) return res.status(404).json({ message: 'Not found' });
res.json({ message: 'Article deleted' });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
module.exports = router;
๐งช Step 6: Testing the API
Use tools like Postman, Insomnia, or curl:
- Create:
curl -X POST http://localhost:3000/api/articles \
-H "Content-Type: application/json" \
-d '{"title": "My First Blog", "content": "Hello world!", "author": "Xavier"}'
- Read All:
curl http://localhost:3000/api/articles
- Read One:
curl http://localhost:3000/api/articles/<article_id>
- Update:
curl -X PUT http://localhost:3000/api/articles/<article_id> \
-H "Content-Type: application/json" \
-d '{"title": "Updated Title"}'
- Delete:
curl -X DELETE http://localhost:3000/api/articles/<article_id>
โ Final Notes
- Make sure MongoDB is running locally (
mongodb://localhost:27017
) - Keep practicing with different data
- You can later connect this API to a front-end using React or Vue
- Keep exploring how to implement validation. https://dev.to/ncutixavier/add-joi-validation-middleware-cda
Top comments (0)