こんにちは。よっしーです(^^)
今日は、ルーティングについて解説しています。
背景
ルーティングについて調査する機会がありましたので、その時の内容を備忘として記事に残しました。
+server
SvelteKitというウェブアプリケーションフレームワークにおけるルーティングの機能について説明しています。主なポイントは以下の通りです:
- ページだけでなく、
+server.js
ファイルを使用してルートを定義することができます。
- これは「APIルート」や「エンドポイント」とも呼ばれます。
+server.js
ファイルを使用すると、レスポンスを完全に制御できます。+server.js
ファイルでは、HTTPメソッドに対応する関数をエクスポートします。
- 対応するHTTPメソッドには、GET、POST、PATCH、PUT、DELETE、OPTIONS、HEADなどがあります。
- これらの関数は、
RequestEvent
引数を受け取り、Response
オブジェクトを返します。
この機能により、開発者はAPIエンドポイントやカスタムサーバーサイドの処理を柔軟に実装することができます。通常のページレンダリングとは異なり、この方法では生のHTTPリクエストとレスポンスを直接扱うことができるため、より高度な制御が可能になります。
たとえば、GET ハンドラーを使用して /api/random-number ルートを作成できます。
// src/routes/api/random-number/+server.js
import { error } from '@sveltejs/kit';
/** @type {import('./$types').RequestHandler} */
export function GET({ url }) {
const min = Number(url.searchParams.get('min') ?? '0');
const max = Number(url.searchParams.get('max') ?? '1');
const d = max - min;
if (isNaN(d) || d < 0) {
error(400, 'min and max must be numbers, and min must be less than max');
}
const random = min + Math.random() * d;
return new Response(String(random));
}
Response
オブジェクトの生成:
Response
の最初の引数としてReadableStream
を使用できます。- これにより、大量のデータのストリーミングやサーバーセントイベントの作成が可能になります。
- ただし、AWS Lambdaのようにレスポンスをバッファリングするプラットフォームにデプロイする場合は、この機能が制限される可能性があります。
- 便利なメソッド:
@sveltejs/kit
から提供されるerror
、redirect
、json
メソッドを使用できます。- これらのメソッドは便利ですが、必須ではありません。
- エラー処理:
- エラーが発生した場合(
error(...)
を使用した場合や予期せぬエラーの場合)、レスポンスはエラーのJSON表現またはフォールバックエラーページになります。 - どちらになるかは、リクエストの
Accept
ヘッダーによって決まります。 - フォールバックエラーページは
src/error.html
でカスタマイズできます。 - この場合、
+error.svelte
コンポーネントは描画されません。
これらの機能により、開発者はより柔軟にサーバーサイドの処理を制御できます。大規模なデータ処理やリアルタイムの通信、エラー処理など、さまざまなシナリオに対応できるようになっています。
特に、ストリーミング機能は大量のデータを効率的に扱う場合に有用です。また、エラー処理の柔軟性も高く、APIとウェブページの両方に適した形でエラーレスポンスを返すことができます。
OPTIONS ハンドラーを作成するときは、Vite が Access-Control-Allow-Origin ヘッダーと Access-Control-Allow-Methods ヘッダーを挿入することに注意してください。これらは追加しない限り本番環境には存在しません。
Receiving data
POST/PUT/PATCH/DELETE/OPTIONS/HEAD ハンドラーをエクスポートすると、+server.js ファイルを使用して完全な API を作成できます。
// src/routes/add/+page.svelte
<script>
let a = 0;
let b = 0;
let total = 0;
async function add() {
const response = await fetch('/api/add', {
method: 'POST',
body: JSON.stringify({ a, b }),
headers: {
'content-type': 'application/json'
}
});
total = await response.json();
}
</script>
<input type="number" bind:value={a}> +
<input type="number" bind:value={b}> =
{total}
<button on:click={add}>Calculate</button>
// src/routes/api/add/+server.js
import { json } from '@sveltejs/kit';
/** @type {import('./$types').RequestHandler} */
export async function POST({ request }) {
const { a, b } = await request.json();
return json(a + b);
}
一般に、ブラウザからサーバーにデータを送信するには、フォーム アクションの方が適しています。
GET ハンドラーがエクスポートされる場合、HEAD リクエストは GET ハンドラーの応答本文のコンテンツ長を返します。
Fallback method handler
フォールバック ハンドラーのエクスポートは、+server.js からの専用エクスポートを持たない MOVE などのメソッドを含む、未処理のリクエスト メソッドと一致します。
// src/routes/api/add/+server.js
import { json, text } from '@sveltejs/kit';
export async function POST({ request }) {
const { a, b } = await request.json();
return json(a + b);
}
// This handler will respond to PUT, PATCH, DELETE, etc.
/** @type {import('./$types').RequestHandler} */
export async function fallback({ request }) {
return text(`I caught your ${request.method} request!`);
}
HEAD リクエストの場合、GET ハンドラーはフォールバック ハンドラーよりも優先されます。
Content negotiation
+server.js ファイルは +page ファイルと同じディレクトリに配置でき、同じルートをページまたは API エンドポイントにすることができます。どちらを決定するために、SvelteKit は次のルールを適用します。
- PUT/PATCH/DELETE/OPTIONS リクエストはページには適用されないため、常に +server.js によって処理されます。
- GET/POST/HEAD リクエストは、accept ヘッダーが text/html を優先する場合 (つまり、ブラウザ ページ リクエストである場合)、ページ リクエストとして扱われます。それ以外の場合は、+server.js によって処理されます。
- GET リクエストへの応答には Vary: Accept ヘッダーが含まれるため、プロキシとブラウザは HTML 応答と JSON 応答を別々にキャッシュします。
おわりに
今日は、 ルーティングについて解説しました。
何か質問や相談があれば、コメントをお願いします。また、エンジニア案件の相談にも随時対応していますので、お気軽にお問い合わせください。
それでは、また明日お会いしましょう(^^)
コメント