Freshでapiフォルダとutilsフォルダの使い分け
作成日
更新日
FreshにはDeno Fresh CRUD API機能がある。
api
フォルダutils
もしくはlibs
と名づけることが多そう?なフォルダ。
例えば getPosts
という関数はどちらに配置すべきなのか。
api
に配置した場合
これはクライアント側で呼び出される。 例えば、次のようなSupabaseから記事を取得するコードの場合。
api/getPosts.ts
import { Handlers } from "$fresh/server.ts";
import { supabase } from "../../utils/supabase.ts";
interface Post {
title: string;
slug: string;
created_at: string;
}
export const handler: Handlers = {
async GET(_req, ctx) {
const { data, error } = await supabase
.from("articles")
.select("title, slug, created_at")
.eq("category", "post")
.eq("private", false)
.order("created_at", { ascending: false });
if (error || !data) return new Response(JSON.stringify([]), { status: 500 });
return new Response(JSON.stringify(data), {
headers: { "Content-Type": "application/json" },
});
},
};
これはislandから次のように呼び出す。
export default function Sidebar() {
const [posts, setPosts] = useState<Post[]>({});
useEffect(() => {
async function fetchPosts() {
try {
const res = await fetch("/api/getPosts");
const data = await res.json();
setPosts(data);
} catch (error) {
console.error("Failed to fetch posts:", error);
}
}
fetchPosts();
}, []);
return (
<>
/*postsを表示する*/
</>
)
}
これは、useEffectを使ってクライアント側で処理がされる。
utils
に配置した場合
サーバー側で呼び出される。
同様にSupabaseから記事を取得するコード。
utils/getPosts.ts
import { supabase } from "./supabase.ts";
import { Post } from "../types/post.ts";
export async function getPosts(): Promise<Post[]> {
const { data, error } = await supabase
.from("articles")
.select("title, slug, created_at")
.eq("private", false)
.order("created_at", { ascending: false });
if (error || !data) {
console.log(error);
return [];
}
return data;
}
これは通常のコンポーネントから props を通して呼び出す。
index.tsx
interface HomeData {
posts: Post[];
}
export const handler: Handlers<HomeData> = {
async GET(_req, ctx) {
// すべての記事を取得
const allPosts = await getPosts() ?? [];
return ctx.render({
posts: allPosts,
});
},
};
export default function Home(props: PageProps<HomeData>) {
const { posts } = props.data;
return (
<>
/*postsを表示する*/
</>
)
}
この方法はSSRになる。
まとめ
api
に配置した場合は クライアントサイドレンダリングutils
に配置した場合はサーバーサイドレンダリング
自分なりの結論として、全ての記事を取得するような時はSSR、画像などを遅延読み込みする時はクライアントサイドの方が良いという認識をした。

公開日
更新日