Edited at

vte.cxによるバックエンドを不要にする開発(6.採番)

前回=>vte.cxによるバックエンドを不要にする開発(5.データの一貫性)

今回はデータ登録における採番の方法について説明します。


自動採番

前回作成したホテル予約サイトでは、キー(link.___href)に、/hotel/101/hotel/102といった値をセットしていましたが、これを省略することで自動採番とすることができます。以下のように実際にinitdataのエントリでlink項目を省略して実行してみましょう。


index.tsx

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というように自動的に番号が採番されます。

スクリーンショット 2019-09-10 14.57.44.png


採番カウンタを利用して独自の採番を行う

自動採番ではなく、ホテルの部屋番号101,102のようにユーザが決めた値で採番したい場合もあるでしょう。その場合は、採番カウンタ機能を利用します。_setidsで採番カウンタの設定が行え、_addidsで採番カウンタの加算が行えます。

例えば、以下のサンプルのように、PUT /d/hotel?_setids=100とすると、/hotelをキーとする採番カウンタは100になります。また、PUT /d/hotel?_addids=1で101にカウントアップされます。(採番カウンタはキーごとに管理されます。ここでは/hotelがキー)

採番に関する詳しい説明は、ドキュメントを参照してください。


index.tsx

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が表示されるかと思います。

それでは、今日はここまでです。

お疲れさまでした。

次回=>vte.cxによるバックエンドを不要にする開発(7.サーバサイドJavaScript)