Goal
WebAPI開発ぽいものをblocklyで実現する
Reference
前回記事を見てね
Specification
こんな感じのプログラムをblocklyで実現できるようにするよ
post(req, res) {
var item = itemDao.fetchById(req.body.id);
if(item === null || item.delete_flag) {
let error = new Error(404, 'Not Found');
res.send(error);
}
let resData = itemDao.update(req.body);
res.send(resData);
}
ブロック作り
Blockly Developer Toolsなるものもありますが、いまいち使いづらいので普通にコード書きます。
以下のブロックを作ります。
- item_findById: アイテムを検索するDAO
- item_update: アイテムを更新するDAO
- item_obj: アイテムオブジェクト
- req_body: リクエストのBody
- req_body_sel: リクエストのBodyから要素を取り出す
- res_send: レスポンスを送る
- res_error: エラーレスポンスを作成
そもそも、blocklyでオブジェクト指向は難しいです。
オブジェクトのメソッドとかフィールドにアクセスする直感的な表現ができるといいんですが。。。
Overall
とりあえず作ってみた。
ファイル構造は前回記事のとおりです。
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>blockly test</title>
</head>
<body>
<div id="blocklyDiv" style="height: 480px; width: 800px;"></div>
<xml id="toolbox" style="display: none">
<category name="Control" colour="210">
<block type="controls_if"></block>
<block type="logic_compare"></block>
<block type="logic_operation"></block>
</category>
<category name="Math" colour="230">
<block type="math_number"></block>
</category>
<category name="Request" colour="65">
<block type="req_body"></block>
<block type="req_body_sel"></block>
</category>
<category name="Response" colour="290">
<block type="res_send"></block>
<block type="res_error"></block>
</category>
<category name="Item" colour="200">
<block type="item_findById"></block>
<block type="item_update"></block>
<block type="item_obj"></block>
</category>
<category name="Text" colour="230">
<block type="text"></block>
</category>
<category name="Variables" colour="330" custom="VARIABLE">
</category>
</xml>
<script src="js/blockly_compressed.js"></script>
<script src="js/blocks_compressed.js"></script>
<script src="js/msg/js/ja.js"></script>
<script>
var workspace = Blockly.inject('blocklyDiv', {
toolbox: document.getElementById('toolbox'),
media: 'media/'
});
Blockly.Blocks['item_findById'] = {
init: function () {
this.appendValueInput('VALUE')
.setCheck('String')
.appendField('find by id:');
this.setOutput(true, 'Item');
this.setColour(160);
this.setTooltip('Returns Item of the provided id.');
}
};
Blockly.Blocks['item_update'] = {
init: function () {
this.appendValueInput('VALUE')
.setCheck('Item')
.appendField('update item:');
this.setOutput(true, 'Item');
this.setColour(160);
this.setTooltip('Returns Item of update result.');
}
};
Blockly.Blocks['item_obj'] = {
init: function () {
this.appendDummyInput()
.appendField('item:')
.appendField(new Blockly.FieldDropdown([
['id', 'id'],
['delete_flag', 'delete_flag'],
['name', 'name']
]),
'FIELDNAME');
this.setOutput(true);
this.setColour(160);
}
};
Blockly.Blocks['req_body'] = {
init: function () {
this.appendDummyInput()
.appendField('req body.')
this.setOutput(true, 'Item');
this.setColour(65);
this.setTooltip('Returns Request Body.');
}
};
Blockly.Blocks['req_body_sel'] = {
init: function () {
this.appendValueInput("Request");
// inputをブロックの中に設定するよ
this.setInputsInline(true);
this.appendDummyInput()
.appendField(new Blockly.FieldDropdown([
['id', 'id'],
['name', 'name']
]),
'FIELDNAME');
this.setOutput(true, 'String');
this.setColour(65);
}
};
Blockly.Blocks['res_send'] = {
init: function () {
this.appendValueInput('VALUE')
.appendField('send response:');
this.setColour(290);
this.setPreviousStatement(true, 'Action');
}
};
Blockly.Blocks['res_error'] = {
init: function () {
this.appendDummyInput()
.appendField('create error obj');
this.appendValueInput('VALUE')
.setCheck('Number')
.appendField('error code:');
this.appendValueInput('VALUE')
.setCheck('String')
.appendField('error msg:');
this.setOutput(true, 'Number');
this.setColour(160);
this.setTooltip('Returns Error Response object.');
}
};
</script>
</body>
</html>
結果はこんな感じ