API Platform Admin+Next

API Platform Adminは強力ながら、導入しようとすると問題も多くFixが大変。今回もNextで新規で立ち上げようとしたところ、Loading画面から進まないというストレスフルな現象が発生。

ということでベースはReact Adminにして、hydraDataProviderのみを使用する形にしてみる。

React Admin公式の解説をベースにする。

空のディレクトリから下記のコマンドを実行。

pnpm create next-app ./

プロンプトでいくつか質問されますが、必要に応じて自由に回答してください。このチュートリアルでは、src フォルダーを使用していることを前提としているため、5 番目の質問には Yes と答えます。App Router については、使用するかどうかを選択できますが、このチュートリアルでは、両方の使用方法について説明します。(新しいアプリケーションの場合、Next.js では App Router の使用を推奨しています)。

react-adminと@api-platform/adminをインストールする。

pnpm i react-admin @api-platform/admin

components/AdminApp.tsxを追加する。ポイントはhydraDataProviderはintrospectメソッドを実行しなければいけないということ。これを実行しないと、このissueにあるような問題がしてしまう。

import { hydraDataProvider } from "@api-platform/admin";
import { useEffect, useRef, useState } from "react";
import { Admin, Resource, ListGuesser, EditGuesser, DataProvider, Loading } from "react-admin";
import { inspect } from "util";

const ENTRYPOINT = "https://demo.api-platform.com"

const AdminApp = () => {

    const dataProvider = useRef<DataProvider>(undefined);
    const [introspect, setIntrospect] = useState(true);

    useEffect(() => {

        if(dataProvider.current !== undefined) return;

        dataProvider.current = hydraDataProvider({ entrypoint: ENTRYPOINT })
        dataProvider
        .current
        .introspect()
        .then(({}) => {
            setIntrospect(false);
        })
        .catch((err: any) => {
            console.error(err)
        });
    }, []);

    if (introspect) {
        return <Loading />
    }


    return (
        <Admin dataProvider={dataProvider.current}>
            <Resource
                name="books"
                list={ListGuesser}
                edit={EditGuesser}
            />
        </Admin>
    )
};

export default AdminApp;

app/page.tsxでAdminAppを呼び出す。

'use client'
import { NextPage } from "next";
import dynamic from "next/dynamic";
const AdminApp = dynamic(() => import("@/components/AdminApp"), { ssr: false });

const Home: NextPage = () => <AdminApp />;

export default Home;

あとはpnpm devpnpm buildなどを実行して動作確認。