はじめに
Nuxt3のServer APIで利用可能なリクエスト一覧です。
本記事で扱うデータの取得取得方法は下記の4つ。
- クエリパラメータ
- リエクエストボディ
- パスパラメータ
- マルチパートフォーム
サーバーAPIの公式ドキュメント
クエリパラメータ
クエリパラメータはドキュメントに記載がある為、そちらに従って実装する。
- クライアント側
<script setup lang="ts">
const res = await useFetch("/api/hoge?param1=abcd", {
method: "GET",
headers: { "Content-Type": "application/json" },
});
</script>
- サーバ側
サーバ側もドキュメントに従いgetQuery
メソッドを利用して取得する。nuxt3の自動インポート機能によりimport
文は不要。
例として以下のフォルダ構成でindex.get.ts
を作成する。
server/
| - api/
|- hoge/
| - index.get.ts
export default defineEventHandler(async (event) => {
const query = getQuery(event)
console.log(query.param1); // 「abcd」と出力される
});
サーバ側ではquery.param1=abcd
として値を取得できる。
リクエストボディ
リクエストボディから値を取得する方法もドキュメントに記載があるため、その通りに実装する。
- クライアント側
リクエストボディの値はuseFetch
のbody
プロパティに設定する。
<script setup lang="ts">
const res = await useFetch("/api/hoge", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ comment: "test" }),
});
</script>
- サーバ側
サーバ側でリクエストボディの値を取得する際はreadBody
を利用する。
例として以下のフォルダ構成でindex.post.ts
を作成する。
server/
| - api/
|- hoge/
| - index.post.ts
export default defineEventHandler(async (event) => {
const body = await readBody(event); // readBodyメソッドを利用
console.log(body) // 「{ comment: "test" }」と出力される
});
サーバ側ではbody={ comment: "hoge" }
として値を取得できる。
パスパラメータ
サーバAPI側のパスパラメータの取得処理は、フロントのルーティングと似たルールで実装することで実現可能。
- クライアント側
<script setup lang="ts">
const res = await useFetch("/api/hoge/abcd", {
method: "GET",
headers: { "Content-Type": "application/json" },
});
</script>
- サーバ側
パスパラメータとして値を受け取る為に、フロント側と同様にserver/api
配下に、[id].${メソッド名}.ts
の命名規則でファイルを作成する。
これにより、サーバ側ではevent.context.params?.id
と指定することで、[id]
に指定した値にアクセスできる。
例として、下記の様なフォルダ構成で[id].get.ts
を作成し処理を実装する。
server/
| - api/
|- hoge/
| - [id].get.ts
export default defineEventHandler(async (event) => {
const id: string | undefined = event.context.params?.id;
console.log(id); // 「abcd」と出力される
});
実行することでクライアント側の/api/hoge/abcd
のabcd
の部分が、サーバ側でevent.context.params.id
に格納される。
[id]
の部分は他の文字列でも問題ない。例えばtestId
の変数名で値を取得したい場合は、[id].get.ts
ではなく[testId].get.ts
の名称でファイルを作成する。
その場合、APIの実装の方もtestId
に変更する必要がある。
export default defineEventHandler(async (event) => {
// const id = event.context.params?.id;
const testId: string | undefined = event.context.params?.testId;
console.log(testId);
});
マルチパートフォーム
画像や動画の様な、メディアファイルのアップロードを実装する際に利用する。
マルチパートフォームに関してはNuxt3のドキュメントの方には記載が見当たらず(2023/07/21現在)、Nuxt3のサーバ側のライブラリであるh3のドキュメントを眺めている際に発見した。
- クライアント側
メディアデータを送信するクライアント側は、body
の引数にFormData()
を渡す。 formData
に値を追加する際のキーは、サーバーAPIで取得するときに検索するキーとなる為、サーバーAPIの定義と同じにする必要がある。
以下の例は、メディアファイルとjson形式の2つのデータを、マルチパートフォームを利用してサーバに送信する例である。
<script setup lang="ts">
const formData = new FormData();
formData.append("body", JSON.stringify({comment: "test" }));
formData.append("file", ${fileDataURL}); // 送信するメディアファイルのdataURLを設定する
const res = await useFetch(
`/api/hoge`,
{
method: "POST",
body: formData,
}
)
</script>
- サーバ側
サーバ側でマルチパートフォームでリクエストされた値を取得する際に、readMultipartFormData
を利用する。
Nuxt3の自動インポート機能の対象な為import
文は不要。
リクエストボディの際と同様に、下記の様なフォルダ構成でindex.post.ts
を作成する。
server/
| - api/
|- hoge/
| - index.post.ts
export default defineEventHandler(async (event) => {
const data = await readMultipartFormData(event!);
// リクエストボディとファイルを取得
let body: any | undefined = undefined;
let file: Buffer | undefined = undefined;
for (const d of data) {
if (d.name === "body") {
// クライアント側でformDataに「body」で登録した値
body = {
...JSON.parse(d.data.toString()),
};
} else if (d.name === "file") {
// クライアント側でformDataに「file」で登録した値
file = d.data;
}
}
});
file
にアップロードしたファイルがBuffer
形式で格納され、body
には{comment: "test" }
が格納される。