「Next.jsでつくるフルスタックアプリ前編」の感想・備忘録1

スポンサーリンク

点数

78点

感想

Next.jsについての書籍だが本書は前編ということで、Next.jsとmongoDBを使ってのサーバサイドの実装のみだった。

内容自体は分かりやすかったが、Next.jsとmongoDBでサーバサイドを実装することは少ないと思うので、Next.jsに関する情報としては後編だけで十分だと思う。

毎回思うことだが、著者の書籍は説明が丁寧でとても分かりやすく、素晴らしいと思う。

環境構築

  1. npx create-next-app next-market
    TypeScriptはNo, ESLintはYesとする。
  2. cd next-market
  3. mkdir pages/api/{item,user}
  4. touch pages/api/item/{create,readall,[id],delete}.js
  5. mkdir utils
  6. touch utils/{database,schemaModel}.js
  7. touch form.html
  8. npm run devで確認

アイテム操作機能

データベースを用意

npm install mongoose
※ あらかじめmongoDBをローカルで動かしておく

import mongoose from 'mongoose'

const connectDB = async () => {
  try {
    mongoose.set('strictQuery', false)
    // localhostだと接続できなかったが127.0.0.1だと接続できた。
    await mongoose.connect('mongodb://127.0.0.1:27017/next-market');
    console.log("successfully connected to MongoDB.");
  } catch (err) {
    console.log("unconnected to MongoDB.");
    throw new Error();
  }
};

export default connectDB;

スキーマの作成

import mongoose from 'mongoose'

const itemSchema = mongoose.Schema({
  title: String,
  image: String,
  price: String,
  description: String,
  email: String
}); // _idは自動作成されるものなので定義不要
export const ItemModel = mongoose.models.Item || mongoose.model("Item", itemSchema);
// export const ItemModel = mongoose.model("Item", itemSchema);だとエラーが出る場合があるので念のため上記のようにするとのこと

投稿APIの作成

import connectDB from '../../../utils/database'
import { ItemModel } from "../../../utils/schemaModel";

const createItem = async (req, res) => {
  try {
    await connectDB();
    await ItemModel.create(req.body); // デフォルトでは__vというバージョン管理情報も保存される
    return res.status(200).json({ msg: '作成しました。' })
  } catch (err) {
    return res.status(400).json({ msg: '失敗しました。' })
  }
}
export default createItem;

投稿フォームの作成

<form action="http://localhost:3000/api/item/create" method="POST">
  <input type="text" name="title">
  <button type="submit">投稿</button>
</form>

全投稿取得APIの作成

import connectDB from '../../../utils/database'
import { ItemModel } from "../../../utils/schemaModel";

const getAllItems = async (req, res) => {
  try {
    await connectDB();
    const allItems = await ItemModel.find();
    return res.status(200).json({ msg: '取得成功', allItems: allItems })
  } catch (err) {
    return res.status(400).json({ msg: '取得失敗' })
  }
}
export default getAllItems;
// http://localhost:3000/api/item/readallで確認

投稿取得APIの作成

import connectDB from '../../../utils/database'
import { ItemModel } from "../../../utils/schemaModel";

const getSingleItem = async (req, res) => {
  try {
    await connectDB();
    const item = await ItemModel.findById(req.query.id);
    return res.status(200).json({ msg: '取得成功', item: item })
  } catch (err) {
    return res.status(400).json({ msg: '取得失敗' })
  }
}
export default getSingleItem;
// http://localhost:3000/api/item/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxで確認

投稿修正APIの作成

修正にはidを渡す必要があるが、pages/api/item/[id].jsは既に存在するのでpages/api/item/update/[id].jsを作成する。

  1. mkdir pages/api/item/update
  2. touch pages/api/item/update[id].js
import connectDB from '../../../../utils/database'
import { ItemModel } from "../../../../utils/schemaModel";

const updateItem = async (req, res) => {
  try {
    await connectDB();
    await ItemModel.updateOne({_id: req.query.id}, req.body);
    return res.status(200).json({ msg: '更新成功' })
  } catch (err) {
    return res.status(400).json({ msg: '更新失敗' })
  }
}
export default updateItem;

投稿削除APIの作成

削除にはidを渡す必要があるが、pages/api/item/[id].jsは既に存在するのでpages/api/item/delete/[id].jsを作成する。

  1. mkdir pages/api/item/delete
  2. touch pages/api/item/delete[id].js
import connectDB from '../../../../utils/database'
import { ItemModel } from "../../../../utils/schemaModel";

const deleteItem = async (req, res) => {
  try {
    await connectDB();
    await ItemModel.deleteOne({_id: req.query.id});
    return res.status(200).json({ msg: '削除成功' })
  } catch (err) {
    return res.status(400).json({ msg: '削除失敗' })
  }
}
export default deleteItem;

コメント