12k
All articles

SvelteKit Remote Functions 初心者ガイド

SvelteKit の remote functions は型安全なサーバー呼び出しで手動 API を置き換える。query・form・command・prerender の違いを解説。

OpenReplay Team
OpenReplay Team
SvelteKit Remote Functions 初心者ガイド

SvelteKitアプリを+server.tsエンドポイントやフォームアクションで構築してきた方へ。これらは機能しますが、ボイラープレートコードを書く必要があります。リクエストボディのパース、手動での入力検証、クライアントとサーバーで別々の型定義の保守など。SvelteKit Remote Functionsは異なるアプローチを提供します—従来のAPIエンドポイントの儀式的な作業なしに、型安全なサーバー呼び出しを実現します。

このガイドでは、リモート関数とは何か、各タイプをいつ使用するか、そして採用前に理解すべきトレードオフについて説明します。

重要なポイント

  • リモート関数は、サーバーサイドコードをHTTPエンドポイントにコンパイルし、自動生成されたfetchラッパーを提供することで、手動でのAPIルート保守なしにエンドツーエンドの型安全性を実現します。
  • 4つの関数タイプがそれぞれ異なる目的を果たします:queryはデータ取得用、formはプログレッシブエンハンスメント対応の送信用、commandはJavaScript依存のミューテーション用、prerenderはビルド時の静的データ用です。
  • すべてのリモート関数は公開アクセス可能なエンドポイントになるため、ZodやValibotなどのStandard Schemaライブラリを使用した入力検証がセキュリティ上不可欠です。
  • リモート関数は明示的なオプトインが必要で、実験的機能のままであるため、API変更が予想されます。潜在的な脆弱性に対処するため、SvelteKitを最新に保つことが重要です。

SvelteKit Remote Functionsとは?

リモート関数を使用すると、クライアントが通常の関数のように呼び出せるサーバーサイドコードを記述できます。裏側では、SvelteKitがこれらをHTTPエンドポイントにコンパイルし、クライアント用のfetchラッパーを生成します。従来のAPIルートを構築・保守することなく、エンドツーエンドの型安全性が得られます。

SvelteKitがフロントエンドとバックエンド間の配管作業を処理してくれると考えてください。.remote.tsファイルに関数を記述すれば、SvelteKitがシリアライゼーション、エンドポイント生成、型推論を処理します。

公式リファレンスが必要な場合、この機能はSvelteKitドキュメントのRemote Functionsセクションに記載されています: https://kit.svelte.dev/docs/remote-functions

実験的機能の有効化

リモート関数は、svelte.config.jskit.experimental.remoteFunctionsを通じて明示的なオプトインが必要です:

const config = {
  kit: {
    experimental: {
      remoteFunctions: true
    }
  }
};

export default config;

Svelteコンポーネント内で直接awaitを使用したい場合は、Svelteの実験的非同期サポートを別途有効にする必要があります。これは必須ではありません—リモート関数はこれなしでも動作します—が、コンポーネントコードを簡素化します。

SvelteKit Server Functionsの4つのタイプ

リモート関数には4つのバリエーションがあり、それぞれ特定のユースケース向けに設計されています。

Query: 動的データの取得

データベース、API、またはサーバーリソースからデータを読み取る際にqueryを使用します。クエリはコンポーネントのレンダリング中に実行でき、同じレンダリングライフサイクル内で重複排除とバッチ処理が行われます。

import { query } from '$app/server';
import { db } from '$lib/db';
import { posts } from '$lib/schema';

export const getPosts = query(async () => {
  return await db.select().from(posts);
});

パフォーマンスが重要なシナリオでは、query.batchが複数の同時呼び出しを単一のリクエストにグループ化し、手動最適化なしにn+1問題を解決します。

Form: プログレッシブエンハンスメント対応のデータミューテーション

form関数はユーザー入力の送信を処理します。主な利点はプログレッシブエンハンスメントです。フォームはJavaScriptなしで動作し、必要に応じて従来の送信方法にフォールバックします。

返されたオブジェクトを<form>要素にスプレッドすれば、SvelteKitが拡張版と非拡張版の両方の送信を自動的に処理します。

Command: 柔軟なミューテーション

commandformと同様に機能しますが、フォーム要素に縛られません。ボタンクリック、ドラッグ&ドロップアクション、またはフォームコンテキスト外でトリガーされるミューテーションに使用します。

フォームとは異なり、コマンドはJavaScriptを必要とします。プログレッシブエンハンスメントが重要な場合はformを選択してください。柔軟性が必要な場合はcommandを選択してください。

Prerender: ビルド時の静的データ

prerenderは実行時ではなく、ビルド時にデータを取得します。結果はビルド時にキャッシュされ、プラットフォームキャッシュまたはCDN経由で提供されます。設定、デプロイ時にのみ変更されるCMSコンテンツ、またはリアルタイム更新が不要なデータに使用します。

重要な制約:queryは完全にプリレンダリングされたページでは使用できません。クエリは本質的に動的だからです。

セキュリティ: すべてのリモート関数は公開エンドポイント

これは理解が重要です:すべてのリモート関数は、誰でも呼び出せるHTTPエンドポイントになります。入力検証はオプションではなく、不可欠です。

SvelteKitは、ZodやValibotなどのStandard Schemaライブラリを使用した引数の検証を期待しています(“Standard Schema”イニシアチブはhttps://standardschema.devに文書化されています):

import { query } from '$app/server';
import * as v from 'valibot';
import { db } from '$lib/db';
import { posts } from '$lib/schema';

const Params = v.object({
  slug: v.string()
});

export const getPost = query(Params, async ({ slug }) => {
  return await db.select().from(posts).where(eq(posts.slug, slug));
});

検証なしでは、攻撃者がエンドポイントに任意のデータを送信できます。SvelteKitは通常、検証失敗に対して400レベルのエラーを返し、情報漏洩を回避します。

SvelteKitを最新に保つ

過去のバージョンには、DoS問題を含むリモート関数に影響する脆弱性がありました。特に機能が実験的段階にある間(SvelteKit 2.x時点)は、リリースを最新に保ってください。

考慮すべきトレードオフ

リモート関数はボイラープレートを削減しますが、魔法ではありません。以下の制約を考慮してください:

  • ファイルの場所が重要: .remote.tsファイルはsrc/lib/serverを除くsrc内の任意の場所に配置
  • プリレンダーキャッシング: ブラウザとCDNのキャッシングにより、再デプロイまでデータが古くなる可能性
  • 実験的ステータス: API変更やバグが予想される

リモート関数は、別々のエンドポイント定義を保守することなく型安全なクライアント・サーバー通信が必要な場合に最適です。すべての+server.tsファイルの代替ではありません—複雑な認証フローやサードパーティのWebhookハンドラーは、従来のエンドポイントが適している場合があります。

各関数タイプを使用するタイミング

シナリオ関数タイプ
データベースレコードの取得query
フォールバック付きフォーム送信form
ボタントリガーアクションcommand
CMSコンテンツ、サイト設定prerender

まとめ

SvelteKit Remote Functionsは、クライアントとサーバーコード間の境界を簡素化します。手動でのエンドポイント保守を排除しながら、組み込みの検証と型安全性を提供します。データ取得にはqueryから始め、ユーザー入力にはformを追加し、特定のパターンに適合する場合はcommandまたはprerenderを使用してください。

この機能は実験的です—変更が予想されます。しかし、エンドポイントのボイラープレートに疲れたSvelteKit開発者にとって、リモート関数は探求する価値のある魅力的な代替手段を提供します。

よくある質問

同じプロジェクト内で既存の+server.tsエンドポイントとリモート関数を併用できますか?

はい、リモート関数と従来のエンドポイントは競合なく共存できます。段階的に移行でき、エンドポイントを一度に1つずつ変換できます。多くのプロジェクトでは、複雑な認証やWebhookハンドラーを従来のエンドポイントとして保持しながら、よりシンプルなデータ操作にリモート関数を使用しています。

リモート関数は認証と認可をどのように処理しますか?

リモート関数には組み込みの認証機能はありません。SvelteKitの標準メカニズムを通じてリクエストコンテキストにアクセスし、各関数内で認可チェックを実装します。保護が必要な関数の開始時にユーザーセッションと権限を検証してください。従来のエンドポイントと同様です。

リモート関数がエラーをスローした場合、何が起こりますか?

未処理のエラーは、クライアントに500レスポンスを返します。SvelteKitは本番環境でエラーメッセージをサニタイズし、機密情報の漏洩を防ぎます。制御されたエラー処理には、@sveltejs/kitからredirectまたはerrorオブジェクトをスローしてください。SvelteKitがクライアント側で適切に処理します。

リモート関数はサーバーレスデプロイ用のSvelteKitアダプターで動作しますか?

リモート関数は、サーバーサイドレンダリングをサポートする任意のアダプターで動作します。標準のHTTPエンドポイントにコンパイルされるため、Vercel、Netlify、Cloudflare Workersなどのプラットフォームで通常通り処理されます。プリレンダー関数はビルド時にのみ実行されるため、どこでも動作します。

DevTools for the frontend

Gain Debugging Superpowers

Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers.

Star on GitHub12k

We use cookies to improve your experience. By using our site, you accept cookies.