I'm building an Express REST API for a blog management dashboard. the Front-End will be Vue JS, where the user can log in, create websites, and add blog posts to specific sites that they've added. All of this will be stored in Mongo DB Atlas.
I've followed a basic guide on creating a restful api, with CRUD actions and linking it to Mongo DB.
It shows me how I can create models, import routes using middleware and perform GET and POST requests to interact with my database.
It provides a way of adding blog posts, each as an object to an array in Mongo DB. I now need to extend this to essentially group an array of objects (blog posts) and put them into a specific object, and still retain the CRUD actions for each.
Currently, I have my app.js
which essentially loads in sites and posts, this is as follows:
const express = require('express');
const app = express();
const mongoose = require('mongoose');
const slug = require('mongoose-slug-generator');
const bodyParser = require('body-parser');
const cors = require('cors');
require('dotenv/config');
mongoose.plugin(slug);
// middleware
app.use(cors());
app.use(bodyParser.json());
// routes
const postRoute = require('./routes/posts');
const siteRoute = require('./routes/sites');
app.use('/posts', postRoute);
app.use('/sites', siteRoute);
Each one of the routes, loads the CRUD actions for adding an individual blog post, and an individual site.
This is pretty straightforward, however, I'm struggling to understand how, and what I need to add in order to add a specific blog post to a specific collection object in the database.
My JS file which contains routes to add a blog post is:
const express = require('express');
const router = express.Router();
const Post = require('../models/Post');
// get all posts
router.get('/', async (req, res) => {
try {
const posts = await Post.find();
res.json(posts);
} catch(err) {
res.json({message: err})
}
});
// create blog post
router.post('/add', async (req, res) => {
const post = new Post({
title: req.body.title,
slug: req.body.slug,
author: req.body.author,
creation: req.body.creation,
body: req.body.body,
css: req.body.css,
enabled: req.body.enabled
})
try {
const savedPost = await post.save()
res.json(savedPost);
} catch(err) {
res.json({message: err})
}
});
// get specific post
router.get('/:post', async (req, res) => {
try {
const post = await Post.findById(req.params.postId)
res.json(post)
} catch(err) {
res.json({message: err})
}
});
// delete specific post
router.delete('/:post', async (req, res) => {
try {
const removePost = await Post.deleteOne({ _id: req.params.postId })
res.json(removePost)
} catch(err) {
res.json({message: err})
}
});
// delete specific post
router.patch('/:post', async (req, res) => {
try {
const updatedPost = await Post.updateOne({ _id: req.params.postId }, { $set: {
title: req.params.title
}})
res.json(updatedPost)
} catch(err) {
res.json({message: err})
}
});
module.exports = router;
And this works great, however, I need to be able to POST a specific blog post to a specific object, created by my sites model.
In the end, I'd like to end up with something like this:
[
{
"ID": "some unique ID",
"name": "Example Blog Site 01",
"enabled": true,
"blogs": [
{
"title": "My blog title",
"slug": "slug",
"description": "some blog content"
},
{
"title": "My blog title",
"slug": "slug",
"description": "some blog content"
}
]
},
{
"ID": "some unique ID",
"name": "Example Blog Site 02",
"enabled": true,
"blogs": [
{
"title": "My blog title",
"slug": "slug",
"description": "some blog content"
},
{
"title": "My blog title",
"slug": "slug",
"description": "some blog content"
}
]
}
]
The blogs array in each of the objects I'd like to be my sites.js
and, the parent objects to be my sites.js
route.
Essentially giving the user the ability to quickly create a set of blog posts for an endpoint, e.g:
- https://example.com/api/sites/my_site/posts - GET all
https://example.com/api/sites/my_site/posts/blog-post-01 - GET specific
- https://example.com/api/sites/my_site_02/posts/blog-post-01 - GET specific