Astro JSの非HTMLルート:ファイル&リソースAPI

🐝 AstroはHTMLだけじゃない!

この投稿では、Astro JSの非HTMLルートについて見ていきます。Astroは、コンテンツサイトの配信を得意としており、それを素早く行います。ただし、配信するコンテンツがHTMLページだけである必要はありません。実際に、Astroの非HTMLルートの例をいくつか見ていきます。最初の例では、APIルートからPDFファイルを生成して提供します。一方で、2つ目の例では、JSONデータを作成します(これもリソースルートから)。これを拡張してJSON APIを作成することもできます。我々の例は静的なAstroサイトに焦点を当てていますが、Astro SSRサイトにも適応可能であることがわかります。SSRではさらに進んで、Webhookへの応答や、次世代の画像の生成、またはサイトのHTMLページのためのソーシャルシェア用画像を作成することができます。

🧱 Astro JSの非HTMLルート

実を言うと、Astroサイトに非HTMLルートを追加することはそれほど多くはありません。したがって、スクラッチからプロジェクトを構築する代わりに、いくつかのコード例を見ていくことにしましょう。それで大丈夫ですか!完全なコードが欲しい場合は、リポジトリがありますので、ページの下の方にリンクがあるのでご覧ください。

このアイデアは、サイトのHTMLコードからリソースをリンクできるようにすることです。ここでは、リンクをホームページに置きます。もちろん、出発点やユースケースによっては、他にもより良いソリューションがあるかもしれません。例えば、ファクトシートを作成したとしましょう。リンクをクリックした全員に同じファクトシートを配布する場合(カスタマイズなし)、publicフォルダーにPDFファイルを配置するだけでも良いかもしれません。実際、そのフォルダーはViteによる処理を必要としないものすべてのためのものです。public/factsheet.pdf/factsheet.pdfとしてhrefでリンクできます。

静的なAstro JSの非HTMLルート

もう一つ上のレベルに行きましょう。まだファクトシートを持っていますが、今度はアプリをビルドするたびに最新の利用可能なデータを取り込みたいとします。静的なAstroサイトで(デフォルトです)。ファクトシートは、時折変わる外部APIからデータを取り込むかもしれません。ここでは、私たちの静的サイトを使うアプローチにできます。ファイルルートでビルド時にPDFを生成できます。再び、すべてのユーザーは同じニュースレターを受け取りますが、インプットデータが変わるたびに手動で更新する手間を自分自身で省くことができます。

hrefpublicの場合と似ていますが、データの源泉が異なり、非HTMLリソースルートで異なって生成されます:

<!-- TRUNCATED -->
  <body>
    <main class="wrapper">
      <h1>Astro JSの非HTMLルート</h1>
      <ul>
        <li><a aria-label="PDFファイルを開く" href="/pdf-resource.pdf">PDFファイルルート</a></li>
        <li><a aria-label="JSONファイルを開く" href="/json-resource.json">JSONファイルルート</a></li>
      </ul>
    </main>
    </body>
    </html>

サーバーサイドレンダリング(SSR) APIルート

SSR Astroサイトを構築したい場合、ここで行っていることと似たアプローチが選べます。この場合、訪問者の名前をファクトシートの一番上に追加するような個別化も可能です。静的サイトと比べて変更が必要なのは僅かな部分だけですが、SSRサイトでPDFを生成するために必要です。現実には、最大の違いは、ユーザーの個別データを収集するためにフォームやその他のメカニズムが必要になることです。

📝 静的サイト上でのAstro PDFファイルルート

静的サイトでAstroの非HTMLルートを作成するには、src/pagesに新しいファイルを追加します。HTMLページのファイルベースルーティングと同様に、パスはアクセスするファイルのhrefを反映します。唯一の違いは.jsまたは.tsを最後に追加することです。上記のスニペットでhref/pdf-resource.pdfの場合、リソースルートの完全なパスはsrc/pages/pdf-resource.tsになります(TypeScriptを使用します)。

ここがそのファイルです:

import type { APIRoute } from 'astro';
import pdf from 'pdfjs';
import helvetica from 'pdfjs/font/Helvetica';

export const get: APIRoute = async function get() {
  try {
    const doc = new pdf.Document({ font: helvetica, padding: 10 });
    const text = doc.text({ fontSize: 12 });
    text.add('サンプルPDF');
    const buffer = await doc.asBuffer();

    return { body: buffer.toString('binary'), encoding: 'binary' };
  } catch (error: unknown) {
    throw new Error(`pdf-resource.pdfルートで問題が発生しました!: ${error as string}`);
  }
};

ここではpdfjsパッケージを使い、PDFを生成します。我々の場合はダミーの内容です。実際のアプリではゼロから生成するか、他のPDFを組み合わせて作ることができます。pdfjsのドキュメントでの使用法について詳しくはこちら。最も重要なのは、12行目で返すアウトプットです。静的サイトでは、bodyフィールドが文字列のオブジェクトを返すことを目指してください。SSRの場合はResponseオブジェクトを返すことができ、HTMLもストリーミングできます。ここではbinaryエンコーディングを使用しており、これはAstroが画像を含むPDFを正確にエンコードできるようにするためです — ここでのアドバイスは@altanoに感謝します。

静的サイトを構築する際には、このファイルはサイトを再ビルドするときにのみ変更されます。各訪問者にカスタマイズする必要がない場合はこれで問題ありません。

SSR拡張

SSRではファイル名に.pdf拡張子は不要です。Responseオブジェクトを返し、application/pdfヘッダを含めることもできます:

import type { APIRoute } from 'astro';
import pdf from 'pdfjs';
import helvetica from 'pdfjs/font/Helvetica';

export const get: APIRoute = async function get() {
  try {
    const doc = new pdf.Document({ font: helvetica, padding: 10 });
    const text = doc.text({ fontSize: 12 });
    text.add('サンプルPDF');
    const buffer = await doc.asBuffer();

    return new Response(buffer.toString(), {
      status: 200,
      headers: { 'content-type': `application/pdf` },
    });
  } catch (error: unknown) {
    return new Response(`pdf-resource.pdfルートで問題が発生しました!: ${error as string}`, {
      status: 501,
      statusText: 'サーバーエラー',
    });
  }
};

また、ここではリクエストごとにアウトプットをカスタマイズする自由があります。

🤖 静的サイトでのAstro JSONリソースルート

import type { APIRoute } from 'astro';

export const get: APIRoute = async function get() {
  try {
    const astroResources = [
      { name: 'ドキュメント', url: 'https://docs.astro.build/en/getting-started/' },
      { name: 'ディスコード', url: 'https://docs.astro.build/chat' },
    ];

    return { body: JSON.stringify(astroResources) };
  } catch (error) {
    throw new Error('json-resource.jsonルートで問題が発生しました!');
  }
};

ここではファイル内でJSONを構築します。静的サイトの場合、ビルドごとにカスタマイズできますが、要求ごとにカスタマイズするには完全なSSRに移行する必要があります。PDFルートの場合と同様に、SSRに移行すれば.json拡張子を省略できます(代わりにjson-resource.tsになります)。当然、content-typeヘッダも更新し、application/jsonにすることができます。

🙌🏽 Astro JSの非HTMLルート:まとめ

このAstro JS非HTMLルートの投稿では、APIルートからファイルやリソースを提供する方法を見てきました。特に、

  • 静的ファイルルートからPDFやJSONデータを配信する方法
  • SSR APIルートでPDFリソースを生成する例
  • これらの手法を避け、よりシンプルな方法にする時。

この投稿が役に立ったことを願っています!いつものように、レベルアップするためのたくさんの方法があります。静的またはSSR Astroサイト上でCSVファイルを生成するコードをアダプトすることができます。pdfjsを探索し、アプリに完全な機能のPDFを生成することもできます。次のレベルに進みたい場合は、例えばWebhookリスナーを追加するなどを検討してください。これは、サービスからのWebhookをリッスンし、別のサービス(例えば静的Astroサイトを再構築するなど)でWebhookをトリガーすることができます。また、Open Graphソーシャルシェア画像を生成することも考えられます。何を選ぶにせよ、完全なプロジェクトコードをRodney LabのGitHubページで見てみてください。皆さんのプロジェクトでのスターターの活用方法や、改善の可能性についても興味があります。

🙏🏽 Astro JS非HTMLルート:フィードバック

この投稿は役に立ちましたか?別のトピックについての投稿を見たいですか?新しい投稿のアイディアでご連絡ください。また、私の執筆スタイルが気に入った場合は、コンサルタントとして貴社のサイト用にいくつかの投稿を作成できるかどうかご連絡ください。以下で更に連絡する方法を見つけることができます。このような投稿を支持して数ドル、ユーロ、ポンドを割くことができれば、Buy me a Coffeeを通じて私を支えることを検討してください

最後に、投稿が役に立つと思うフォロワーのために、ソーシャルメディアアカウントで投稿を共有してください。コメントを残すだけでなく、Twitterで@askRodneyまたはTelegramでaskRodneyに連絡することもできます。またRodney Labへの連絡方法もご確認ください。私は定期的にAstroSvelteKitについて投稿しています。また、最新のプロジェクトの情報を得るためにニュースレターに登録してください

こちらの記事はdev.toの良い記事を日本人向けに翻訳しています。
https://dev.to/askrodney/astro-js-non-html-routes-file-resource-api-3jcj