Next.jsでAPIを構築して利用する方法

ウェブサイト用に別途バックエンドを構築する必要があった時代は過ぎ去りました。Next.jsのファイルベースのAPIルーティングを使用すると、Next.jsプロジェクト内にAPIを記述することで、作業を楽にすることができます。

Next.jsは、実稼働環境で利用できるウェブアプリを構築するプロセスを簡素化する機能を備えたReactメタフレームワークです。Next.jsでREST APIを構築し、そのAPIからデータを取得してNext.jsページで利用する方法を説明します。

create-next-appを使用してNext.jsプロジェクトを作成する

create-next-app CLIツールを使用して、新しいNext.jsプロジェクトを作成できます。これにより、Next.jsアプリケーションの構築を開始するために必要なパッケージとファイルがインストールされます。

ターミナルでこのコマンドを実行して、api-routesという名前の新しいNext.jsフォルダーを作成します。create-next-appをインストールするように求めるプロンプトが表示される場合があります。

npx create-next-app api-routes

コマンドが完了したら、api-routesフォルダーを開いてAPIルートの作成を開始します。

Next.jsのAPIルーティング

APIルートはサーバー上で実行され、ユーザーデータをデータベースに保存したり、CORSポリシーエラーが発生せずにAPIからデータを取得したりするなど、さまざまな用途に使用できます。

Next.jsでは、/pages/apiフォルダー内にAPIルートを作成する必要があります。Next.jsはこのフォルダー内の各ファイルに対してAPIエンドポイントを生成します。user.jsを/pages/apiに追加すると、Next.jsはhttp://localhost:3000/api/userにエンドポイントを作成します。

基本的なNext.js APIルートには、次の構文があります。

export default function handler(req, res) {
res.status(200).json({ name: 'John Doe' })
}

handler関数をエクスポートして機能させる必要があります。

APIルートを作成する

/pages/apiフォルダーにtodo.jsという名前の新しいファイルを作成して、TODOアイテムのAPIルートを追加します。

TODOデータベースをモックする

TODOを取得するには、GETエンドポイントを作成する必要があります。わかりやすくするために、このチュートリアルではデータベースの代わりにTODOアイテムの配列を使用しますが、MongoDBやMySQLなどのデータベースを使用しても問題ありません。

アプリケーションのルートフォルダーにあるtodo.jsにTODOアイテムを作成し、次のデータを追加します。

export const todos = [
{
id: 1,
todo: "Do something nice for someone I care about",
completed: true,
userId: 26,
},
{
id: 2,
todo: "Memorize the fifty states and their capitals",
completed: false,
userId: 48,
},
// other todos
];

これらのTODOアイテムは、モックデータ用のREST APIであるDummyJSONウェブサイトからのものです。このDummyJSON TODOエンドポイントから正確なデータを見つけることができます。

次に、/pages/api/todos.jsにAPIルートを作成し、handler関数を追加します。

import { todos } from "../../todo";export function handler(req, res) {const { method } = req;switch (method) {case "GET":res.status(200).json(todos);break;case "POST":const { todo, completed } = req.body;todos.push({id: todos.length + 1,todo,completed,});res.status(200).json(todos);break;default:res.setHeader("Allow", ["GET", "POST"]);res.status(405).end(Method ${method} Not Allowed);break;}}

このルートはGETとPOSTのエンドポイントを処理します。GETリクエストに対してすべてのTODOを返し、POSTリクエストに対してTODOアイテムをTODOデータベースに追加します。他のメソッドの場合、ハンドラーはエラーを返します。

フロントエンドでAPIルートを利用する

TODOの配列を含むJSONオブジェクトを返すAPIエンドポイントを作成しました。

APIを利用するには、APIエンドポイントからデータを取得するfetchTodosという関数を作成します。この関数はfetchメソッドを使用しますが、Axiosを使用してAPIリクエストを行うこともできます。次に、ボタンをクリックしたときにこの関数を呼び出します。

import Head from "next/head";import { useState } from "react";export default function Home() {const [todos, settodos] = useState([]);const fetchTodos = async () => {const response = await fetch("/api/todos");const data = await response.json();settodos(data);};return (Create Next AppGet todos{todos.map((todo) => {return ({todo.todo}:{todo.completed}.);})});}

このスニペットのリストは、TODOアイテムがフェッチされると表示されます。

POSTエンドポイントの場合は、APIにPOSTリクエストを行うsaveTodoという新しい関数を作成します。fetchリクエストは新しいTODOアイテムを本文に格納し、新しいTODOアイテムを含むすべてのTODOアイテムを返します。次に、saveTodo関数はそれらをtodosの状態に格納します。

const saveTodo = async () => {
const response = await fetch("/api/todos", {
method: "POST",
body: JSON.stringify(newTodo),
headers: {
"Content-Type": "application/json",
},
});

const data = await response.json();
settodos(data);
};

次に、新しいTODOアイテムを受け取るテキスト入力バーを含むフォームを作成します。このフォームのsubmitハンドラー関数はsaveTodo関数を呼び出します。

import Head from "next/head";
import { useReducer, useState } from "react";
import styles from "../styles/Home.module.css";

export default function Home() {
const [todos, settodos] = useState([]);

const [newTodo, setnewTodo] = useState({
todo: "",
completed: false,
});

const fetchTodos = async () => {
// fetchTodos
};

const saveTodo = async (e) => {
const response = await fetch("/api/todos", {
method: "POST",
body: JSON.stringify(newTodo),
headers: {
"Content-Type": "application/json",
},
});

const data = await response.json();
settodos(data);
};

const handleChange = (e) => {
setnewTodo({
todo: e.target.value,
});
};

const handleSubmit = (e) => {
e.preventDefault();
saveTodo();
setnewTodo({
todo: '',
});
};

return (
<div className={styles.container}>
<Head>
<title>Create Next App</title>
<meta name="description" content="Generated by create next app" />
<link rel="icon" href="/favicon.ico" />
</Head>
<main>
// Fetches the todo items when clicked
<button onClick={fetchTodos}>Get todos</button>

// Saves a new todo item when submitted
<form onSubmit={handleSubmit}>
<input type="text" onChange={handleChange} value={newTodo.todo} />
</form>
<ul>
{// list todo items}
</ul>
</main>
</div>
);
}

このハンドラーは、ユーザーがフォームを送信するたびに新しいTODOをデータベースに追加します。また、この関数はAPIから受信したデータを使用してtodosの値を更新し、新しいTODOアイテムをリストに追加します。

APIルーティングはNext.jsの長所のほんの一部にすぎない

Next.jsのAPIルートを構築して使用する方法を説明しました。これで、Next.jsプロジェクトフォルダーを離れることなく、フルスタックアプリケーションを作成できます。APIルーティングは、Next.jsが提供する多くの利点の1つです。

Next.jsはまた、コード分割、遅延読み込み、組み込みのCSSサポートなどのパフォーマンス最適化も提供します。高速でSEOに優しいウェブサイトを構築する場合は、Next.jsを検討する必要があります。