最近、AWS関連の記事8月5日、8月12日、8月18日を書いているのはバックエンドの開発を行っているからです。バックエンドはフロントエンドにAPIを提供するのが一番の目的ですが、管理画面も重要な機能だと思います。
管理画面といえば業務フローをサポートするための画面もありますが、ここではデータの確認や簡単な修正、いわゆるデーターベースのCRUD画面(Create, Read, Update, Delete)に付いての書きます。
React-admin、PostGraphileとは
CRUD画面を簡単に作成できるツールやライブライリーは多く存在します。たとえばRuby on RailsにはRailsAdminのような有名なライブラリーがあります。
今回の仕事の参加する開発者はReactプログラマーなので、管理画面もReactベースのものが良いと思います。Reactベースの管理画面ライブライリーも多数ありますが、ReactAdminが良く使われているようです。
React-admin
ReactAdminはチュートリアルのMapping API Endpoints With Resourcesにあるように簡単なコードでCRUD画面が作れます。また画面をカスタマイズする場合はReactコンポーネントとして作るので将来の拡張もやりやすそうです。
さらにReactAdminはサーバーとの接続部分がData Providersとして分離されていて、RestAPI, GraphQLをはじめFirebase用など、たくさんのプロバイダーがすでに在ります。
PostGraphile
今回のシステムはRDBにはPostgreSQLを使います、いろいろと検索していたらPostGraphileというものを見つけました!
PostGraphileはメカニカル(メタリック)な像がアイコンになっています、ご存じなようにPostgreSQLのアイコンは象です。このメカ像は、PostgreSQLデータの問合せ・変更できるGraphQLサーバーが簡単に作れる素晴らしいソフトウェアです。
PostGraphileはスタンドアロンでも使えますが、Express等に組み込めるライブライリーとしても使えます。PostGraphileを起動すると組み込まれているGraphQLのWebクライアントGraphiQLを使ってPostgreSQLのテーブルがGraphQLで問合せ・変更(query・mutation)を試せます。
また、React-adminにはPostGraphileに接続する専用プロバイダーra-postgraphileがあります。
React-admin、PostGraphileを試してみた
PostgreSQL、PostGraphileを使ったExpressサーバー、React-admin用React環境をDocker Desktop for Mac上に作り試してみました。ここから色々な問題にぶち当たります😅。
1. ra-postgraphileのサンプルコードが動かない
React-adminra-postgraphileページに簡単なサンプルコードがあるので、これを参考に管理画面のコードを書きましたがエラーになってしまいました。Apollo Clientを使っていますがコードが古いのかもしれません。いろいろと調べ以下のようなコードで動きました(as any
がまだ解決できていませんね)。
import { useEffect, useState } from 'react'
import { Admin, Resource, ListGuesser, ShowGuesser, EditGuesser, LegacyDataProvider,
List, Datagrid, TextField, DateField, EmailField, ReferenceField,
EditButton, ResourceProps, ResourceComponentProps } from 'react-admin';
import { ApolloProvider, useApolloClient } from '@apollo/react-hooks'
import pgDataProvider from 'ra-postgraphile'
import { ApolloClient, InMemoryCache } from '@apollo/client'
const ReacTAdmin = () => {
const [dataProvider, setDataProvider] = useState<LegacyDataProvider|null>(null)
const client = useApolloClient()
useEffect(() => {
(async () => {
const dataProvider = await pgDataProvider(client as any) // TODO fix any
setDataProvider(() => dataProvider)
})()
}, [client])
return (
dataProvider && (
<Admin dataProvider={dataProvider}>
<Resource name="users" list={ListGuesser} show={ShowGuesser} edit={EditGuesser}/>
</Admin>)
)
}
export const App = () => {
const apolloClient = new ApolloClient({
uri: `http://localhost:5000/graphql`,
cache: new InMemoryCache()})
return (
<ApolloProvider client={apolloClient}>
<ReacTAdmin />
</ApolloProvider>
)
}
2. Cannot query field “users” on type “Query”. Did you mean “user” …
React-adminとPostGraphileが接続できるようになりましたが、React-adminのコンソールにCannot query field "users" on type "Query". Did you mean "user", "allUsers", or "query"?
というエラーが表示されました。
上のコードの<Resource name="users" ...
のusers
がいけないようです、試しに<Resource name="allUsers" ...
と変更したところエラーは発生しなくなりましたが何も表示されませんでした。
いろいろ調べましたが解決しません。😅😅😅
しかし、React-Admin and Postgraphile playgroundというReact-admin + ra-postgraphile + PostGraphileを使ったサンプルコードがGitHubにありました。早速git clone
して動かしてみました(Docker化されているので直ぐに動きました)。なんと同じDBを使ってもGraphiQLの左側に表示されているスキーマ一覧が違います。
私のPostGraphileサーバー | stephane-kleinさんのサンプル |
---|---|
AllGroups | groups |
AllUsers | users |
group | |
groupById | group |
user | |
userById | user |
PostGraphileの設定が違うようです、stephane-kleinさんのサンプルコードを読んでみるとPostGraphileに PgSimplifyInflectorPluginというプラグインが使われています。私のPostGraphileサーバーにもこのプラグインを追加したところ同じスキーマ一覧になりました!
ra-postgraphileページをよく見るとLimitationsのところにPgSimplifyInflectorPlugin,PgConnectionFilterPluginを入れている環境でテストしていると書かれていました。😅
3. Error: You must declare a <Resource name=“nodes”> in order to use…
しかし、Error: You must declare a <Resource name="nodes"> in order to use a <ReferenceField reference="nodes"><ReferenceField source="nodeId" reference="nodes"><TextField source="id" /></ReferenceField>
というエラーが発生します。
ここに出てくるnodeIdは上のGraphiQL画像に表示されていますが、query結果のオブジェクトに付いているユニークなIDです。これはFacebbokが作ったGraphQLクライアントライブライリーRelayで導入されたものです、クライアント側でデータをキャッシュするのに役立つIDです。詳細はこちら
しかし、stephane-kleinさんのサンプルではnodeIdは使われていませんでした。コードを見るとskipPlugins: [NodePlugin]
でnodeId機能をスキップしていました。この設定を入れてやっとReact-adminの画面にusersテーブルの内容が表示されました! 👏
もちろん、変更等も動作しました 👏👏
まとめ
React-admin + PostGraphileで、(半日くらい悩みましたが)比較的簡単に管理画面ができました。
ただし色々な問題を解決できたのは、Stéphane Kleinが作られたReact-Admin and Postgraphile playgroundのおかげです。
Stéphane Kleinさん、ありがとうございます!!