Svelte入門:リファレンス $app/server

スポンサーリンク
Svelte入門:リファレンス $app/server 用語解説
Svelte入門:リファレンス $app/server
この記事は約12分で読めます。
よっしー
よっしー

こんにちは。よっしーです(^^)

今日は、SvelteKitのリファレンスについて解説しています。

スポンサーリンク

背景

SvelteKitのリファレンスについて調査する機会がありましたので、その時の内容を備忘として記事に残しました。

$app/server

import { getRequestEvent, read } from '$app/server';

$app/server モジュールは SvelteKit アプリケーションでサーバーサイド特有の機能にアクセスするためのユーティリティを提供します。このモジュールは、サーバーサイドのコンテキストでのみ使用可能です(クライアントサイドでは使用できません)。

このモジュールには以下の2つの主要なエクスポートが含まれています:

  1. getRequestEvent – 現在のリクエストイベントを取得するための関数です。リクエストに関する情報やサーバーサイドのコンテキストへのアクセスを提供します。
  2. read – Svelteコンポーネントを含む、カスタムファイルタイプの内容を読み取るための関数です。主に高度なユースケース向けです。

これらの関数は、サーバーサイドでのみ実行されるコード(例:サーバーアクション、サーバー関数、ロードメソッドなど)内で使用できます。クライアントサイドのブラウザ環境では使用できないため、使用する際はサーバーサイドのコンテキストであることを確認する必要があります。

使用シナリオ

これらの関数は主に以下のような状況で使用されます:

  • サーバーサイドでリクエストに関する詳細情報(ヘッダー、クッキー、パラメータなど)へのアクセスが必要な場合
  • サーバーサイドでのみ利用可能な機能(ファイルシステム、データベース接続など)にアクセスする場合
  • コンポーネントファイルの内容を直接読み取る高度なユースケース

次のセクションで、各関数の詳細な説明を行います。

getRequestEvent

バージョン 2.20.0 以降で利用可能 現在の RequestEvent を返します。handleload、アクション(およびそれらから呼び出される関数)内で使用できます。 AsyncLocalStorage のない環境では、これは同期的に呼び出す必要があります(つまり、await の後ではなく)。

function getRequestEvent(): RequestEvent
	Partial<Record<string, string>>,
	string | null
>;

解説

getRequestEvent は SvelteKit の $app/server モジュールが提供する関数で、以下のような特徴があります:

  1. リクエストコンテキストへのアクセス – 現在処理中のリクエストに関する情報やコンテキストにアクセスするために使用します。
  2. サーバーサイド専用 – この関数はサーバーサイドでのみ使用でき、クライアントサイドのコード(ブラウザで実行されるコード)では使用できません。
  3. 利用可能なコンテキスト – 以下の場所で使用可能です:
    • hooks.server.jshandle 関数内
    • +page.server.js+layout.server.jsload 関数内
    • サーバーアクション内
    • 上記から呼び出される関数内
  4. 同期的な呼び出し – 一部の環境(AsyncLocalStorage をサポートしていない環境)では、await の後ではなく同期的に呼び出す必要があります。
  5. 戻り値RequestEvent オブジェクトが返されます。これには、リクエストヘッダー、クッキー、URL パラメータ、フェッチ機能などが含まれます。

使用例

// +page.server.js
import { getRequestEvent } from '$app/server';

// サーバーアクションの例
export const actions = {
  default: async () => {
    const event = getRequestEvent();
    
    // リクエストヘッダーへのアクセス
    const userAgent = event.request.headers.get('user-agent');
    
    // クッキーへのアクセス
    const cookies = event.cookies;
    const sessionId = cookies.get('sessionid');
    
    // URL パラメータへのアクセス
    const { id } = event.params;
    
    // 応答の設定
    cookies.set('last_action', new Date().toISOString(), {
      path: '/',
      maxAge: 60 * 60
    });
    
    return { success: true };
  }
};

// load 関数の例
export async function load() {
  const event = getRequestEvent();
  
  // サーバーサイドのみで利用可能な環境変数へのアクセス
  const apiKey = process.env.API_KEY;
  
  // サーバーサイドのフェッチ
  const data = await event.fetch('/api/internal', {
    headers: {
      'Authorization': `Bearer ${apiKey}`
    }
  });
  
  return {
    serverData: await data.json()
  };
}

// ユーティリティ関数の例
async function checkUserPermission(userId) {
  // リクエストイベントを取得
  const event = getRequestEvent();
  
  // データベース接続などのサーバーサイドリソースへのアクセス
  const db = event.platform.env.DATABASE;
  
  // ユーザー権限の確認
  const permissions = await db.query('SELECT * FROM permissions WHERE user_id = $1', [userId]);
  
  return permissions;
}

getRequestEvent は、特に以下のような場合に役立ちます:

  1. 認証・認可 – リクエストヘッダーやクッキーを検証して、ユーザー認証を処理する場合。
  2. リクエスト固有の情報へのアクセス – URL パラメータ、クエリパラメータ、リクエストボディなどにアクセスする場合。
  3. レスポンスの制御 – クッキーの設定、ヘッダーの設定、リダイレクトの実行など。
  4. サーバーサイドのみのリソースへのアクセス – 環境変数、データベース接続、ファイルシステムなど、クライアントサイドでは利用できないリソースにアクセスする場合。
  5. サーバーサイドユーティリティの作成 – 複数のアクションや load 関数で再利用できるサーバーサイドユーティリティを作成する場合。

注意点として、AsyncLocalStorage をサポートしていない環境では、await の後で getRequestEvent を呼び出すとエラーになる可能性があるため、同期的に呼び出すか、await の前に変数に格納しておくことが推奨されます。

read

バージョン 2.4.0 以降で利用可能 ファイルシステムからインポートされたアセットの内容を読み取ります

import { read } from '$app/server';
import somefile from './somefile.txt';

const asset = read(somefile);
const text = await asset.text();
function read(asset: string): Response;

解説

read は SvelteKit の $app/server モジュールが提供する関数で、以下のような特徴があります:

  1. アセット読み取り – インポートしたファイルの内容をサーバーサイドで読み取るために使用します。
  2. サーバーサイド専用 – この関数はサーバーサイドでのみ使用でき、クライアントサイドのコード(ブラウザで実行されるコード)では使用できません。
  3. 引数 – インポートされたアセットのパス(文字列)を受け取ります。
  4. 戻り値Response オブジェクトを返します。これは Web 標準の Response オブジェクトと同様に、.text().json().arrayBuffer() などのメソッドを持ちます。
  5. 用途 – コンポーネントではないファイル(テキストファイル、JSON、画像など)の内容にサーバーサイドでアクセスする際に使用します。

使用例

// +page.server.js
import { read } from '$app/server';
import configFile from '../config.json';
import template from './template.html';
import rawData from './data.csv';

export async function load() {
  // JSON ファイルの読み取り
  const configResponse = read(configFile);
  const config = await configResponse.json();
  
  // HTML テンプレートの読み取り
  const templateResponse = read(template);
  const templateHtml = await templateResponse.text();
  
  // CSV データの読み取り
  const dataResponse = read(rawData);
  const csvContent = await dataResponse.text();
  
  // CSV を解析して処理
  const parsedData = parseCSV(csvContent);
  
  return {
    config,
    template: templateHtml,
    data: parsedData
  };
}

// CSV パース用のヘルパー関数
function parseCSV(csvContent) {
  // CSV パース処理
  const lines = csvContent.trim().split('\n');
  const headers = lines[0].split(',');
  
  return lines.slice(1).map(line => {
    const values = line.split(',');
    return headers.reduce((obj, header, i) => {
      obj[header] = values[i];
      return obj;
    }, {});
  });
}

別の使用例として、画像やバイナリファイルの読み取り:

// +server.js
import { read } from '$app/server';
import imageFile from '../assets/image.png';

export async function GET() {
  const imageResponse = read(imageFile);
  
  // バイナリデータとして読み取り
  const imageBuffer = await imageResponse.arrayBuffer();
  
  // ヘッダー情報へのアクセス
  const contentType = imageResponse.headers.get('content-type');
  
  // 新しいレスポンスを作成して返す
  return new Response(imageBuffer, {
    headers: {
      'content-type': contentType,
      'cache-control': 'max-age=3600'
    }
  });
}

Svelte ファイルのソースコードへのアクセス(高度なユースケース):

// +page.server.js
import { read } from '$app/server';
import ComponentSource from './Example.svelte';

export async function load() {
  // Svelte コンポーネントのソースコードを読み取る
  const componentResponse = read(ComponentSource);
  const sourceCode = await componentResponse.text();
  
  // ソースコードを解析または表示
  return {
    componentSource: sourceCode
  };
}

read 関数は、特に以下のような場合に役立ちます:

  1. 静的ファイルの読み込み – 設定ファイル、テンプレート、データファイルなどの静的ファイルをサーバーサイドで読み込む場合。
  2. コンテンツ生成 – HTML、マークダウン、テンプレートなどのファイルを読み込み、動的にコンテンツを生成する場合。
  3. アセット処理 – 画像や他のバイナリファイルを読み込み、サーバーサイドで処理する場合。
  4. ドキュメント生成 – ソースコードやドキュメントファイルを読み込み、ドキュメント生成システムを構築する場合。

注意点として、read 関数はサーバーサイドでのみ機能し、ビルド時に解決される静的インポートされたアセットにのみ使用できます。動的なファイルパスや実行時に変わるファイルには使用できません。

おわりに

今日は、 SvelteKitのリファレンスについて解説しました。

よっしー
よっしー

何か質問や相談があれば、コメントをお願いします。また、エンジニア案件の相談にも随時対応していますので、お気軽にお問い合わせください。

それでは、また明日お会いしましょう(^^)

コメント

タイトルとURLをコピーしました