前置き
去年のアドベントカレンダーで、以下にような投稿をしています。
PleasanterのAPI関連メソッドを使いやすくしたい。
PleasanterのAPIはそのままだと、なかなか使い勝手が悪い、だからクラスにまとめよう、というお話でした。
今回はその続き、実際に構築したクラスを利用し、Next.jsからAPIを使ってみようと思います。
環境
主な環境は以下のとおり
- next: 14.1.0
- react: 18
- tailwindcss: 3.3.0
作るもののイメージ
Next.js
単純にPleasanterのデータを画面に表示するだけです。
Pleasanter
こっちもほぼプレーンの状態です。
ソースコード
Git
以下を参照してください。
構成
Next.jsの構成は以下の通り
app
├components
│└PleasanerItem.tsx /Pleasaterの1レコード分を描画するコンポーネント
├lib
│└pleasanterClient.ts /API接続用
└page.tsx /メイン
環境変数
.envファイルを用意して、PleasanterのAPIキーとURLを設定します。
NEXT_PUBLIC_PLEASANTER_APY_KEY=XXXXXXXXXXXXXXXXXXXXXX
NEXT_PUBLIC_PLEASANTER_URL=http://XXXXXXX/
その上で、npm run dev で動くはず。
ソース解説
pleasanterClient.ts
こちらは、以前の記事を参照してください。完全に外部から呼び出すので、Pleasanterのサーバスクリプト、スクリプトのメソッドなんかは、ザクっと削除しています。
page.tsx
import {
ApiColumnKeyDisplayType,
ApiDataType,
PleasanterApiClient,
View,
} from "./lib/pleasanterClient";
import PleasanterItem from "./components/PleasanterItem";
const columns = ["IssueId", "Title", "Body", "Owner", "Status"];
const siteId = 11114883;
const getPleasanterRecords = async () => {
try {
let view = new View({});
let gridColumnHash = columns;
view.setGridColumnsByArray({ value: gridColumnHash });
let filterStatus = ["200"];
view.setColumnFilterHash({
key: "Status",
value: JSON.stringify(filterStatus),
});
view.ApiDataType = ApiDataType.KeyValues;
view.ApiColumnKeyDisplayType = ApiColumnKeyDisplayType.ColumnName;
view.ApiKey = process.env.NEXT_PUBLIC_PLEASANTER_APY_KEY;
view.ApiVersion = 1.1;
let res = await PleasanterApiClient.apiGet({
id: siteId,
view: view,
url: process.env.NEXT_PUBLIC_PLEASANTER_URL!,
});
return res;
} catch (err) {
console.log(err);
}
};
async function Home() {
let res = await getPleasanterRecords();
let rowItems: any[];
rowItems = res.Response.Data;
return (
<>
<div className=" py-8 px-8">
<h1 className=" text-6xl">Home</h1>
<div className=" flex">
{rowItems.map((rowItem) => (
<div key={rowItem.IssueId}>
<PleasanterItem
rowItem={rowItem}
columns={columns}
/>
</div>
))}
</div>
</div>
</>
);
}
export default Home;
少し具体的に説明
const columns = ["IssueId", "Title", "Body", "Owner", "Status"];
Pleasanterから取得したい項目を配列で指定します。後続のview生成時やcomponentで画面描画する時に利用します。
const getPleasanterRecords = async () => {
//~~省略~~
};
PleasnaterへのAPIリクエストViewを生成、pleasanterClientを呼び出します。Viewの使い方などは過去記事を参照ください。
async function Home() {
let res = await getPleasanterRecords();
let rowItems: any[];
rowItems = res.Response.Data;
return (
<>
<div className=" py-8 px-8">
<h1 className=" text-6xl">Home</h1>
<div className=" flex">
{rowItems.map((rowItem) => (
<div key={rowItem.IssueId}>
<PleasanterItem
rowItem={rowItem}
columns={columns}
/>
</div>
))}
</div>
</div>
</>
);
}
export default Home;
pleasnaterClietnからのレスポンスを受け取り、mapで展開しつつPleasanterItemコンポーネントへ受け渡します。
PleasanterItem.tsx
import React from "react";
type props = {
rowItem: any;
columns: string[];
};
const PleasanterItem = ({ rowItem, columns }: props) => {
return (
<>
<div className="">
<div className=" m-3 p-2 border w-auto">
{columns.map((column) => (
<p key={column} className=" text-3xl text-cyan-600">
{column} = {rowItem[column]}
</p>
))}
</div>
</div>
</>
);
};
export default PleasanterItem;
難しいことはしておらず、受け取ったレコードデータ(rowItem)から、colmunsに設定されたPleasnater項目ごと展開し、画面描画しています。
おわりに
最終的には、
npm i pleasanterClient
なんて、npmに登録できたらいいなぁ、などと思いつつ今回はここまでです。