Next.js+React-admin+PostgreSQLによる開発環境構築
はじめに
Next.js+React-admin+PostgreSQLで開発するための環境を構築する手順。
基本的にはReact-adminのチュートリアルをベースに進めていく。
Next.jsプロジェクト作成
まずはNext.jsのプロジェクトを作成。
>npx create-next-app@latest
※ 「Would you like to use App Router? (recommended)」について
「Pages Router」と「App Router」があるらしい。
今後は「App Router」がおすすめらしいので、今回は「App Router」を選択。
起動
npm run dev
で起動し、http://localhost:3000/
にアクセス。
とりあえず画面は開いた。
React-adminとの統合
react-adminをインストール。
最初のテスト用にra-data-json-serverを使用するので、これもいったんインストール。
>npm add react-admin ra-data-json-server
チュートリアルに従ってsrc/components/AdminApp.jsx
のファイルを追加し、src/app/page.tsx
のファイルの中身を書き換える。
画面を確認すると、React-adminの管理画面が表示される。
ここまではほぼチュートリアルの通り。
APIルーティング
「Pages Router」の場合はデフォルトで「pages/api」のフォルダが作成されており、ここにAPIを追加すればよかったのだが、「App Router」の場合は少し違うらしい。
詳細は、以下参照。
以下のように、api\hello\route.ts
のファイルを作成する。
http://localhost:3000/api/hello
でアクセスすると、APIからの応答が確認できる。
PostgreSQLとの接続
テスト用に、以下のようなテーブルとデータを作成する。
CREATE TABLE tests (id serial, name text, create_dt timestamptz, note text);
INSERT INTO tests (name, create_dt, note) VALUES ('test1', '2023/01/01','test1-note');
INSERT INTO tests (name, create_dt, note) VALUES ('test2', '2023/01/02','test2-note');
API側で、「pg」を使用してPostgreSQLのテストデータを取得する。
>npm i pg
import { NextResponse } from 'next/server'
const { Pool } = require('pg');
const pool = new Pool({
user: process.env.DB_USER || 'postgres',
password: process.env.DB_PASSWORD || 'postgres',
host: process.env.DB_HOST || 'localhost',
port: process.env.DB_PORT || 5432,
database: process.env.DB_NAME || 'postgres',
ssl: ((process.env.DB_SSL && process.env.DB_SSL.toLowerCase() == 'true') || false)
? { rejectUnauthorized: false } : false,
});
export async function GET() {
const client = await pool.connect();
const ret = await client.query('select * from tests', []);
await client.release(true);
console.log(ret);
return NextResponse.json(ret.rows)
}
http://localhost:3000/api/tests
でテストデータが取得できることを確認。
画面表示
以下を参考に、simpleRestProviderを使用したリスト表示に切り替える。
まずはra-data-simple-restをインストール。
>npm i ra-data-simple-rest
リスト表示の定義。
import { List, Datagrid, TextField, DateField } from 'react-admin';
export const TestList = () => (
<List>
<Datagrid>
<TextField source="id" />
<TextField source="name" />
<DateField source="create_dt" />
<TextField source="note" />
</Datagrid>
</List>
);
ra-data-json-serverを使用していたところを、ra-data-simple-restに切り替える。
"use client"; // only needed if you choose App Router
import { Admin, Resource, ListGuesser, EditGuesser } from "react-admin";
import jsonServerProvider from "ra-data-json-server";
import simpleRestProvider from 'ra-data-simple-rest';
import { TestList } from './Tests';
// const dataProvider = jsonServerProvider("https://jsonplaceholder.typicode.com");
const dataProvider = jsonServerProvider('http://localhost:3000/api/');
const AdminApp = () => (
<Admin dataProvider={dataProvider}>
<Resource name="tests" list={TestList} />
</Admin>
);
export default AdminApp;
画面を更新すると、以下のエラーが発生。
「X-Total-Count」のヘッダーが必要とのこと。
API側でセットする。
import { NextResponse } from 'next/server'
const { Pool } = require('pg');
const pool = new Pool({
user: process.env.DB_USER || 'postgres',
password: process.env.DB_PASSWORD || 'postgres',
host: process.env.DB_HOST || 'localhost',
port: process.env.DB_PORT || 5432,
database: process.env.DB_NAME || 'postgres',
ssl: ((process.env.DB_SSL && process.env.DB_SSL.toLowerCase() == 'true') || false)
? { rejectUnauthorized: false } : false,
});
export async function GET() {
const client = await pool.connect();
const ret = await client.query('select * from tests', []);
await client.release(true);
console.log(ret);
const headers = {
// "Access-Control-Allow-Origin": "*",
// "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
// "Access-Control-Allow-Headers": "Content-Type, Authorization",
"X-Total-Count": ret.rows.length,
};
return NextResponse.json(ret.rows, { status: 200, headers: headers })
}
※ 上記ではコメントアウトしているが、別オリジンからのアクセスの場合は"Access-Control-Allow-Origin"なども設定が必要になるはず。
画面表示すると、今度は成功。
まとめ
とりあえずはNext.js+React-adminの統合と、PostgreSQLデータの取得まで。
ソートやページング、追加更新削除などは未実装。。。
Discussion