Next.jsを利用した一番簡単なAPIの実装

公式LINEからの予約ツールを作りたい（Lステップなど既製品ではなく、自分の学習も兼ねて作りたい）と考えはじめ、スプレッドシートとの連携を考えてGASでの作成も考えたけど、これからスタンダードになるTypescriptを使ったりしたいよねって思ってNext.jsを使って作り始めた。

- [Githubリポジトリ](https://github.com/takumakoike/line-reservation-app)

大元のコードは上記リポジトリになるのだが、今回は該当箇所を紹介します。

## Next.jsの導入
今回については、`npx create-next-app@latest [project-name] [options]`の方法ではなく、GithubからのCloneを利用して始めました。
というのも、もともと作ってあったNext.jsプロジェクトがあったのですが、基本の管理をGithubに集約したら、ローカル上にはあんましコード置いとかなくてもいいんじゃない？って思って、一旦ローカルから削除してたのもありまして。
ということで、該当のリポジトリページからCloneします。
ghコマンドを使えるようにしているのであれば
`gh repo clone takumakoike/line-reservation-app`
URLからのCloneであれば
`https://github.com/takumakoike/line-reservation-app.git`
で実行します。

さてCloneしたし早速`npm run dev`してサーバー立ち上げようとすると、エラー。
ちょっと考えましたが、node_module自体をignoreしていので、cloneしたときにはありません。
なのでルートディレクトリで`npm install`して依存関係にあるものをインストールして再度実行。
無事に立ち上がりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/524273/c6dcc49c-281b-4c00-f804-4c8e769e4df2.png)


## 今回やりたいこと
APIの処理を自分で作りたい！というのがスタートになりますが、いろいろ調べてみても思った記事に辿り着くことは少なく、いろんな実装方法があるのだなと感じました。
今回はなるべくシンプルに実装したいという思いがあったので、appディレクトリの下にapiディレクトリを作成し、そこにroute.tsファイルを作ることでAPIの実装を図りました。

### ①GETリクエストに対するAPI処理を作りたい
GETリクエスト自体はNext.jsのデフォルトコンポーネントのLINKを利用して、href属性にapiのパスを入力すればリクエストの完成になります。
処理の実際については
```Next.js:app/api/route.ts
import { NextResponse } from "next/server";

export async function GET() {
    const data = { message: "APIテスト成功", status: "OK" };

    return NextResponse.json(data, { status: 200 });
}
```
とすると、リンクを踏んだときに、APIテスト成功、のメッセージが出るようになりました。

これができれば、本来やりたいこととして考えているLINEからの予約機能の実装について、リッチメニューにGETリクエストのエンドポイントURLを指定しておけば、任意の画面が見られるようになると考えています（例えば認証情報やCookieを利用して予約状況を確認するなど）

### ②フォームを作ってPOSTメソッドに対するAPI処理を作りたい
続いてはPOSTメソッドに関する処理です。
こちらはトップページにフォームを用意し、上記同様にroute.tsを編集しています。
```Next.js:app/page.tsx
export default function Home() {  
  return (
    <div>
        〜中略〜
        <form action="/api" method='POST'>
          <div>
            <label htmlFor="name">なまえ</label>
            <input type="text" id="name" name='name' />
          </div>
          <button type="submit">そうしん</button>
        </form>
      </div>
    </div>
  );
}
```
```Next.js:app/api/route.ts
export async function POST(request: Request) {
    try {
        const body = await request.formData();
        const name = body.get("name");

        const resOption = {
        status: 200,
        headers: {
            "Content-Type": "application/json",
        },
        };

        return new Response(
        JSON.stringify({ message: `受信内容:${name}` }),
        resOption
        );
    } catch (error: unknown) {
        const errorMessage =
        error instanceof Error ? error.message : "Unknown error occurred";

        return new Response(JSON.stringify({ error: errorMessage }), {
        status: 400,
        headers: { "Content-Type": "application/json" },
        });
    }
}
```
これにより、formタグの中にあるinputタグに対して、何か任意の入力をして送信すると、apiのPOSTメソッドが呼び出され、入力した内容がそのまま返されるということが実装できました。

POSTメソッドが実装できるようになれば、LINE messaging APIの利用と合わせて予約情報をDBに保存したりといったことができるようになる（はず）なので、こちらも必須の技術になりますね。

## 全体の注意点
- Next.jsのAPI機能実装については`api`ディレクトリの直下に`route.ts`ファイルを作る必要がある
- フォームデータの送信については、`json()`で受け取るのではなく、`formData()`で受け取ることが必要
- レスポンスを返すときにはオプションのheaders項目に`{"Content-Type": "application/json}`を明示することでエラーを回避できる

ということがわかりました。

GASでは何となく経験がありましたが、こうやってシンプルに作ってみるといい勉強になりました。