11
5

More than 1 year has passed since last update.

Nuxt3のServer Directoryで利用できるリクエスト一覧

Last updated at Posted at 2023-07-17

はじめに

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
index.get.ts
export default defineEventHandler(async (event) => {
    const query = getQuery(event)
    console.log(query.param1); // 「abcd」と出力される
});

サーバ側ではquery.param1=abcdとして値を取得できる。

リクエストボディ

リクエストボディから値を取得する方法もドキュメントに記載があるため、その通りに実装する。

  • クライアント側

リクエストボディの値はuseFetchbodyプロパティに設定する。

<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
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
[id].get.ts
export default defineEventHandler(async (event) => {
    const id: string | undefined = event.context.params?.id;
    console.log(id); // 「abcd」と出力される
});

実行することでクライアント側の/api/hoge/abcdabcdの部分が、サーバ側でevent.context.params.idに格納される。

[id]の部分は他の文字列でも問題ない。例えばtestIdの変数名で値を取得したい場合は、[id].get.tsではなく[testId].get.tsの名称でファイルを作成する。

その場合、APIの実装の方もtestIdに変更する必要がある。

[testId].get.ts
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" }が格納される。

11
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
5