Yanonoblog!

こつこつと

Next.js - API Routes

背景

実務ではReactを使っているのですがNext.jsのキャッチアップしておきたいと思ったので、その内容を整理したいと思います。

本記事では、Next.jsに関する情報をまとめています。

内容は易しめです。

前回の続きになります!

Next.js - ルーティング / ページ遷移の基本

API Routes

Next.jsでは、標準でAPIを作成するための仕組みが用意されています。

ReactやNext.jsによるアプリケーションでは、基本的にフロントエンドで処理を行い、必要に応じてデータなどをバックエンドであるサーバー側に問い合わせて受け取ります。

Next.jsには標準でWeb APIを簡単に実装するための仕組みが用意されています。

apiディレクト

アプリケーションの「pages」フォルダーの中には「api」というフォルダーが用意されています。この中にJavaScriptスクリプトファイルを配置するだけで、APIとして機能させることができます。

api」フォルダー内のスクリプトファイルは、/api/というパスにマッピングされます。

src/pages/api/hello.tsには、/api/helloというパスが割り当てられ、パスにアクセスするとAPIが実行されるようになります。

yarn create next-app した際のサンプルAPIを使用してみる

以下はyarn create next-app で作成されているAPIです。

// src/pages/api/hello.ts

// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import type { NextApiRequest, NextApiResponse } from 'next'

type Data = {
  name: string
}

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

http.ServerResponseオブジェクトからstatusというメソッドを呼び出し、更にjsonというメソッドを呼び出しています。

これらは「レスポンスヘルパー」と呼ばれるもので、Next.jsに用意されている機能です。

json()メソッドに渡されたdataオブジェクトは、JSON形式に変換され、レスポンスの本文としてクライアントに返されていることが確認できます。

image

クエリーパラメータに応じたAPIを返す例

image

このようにqueryに応じて配列のインデックスから取り出すようにすると動的パスにも対応することが出来ます。

// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import type { NextApiRequest, NextApiResponse } from 'next'

type ResponseData = {
  id: number;
  data: {
    name: string;
    email: string;
  }
}

type User = {
  name: string;
  email: string;
}[]

const data: User = [
  {name:'-', email:'-'},
  {name:'yano', email:'yano@yano'},
  {name:'やの', email:'yanoyano@yano'}
]

export default function handler(
  req: NextApiRequest,
  res: NextApiResponse<ResponseData>
) {
  const id = req.query.id ? +req.query.id : 0
  const result = data[id] ? data[id] : data[0]
  res.status(200).json({id:id, data:result})
}

セレクトボックスの値にに応じたAPIを返す例

セレクトボックスの値に応じてAPIを実行し該当のデータを配列から取り出すことによってセレクトボックスのデータを動的に切り替えています。

https://user-images.githubusercontent.com/78721963/234735278-0aa2556b-77e5-4121-82b3-f628e22b48dc.gif

このコードでは、セレクトボックスで選択した値を保管するselectedと、APIから取得したデータを保管するdataという2つのステートを用意しています。

useEffectフックを使用して、selectedの値が変更されたときにAPIにリクエストを送信し、レスポンスを取得して、取得したデータをsetData関数を使用してステートを更新することで取得したデータを表示しています。

// src/pages/select.tsx

import Head from 'next/head'
import { useState, useEffect } from 'react'

export default function Home() {
  const [selected, setSelected] = useState("0")

  const [data, setData] = useState({id:0,data:{name:'-',email:'-',tel:'-'}})
  useEffect(()=>{
    fetch(`/api/hello?id=${selected}`)
      .then(res=>res.json())
      .then(res=>setData(res))
  },[selected])

  const doAction = (e: React.ChangeEvent<HTMLSelectElement>) => setSelected(e.target.value)

  return (
    <div>
      <Head>
        <title>Select API Sample page.</title>
      </Head>
      <main className="container">
        <h2 className="my-4">Select API Sample page.</h2>
        <p>これは、サンプルで作成したページです。</p>
        <select className="form-select" onChange={doAction}>
          <option value="0">-</option>
          <option value="1">One</option>
          <option value="2">Two</option>
          <option value="3">Three</option>
        </select>
        <hr/>
        <div className="alert alert-primary">
          {data ?
          <table className="table">
            <thead>
              <tr>
                <th>ID</th>
                <th>Name</th>
                <th>Email</th>
                <th>Tel</th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <th>{data.id}</th>
                <td>{data.data.name}</td>
                <td>{data.data.email}</td>
                <td>{data.data.tel}</td>
              </tr>
            </tbody>
          </table>
          :<h6>nodata.</h6>}
        </div>
      </main>
    </div>
  )
}

続く…

コメント

本記事の内容は以上になります!

続きのアウトプットも随時更新したいと思います。

間違いがありましたら修正いたしますので、ご指摘ください。

興味があれば他の記事も更新していきますので是非ご覧になってください♪


プログラミングスクールのご紹介 (卒業生より)

お世話になったプログラミングスクールであるRUNTEQです♪

https://runteq.jp/r/ohtFwbjW

こちらのリンクを経由すると1万円引きになります。

RUNTEQを通じて開発学習の末、受託開発企業をご紹介いただき、現在も双方とご縁があります。

もし、興味がありましたらお気軽にコメントか、TwitterのDMでお声掛けください。

https://twitter.com/outputky

参考