本日からSection5のPost API Routesの作成に入りました。珍しくスムーズに作業が進んで、ユーザーが投稿したテキストの追加と削除、それにlikeとunlikeの追加と削除のroutesが完成です。
今回使ったrequest は、POST・GET・DELETE・PUTです。前回、修正や復習をしたことでPostmanでのcollections作成にもかなり慣れてきて、間違えたとしてもすぐに気づくようになりました。少しずつは上達している感覚です。
Javascriptのmethodsについては、いくつかあやふやになっているものがあるので要復習です。
本日のコード①models/Post.js
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const PostSchema = new Schema({
user: {
type: Schema.Types.ObjectId,
ref: "users"
},
text: {
type: String,
required: true
},
name: {
type: String
},
avatar: {
type: String
},
likes: [
{
user: {
type: Schema.Types.ObjectId,
ref: "users" // to know which likes came from which user
}
}
],
comments: [
{
user: {
type: Schema.Types.ObjectId,
ref: "users"
},
text: {
type: String,
required: true
},
name: {
type: String
},
avatar: {
type: String
},
date: {
type: Date,
default: Date.now
}
}
],
date: {
type: Date,
default: Date.now
}
});
module.exports = Post = mongoose.model("post", PostSchema);
本日のコード②routes/api/posts.js (次回コードを追加予定)
const express = require("express");
const router = express.Router();
const { check, validationResult } = require("express-validator/check");
const auth = require("../../middleware/auth");
const Post = require("../../models/Post");
const Profile = require("../../models/Profile");
const User = require("../../models/User");
// @route POST api/posts
// @desc Create a route
// @access Private
router.post(
"/",
[
auth,
[
check("text", "Text is required")
.not()
.isEmpty()
]
],
async (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
try {
const user = await User.findById(req.user.id).select("-password");
const newPost = new Post({
text: req.body.text,
name: user.name,
avatar: user.avatar,
user: req.user.id
});
const post = await newPost.save();
res.json(post);
} catch (error) {
console.error(err.message);
res.status(500).send("Server Error");
}
}
);
// @route GET api/posts
// @desc GET all posts
// @access Private
router.get("/", auth, async (req, res) => {
try {
const posts = await Post.find().sort({ date: -1 });
res.json(posts);
} catch (err) {
console.error(err.message);
res.status(500).send("Server Error");
}
});
// @route GET api/posts/:id
// @desc GET post by ID
// @access Private
router.get("/:id", auth, async (req, res) => {
try {
const post = await Post.findById(req.params.id);
if (!post) {
return res.status(404).json({ msg: "Post not found" });
}
res.json(post);
} catch (err) {
console.error(err.message);
if (err.kind === "ObjectId") {
return res.status(404).json({ msg: "Post not found" });
}
res.status(500).send("Server Error");
}
});
// @route DELETE api/posts
// @desc Delete a post
// @access Private
router.delete("/:id", auth, async (req, res) => {
try {
const post = await Post.findById(req.params.id);
if (!post) {
return resizeBy.status(404).json({ msg: "Post not found" });
}
//Check user = the person deleting a post is the user who posted
if (post.user.toString() !== req.user.id) {
return res.status(401).json({ msg: "User not authorized" });
}
await post.remove();
res.json({ msg: "Post removed" });
} catch (err) {
console.error(err.message);
if (err.kind === "ObjectId") {
return res.status(404).json({ msg: "Post not found" });
}
res.status(500).send("Server Error");
}
});
// @route PUT api/like/:id
// @desc Like a post
// @access Private
router.put("/like/:id", auth, async (req, res) => {
try {
const post = await Post.findById(req.params.id);
//Check if the post has already been liked by this user
//req.user.id = logged in user
if (
post.likes.filter(like => like.user.toString() === req.user.id).length > 0
) {
return res.status(400).json({ msg: "Post already liked" });
}
post.likes.unshift({ user: req.user.id });
await post.save();
res.json(post.likes);
} catch (err) {
console.error(err.message);
res.status(500).send("Server Error");
}
});
// @route PUT api/unlike/:id
// @desc Like a post
// @access Private
router.put("/unlike/:id", auth, async (req, res) => {
try {
const post = await Post.findById(req.params.id);
//Check if the post has already been liked by this user
//req.user.id = logged in user
//length === 0 means the post is not liked yet
if (
post.likes.filter(like => like.user.toString() === req.user.id).length ===
0
) {
return res.status(400).json({ msg: "Post has not yet been liked" });
}
// Get remove index
const removeIndex = post.likes
.map(like => like.user.toString())
.indexOf(req.user.id);
post.likes.splice(removeIndex, 1);
await post.save();
res.json(post.likes);
} catch (err) {
console.error(err.message);
res.status(500).send("Server Error");
}
});
module.exports = router;
次回は、このコードの中にコメントを追加&削除するRoutesのコードを書いていく予定です。それが終われば、このUdemyコースのバックエンド部分は終了となります。そこからReactを使ってフロントエンド部分を作成していく予定です。
本日書いたコードを元にPostmanでcollections作成:6 requests
本日書いたコードで作成できたcollectionsは以下のとおり。Web Developersがお互いにコミュニケーションを取ることができるWebサービスなので、テキストを投稿したり、Facebookのようにlike/unlikeができるようになっています。
①POST:Add Posts
②GET: Get all posts
③GET: Get post by ID
④DELETE: Delete posts
⑤PUT: Like post
⑥PUT: unlike post
先週、かなり間違いをして修正につぐ修正をしたおかげで、今回の作成は比較的スムーズでした。
現在使用している教材と学習時間:本日の学習時間2.0時間
Udemy:MERN Stack Front To Back: Full Stack React, Redux & Node.js by Brad Traversy
Section5: Post API Routes
-Lec24: Creating The Post Model
-Lec25: Add Post Route
-Lec26: Get& Delete Post Routes
-Lec27: Post Like & Unlike Routes(ここまで完了)
進捗状況:38%
学習時間2.0時間
~本日は休みにしている教材~
Udemy:The Complete Web Developer: Zero to Mastery by Andrei Neagoie
進捗状況: 92%
-参考にしたページ-
「express実践入門」小川充 (GitHub)