Open Libertyの公式ページにある以下サンプルを使用して、Webアプリを作成してみましょう。
https://openliberty.io/guides/rest-client-reactjs.html
Open Libertyってなに?
- 高速で効率的なクラウドネイティブJavaマイクロサービスを構築するための軽量なオープンフレームワークです。
- 要するにJava製のアプリケーションサーバーです。
- Open Liberty 公式ページ:https://openliberty.io/
環境
- Windows11 + WSL2(Ubuntu 20.04.5)
- Mavenインストール済み
- ブラウザはEdge
- node v16.13.2
- openjdk 17.0.8
リポジトリのクローンと完成品の確認
リポジトリをクローンし、ディレクトリを移動します。
git clone https://github.com/openliberty/guide-rest-client-reactjs.git
cd guide-rest-client-reactjs
中にはfinishとstartという2つのディレクトリが含まれており、finishの方にサンプルの完成品が格納されています。
finishディレクトリに移動し、完成品を確認してみましょう。
cd finish
mvn liberty:run
ブラウザでhttp://localhost:9080/
を開くと、以下のような画面を見ることができます。
未完成のWebアプリを実行してみる
startディレクトリに移動し、mvn liberty:dev
コマンドを実行してみます。今回はブラウザでhttp://localhost:9080/
を開いても真っ白なページしか表示されません。http://localhost:9080/artists
にアクセスすると、jsonが返却されます。
http://localhost:9080/artists
からjsonデータを受け取り、Reactで表示できるようにする必要がありそうです。
React部分の実装
まず、index.js
を作成します。このファイルはreactアプリのエントリーポイントになります。
import React from 'react';
import ReactDOM from 'react-dom';
import './Styles/index.css';
import App from './Components/App';
ReactDOM.render(<App />, document.getElementById('root'));
さらに、以下のようにApp.js
ファイルを作成します。
import React from 'react';
import {ArtistTable} from './ArtistTable';
function App() {
return (
<ArtistTable/>
);
}
export default App;
ArtistTable.js
を作成します。このコンポーネントでテーブルを作成します。
import React, { useEffect, useMemo, useState } from 'react';
import { useTable, usePagination, useSortBy } from 'react-table';
import '../Styles/table.css'
export function ArtistTable() {
const [posts, setPosts] = useState([]);
const data = useMemo(() => [...posts], [posts]);
const columns = useMemo(() => [{
Header: 'Artist Info',
columns: [
{
Header: 'Artist ID',
accessor: 'id'
},
{
Header: 'Artist Name',
accessor: 'name'
},
{
Header: 'Genres',
accessor: 'genres',
}
]
},
{
Header: 'Albums',
columns: [
{
Header: 'Number of Tracks',
accessor: 'ntracks',
},
{
Header: 'Title',
accessor: 'title',
}
]
}
], []
);
const tableInstance = useTable(
{
columns,
data,
initialState: { pageIndex: 0, pageSize: 4 }
},
useSortBy,
usePagination
)
const {
getTableProps,
getTableBodyProps,
headerGroups,
prepareRow,
page,
canPreviousPage,
canNextPage,
pageOptions,
pageCount,
gotoPage,
nextPage,
previousPage,
setPageSize,
state: { pageIndex, pageSize }
} = tableInstance;
return (
<>
<h2>Artist Web Service</h2>
<table {...getTableProps()}>
<thead>
{headerGroups.map(headerGroup => (
<tr {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map((column) => (
<th {...column.getHeaderProps(column.getSortByToggleProps())}>
{column.render('Header')}
<span>
{column.isSorted
? column.isSortedDesc
? ' 🔽'
: ' 🔼'
: ''}
</span>
</th>
))}
</tr>
))}
</thead>
<tbody {...getTableBodyProps()}>
{page.map((row, i) => {
prepareRow(row)
return (
<tr {...row.getRowProps()}>
{row.cells.map(cell => {
return <td {...cell.getCellProps()}>{cell.render('Cell')}</td>
})}
</tr>
)
})}
</tbody>
</table>
<div className="pagination">
<button onClick={() => previousPage()} disabled={!canPreviousPage}>
{'Previous'}
</button>{' '}
<div class="page-info">
<span>
Page{' '}
<strong>
{pageIndex + 1} of {pageOptions.length}
</strong>{' '}
</span>
<span>
| Go to page:{' '}
<input
type="number"
defaultValue={pageIndex + 1}
onChange={e => {
const page = e.target.value ? Number(e.target.value) - 1 : 0
gotoPage(page)
}}
style={{ width: '100px' }}
/>
</span>{' '}
<select
value={pageSize}
onChange={e => {
setPageSize(Number(e.target.value))
}}
>
{[4, 5, 6, 9].map(pageSize => (
<option key={pageSize} value={pageSize}>
Show {pageSize}
</option>
))}
</select>
</div>
<button onClick={() => nextPage()} disabled={!canNextPage}>
{'Next'}
</button>{' '}
</div>
</>
);
}
上記のままでは、jsonデータを受け取ることができません。そこで、以下のようにaxios
のインポートとGetArtistsInfo
関数を追加します。GetArtistsInfo
関数では、axiosでhttp://localhost:9080/artists
からデータを受け取っています。
import React, { useEffect, useMemo, useState } from 'react';
import axios from 'axios';
import { useTable, usePagination, useSortBy } from 'react-table';
import '../Styles/table.css'
export function ArtistTable() {
const [posts, setPosts] = useState([]);
const GetArtistsInfo = async () => {
const response = await axios.get('http://localhost:9080/artists')
.then(response => {
const artists = response.data;
for (const artist of artists) {
const { albums, ...rest } = artist;
for (const album of albums) {
setPosts([...posts, { ...rest, ...album }]);
posts.push({ ...rest, ...album });
}
};
}).catch(error => { console.log(error); });
};
const data = useMemo(() => [...posts], [posts]);
const columns = useMemo(() => [{
Header: 'Artist Info',
columns: [
{
Header: 'Artist ID',
accessor: 'id'
},
// 以下省略・・・・・
以上がすべて終わったら、startディレクトリに戻り、以下コマンドを実行します。このコマンドでビルドが走ります。
mvn process-resources
http://localhost:9080 にアクセスしてみましょう。以下のような画面が表示されます。
まとめ
Open LibertyとReactを利用して、簡単なWebサービスを実装できました。みなさんも試してみてください!