Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 111 additions & 0 deletions apps/api/src/controllers/posts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import Post from '../models/post';
import Comment from '../models/comment';

// GET /posts Return an array of all the posts with status code 200
const getPosts = async (req, res, next) => {
try {
const posts = await Post.find();
res.status(200).json(posts);
} catch (error) {
//handling error middleware - errorHandler
next(error);
}
};

// POST /posts Create a new post and return the created post with status code 201
const createPosts = async (req, res, next) => {
// Retrieve the values from the request body
try {
const post = await Post.create(req.body);
res.status(201).json(post);
} catch (error) {
next(error);
}
};

// GET /posts/:id Return a post by id with category object and each comment object in the array with status code 200
const getPostById = async (req, res, next) => {
const { id } = req.params;
try {
const post = await Post.findById(id).populate('comments').populate('category');

return res.status(200).json(post);
} catch (error) {
//handling error middleware - errorHandler
next(error);
}
};

//GET /posts/category/:category Return an array of all the posts by category with status code 200
const getPostsByCategory = async (req, res, next) => {
const { category } = req.params;
try {
const posts = (await Post.findOne({ category })) ?? [];

res.status(200).json(posts);
} catch (error) {
//handling error middleware - errorHandler
next(error);
}
};

// POST /posts/:id/comments Create a comment inside the post and return the comment with status code 201
const createPostComment = async (req, res, next) => {
const { id } = req.params;
try {
const comments = await Comment.create({
author: req.body.author,
content: req.body.content
});

//populate function on getPostById need the reference id from the comments
const posts = await Post.findById(id);
await Post.findByIdAndUpdate(id, { comments: [...posts.comments, comments._id] });

// Return all the posts with that category with a 200 status code
res.status(201).json(comments);
} catch (error) {
//handling error middleware - errorHandler
next(error);
}
};

//PATCH /posts/:id Update post information and return the updated post with status code 200
const updatePost = async (req, res, next) => {
// Retrieve the id from the route params
const { id } = req.params;
try {
const post = await Post.findByIdAndUpdate(id, req.body, { new: true });
res.status(200).json(post);
} catch (error) {
//handling error middleware - errorHandler
next(error);
}
};

// DELETE /posts/:id Delete the post and return the deleted post with status code 200 or 204
const deletePost = async (req, res, next) => {
// Retrieve the id from the route params
const { id } = req.params;
try {
//Remove post comments from database when you delete the post
const posts = await Post.findById(id);
await Comment.deleteMany({ _id: { $in: posts.comments } });
//Remove post
const post = await Post.findByIdAndDelete(id);
res.status(204).json(post);
} catch (error) {
//handling error middleware - errorHandler
next(error);
}
};

export default {
getPosts,
createPosts,
getPostById,
getPostsByCategory,
createPostComment,
updatePost,
deletePost
};
2 changes: 2 additions & 0 deletions apps/api/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { verifyToken } from './middleware/auth';
import { errorHandler } from './middleware/errorHandler';
import auth from './routes/auth';
import categories from './routes/categories';
import posts from './routes/posts';

const host = process.env.HOST ?? 'localhost';
const port = process.env.PORT ? Number(process.env.PORT) : 3000;
Expand All @@ -22,6 +23,7 @@ app.use('/api/auth', auth);

app.use(verifyToken);
app.use('/api/categories', categories);
app.use('/api/posts', posts);

app.use(errorHandler);

Expand Down
30 changes: 30 additions & 0 deletions apps/api/src/models/comment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import mongoose, { Document, Schema } from 'mongoose';

interface IComment extends Document {
author: string;
content: string;
// postId: mongoose.Schema.Types.ObjectId;
}

export const commentSchema = new Schema<IComment>(
{
author: {
type: String,
required: [true, 'Property is required']
},
content: {
type: String,
required: [true, 'Property is required']
}
// postId: {
// type: mongoose.Schema.Types.ObjectId,
// ref: 'Post'
// }
},
{
timestamps: true
}
);

const Comment = mongoose.model<IComment>('Comment', commentSchema);
export default Comment;
39 changes: 39 additions & 0 deletions apps/api/src/models/post.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import mongoose, { Document, Schema } from 'mongoose';

interface IPost extends Document {
title: string;
image: string;
description: string;
category: mongoose.Schema.Types.ObjectId;
comments: [{ type: Schema.Types.ObjectId }];
}

export const postSchema = new Schema<IPost>(
{
title: {
type: String,
required: [true, 'Property is required']
},
image: {
type: String,
required: [true, 'Property is required']
},
description: {
type: String,
required: [true, 'Property is required']
},
category: {
type: mongoose.Schema.Types.ObjectId,
required: [true, 'Property is required'],
ref: 'Category'
},
comments: [{ type: Schema.Types.ObjectId, ref: 'Comment' }]
},
{
timestamps: true
}
);

const Post = mongoose.model<IPost>('Post', postSchema);

export default Post;
28 changes: 28 additions & 0 deletions apps/api/src/routes/posts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import express from 'express';

import postController from '../controllers/posts';

const router = express.Router();

// GET /posts Return an array of all the posts with status code 200
router.get('/', postController.getPosts);

// POST /posts Create a new post and return the created post with status code 201
router.post('/', postController.createPosts);

// GET /posts/:id Return a post by id with category object and each comment object in the array with status code 200
router.get('/:id', postController.getPostById);

//GET /posts/category/:category Return an array of all the posts by category with status code 200
router.get('/category/:category', postController.getPostsByCategory);

// POST /posts/:id/comments Create a comment inside the post and return the comment with status code 201
router.post('/:id/:comments', postController.createPostComment);

//PATCH /posts/:id Update post information and return the updated post with status code 200
router.patch('/:id', postController.updatePost);

// DELETE /posts/:id Delete the post and return the deleted post with status code 200 or 204
router.delete('/:id', postController.deletePost);

export default router;