前回=>vte.cxによるバックエンドを不要にする開発(5.データの一貫性)
今回はデータ登録における採番の方法について説明します。
自動採番
前回作成したホテル予約サイトでは、キー(link.___href)に、/hotel/101
や/hotel/102
といった値をセットしていましたが、これを省略することで自動採番とすることができます。以下のように実際にinitdataのエントリでlink項目を省略して実行してみましょう。
import * as React from 'react'
import * as ReactDOM from 'react-dom'
import { useState } from 'react'
import axios from 'axios'
const App = () => {
const [rooms, setRooms] = useState<VtecxApp.Entry[]>([])
const initdata: VtecxApp.Entry[] = [
{
room: {
name: '101',
reserved: false
} // link項目の省略
},
{
room: {
name: '102',
reserved: false
} // link項目の省略
}
]
const putrooms = async (req:VtecxApp.Entry[]) => {
try {
axios.defaults.headers['X-Requested-With'] = 'XMLHttpRequest'
await axios.put('/d/hotel',req)
getrooms()
} catch (e) {
alert('error:'+e)
}
}
const getrooms = async () => {
try {
axios.defaults.headers['X-Requested-With'] = 'XMLHttpRequest'
const res = await axios.get('/d/hotel?f')
setRooms(res.data)
} catch (e) {
alert('error')
console.log(e)
}
}
const showrooms = () => {
return rooms.map((entry,index) => {
if (entry.room&&!entry.room.reserved) {
return (
<div key={index}>
<p>{entry.room.name}
<button
onClick={() => {
reserve(entry)
}}
>
予約
</button>
</p>
</div>
)
}
})
}
const reserve = async (entry:VtecxApp.Entry) =>{
if (entry.room) {
entry.room.reserved = true
putrooms([entry])
}
}
return (
<div>
<button onClick={() => { putrooms(initdata) }}>
初期化
</button>
<button onClick={() => { getrooms() }}>
一覧
</button>
<br/>
{showrooms()}
</div>
)
}
ReactDOM.render(<App/>, document.getElementById('container'))
これらの項目を、エンドポイント/d/hotel
に対してPUTすると、その配下にエントリが登録され、キーが/hotel/1
というように自動的に番号が採番されます。
採番カウンタを利用して独自の採番を行う
自動採番ではなく、ホテルの部屋番号101,102のようにユーザが決めた値で採番したい場合もあるでしょう。その場合は、採番カウンタ機能を利用します。_setids
で採番カウンタの設定が行え、_addids
で採番カウンタの加算が行えます。
例えば、以下のサンプルのように、PUT /d/hotel?_setids=100
とすると、/hotelをキーとする採番カウンタは100になります。また、PUT /d/hotel?_addids=1
で101にカウントアップされます。(採番カウンタはキーごとに管理されます。ここでは/hotelがキー)
採番に関する詳しい説明は、ドキュメントを参照してください。
import * as React from 'react'
import * as ReactDOM from 'react-dom'
import { useState } from 'react'
import axios from 'axios'
const App = () => {
const [rooms, setRooms] = useState<VtecxApp.Entry[]>([])
const initrooms = async () => {
try {
// 採番の初期値を設定
axios.defaults.headers['X-Requested-With'] = 'XMLHttpRequest'
await axios.put('/d/hotel?_setids=100')
} catch(e) {
alert('error:'+e)
}
const req : VtecxApp.Entry[] = []
for (let i = 0; i < 5; i++) {
try {
// カウントアップしてエントリにセット
axios.defaults.headers['X-Requested-With'] = 'XMLHttpRequest'
const res = await axios.put('/d/hotel?_addids=1')
const entry : VtecxApp.Entry = {}
entry.room = {
name : res.data.feed.title,
reserved: false
}
entry.link = [{
___href : '/hotel/'+res.data.feed.title,
___rel : 'self'
}]
req.push(entry)
} catch(e) {
alert('error:'+e)
}
}
// エントリをまとめて更新
putrooms(req)
}
const putrooms = async (req:VtecxApp.Entry[]) => {
try {
axios.defaults.headers['X-Requested-With'] = 'XMLHttpRequest'
await axios.put('/d/hotel',req)
getrooms()
} catch (e) {
alert('error:'+e)
}
}
const getrooms = async () => {
try {
axios.defaults.headers['X-Requested-With'] = 'XMLHttpRequest'
const res = await axios.get('/d/hotel?f')
setRooms(res.data)
} catch (e) {
alert('error')
console.log(e)
}
}
const showrooms = () => {
return rooms.map((entry,index) => {
if (entry.room&&!entry.room.reserved) {
return (
<div key={index}>
<p>{entry.room.name}
<button
onClick={() => {
reserve(entry)
}}
>
予約
</button>
</p>
</div>
)
}
})
}
const reserve = async (entry:VtecxApp.Entry) =>{
if (entry.room) {
entry.room.reserved = true
putrooms([entry])
}
}
return (
<div>
<button onClick={() => { initrooms() }}>
初期化
</button>
<button onClick={() => { getrooms() }}>
一覧
</button>
<br/>
{showrooms()}
</div>
)
}
ReactDOM.render(<App/>, document.getElementById('container'))
上記コードを実行して初期化ボタンを押すと5件のroomが表示されるかと思います。
それでは、今日はここまでです。
お疲れさまでした。