Astro ビルトインAPIエンドポイントの使い方
静的サイトジェネレーターの Astro はエンドポイントを作成できるビルトイン機能を提供しています。
アストロの公式ドキュメントによると:
Astro lets you create custom endpoints to serve any kind of data. You can use this to generate images, expose an RSS document, or use them as API Routes to build a full API for your site.
SSGでもSSRモードでも利用できますが、挙動に違いがあります。
SSG
- ビルド時に1度だけ実行され、デプロイ後は実行されない
- 用途例: ブログ記事や商品カタログ、サイトマップ生成 など
SSR
- サーバー側でリクエストの度に実行される
- 用途例: 動的OG画像生成、外部API取得、認証 など
なぜビルトイン API エンドポイントを使うのか
- CORS問題: サーバー側でリクエストする場合はブラウザのCORS問題を回避できる
- セキュリティ面: APIキーなどを秘匿することができる
- パフォーマンス面: 初期表示の高速化、サーバー側のキャッシュ利用やサーバー負担減
- SEO: サーバー側でレンダリングされるためクローラーがコンテンツを認識できる
- コード: バックエンドを別途たてる必要がない
実装
エンドポイントは、.js または .ts ファイルを src/pages 配下に追加することで作成できます(例: src/pages/data.json.ts というファイルは /data.json というエンドポイントとして生成されます)。 ファイルに GET or POST などが export されていることでエンドポイントとして認識されます。
管理しやすいように src/pages に api というフォルダを作成してまとめることも可能です。
基本の書き方
src/pages/api/index.ts を作成して以下のようなコードを書きます。 npm run dev を実行してブラウザで http://localhost:4321/api にアクセスすると "Hello, Astro Endpoints 🚀" というテキストが表示されます。
import type { APIRoute } from "astro"
export const GET: APIRoute = () => {
return new Response("Hello, Astro Endpoints 🚀", { status: 200 })
}

外部APIを fetch して取得する
映画の情報を提供する TMDB API を使用して最新の上映中の映画リストを取得する例です。
-
.envファイルを作成
アクセスにAPIキーが必要な場合は.envファイルを作成します。
TMDB_API_ACCESS_TOKEN=YOUR_API_TOKEN
- エンドポイント作成
Astro プロジェクトでは import.meta.env.VARIABLE_NAME で環境変数にアクセスすることができます。
基本の書き方の中身を以下のように変更して、映画情報を fetch します。
import type { APIRoute } from "astro"
const options = {
method: "GET",
headers: {
accept: "application/json",
Authorization: `Bearer ${import.meta.env.TMDB_API_ACCESS_TOKEN}`,
},
};
export const GET: APIRoute = async () => {
try {
const response = await fetch("https://api.themoviedb.org/3/movie/now_playing?language=en-US&page=1", options);
if(!response.ok) {
throw new Error("Fetch faild");
}
const json = await response.json();
const data = json.results;
return new Response(JSON.stringify(data), {
status: 200,
headers: {
"Content-Type": "application/json",
},
});
} catch(error) {
return new Response(JSON.stringify([]), {
status: 500,
headers: {
"Content-Type": "application/json",
},
});
}
}
npm run dev を実行してブラウザで http://localhost:4321/api/tmdb にアクセスすると以下のようなリストが確認できます。

- フロントでの表示
Astro エンドポイントはどのAstroページからでも呼び出し可能です。
先ほど作成したエンドポイントにアクセスして映画のタイトルと概要を表示する例です。
---
import { GET as getMovies } from './api/tmdb.ts';
let response = await getMovies(Astro);
const movies = await response.json();
---
<div>
{movies.map((m: any) => (
<>
<p>{m.title}</p>
<p>{m.overview}</p>
</>
))}
</div>
プロジェクト内の特定のページでのみSSRモードでAPI エンドポイントにアクセスしたい場合は、次の1行を .astro ファイルの先頭に追加します。
---
export const prerender = false;
---
この設定により、このページはSSRモードでレンダリングされるようになります。
Discussion