BlocklyでWebAPIぽいものを作る

# Goal
WebAPI開発ぽいものをblocklyで実現する

# Reference
前回記事を見てね

# Specification

こんな感じのプログラムをblocklyで実現できるようにするよ

```js
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](https://blockly-demo.appspot.com/static/demos/blockfactory/index.html)なるものもありますが、いまいち使いづらいので普通にコード書きます。
以下のブロックを作ります。

- item_findById: アイテムを検索するDAO
- item_update: アイテムを更新するDAO
- item_obj: アイテムオブジェクト
- req_body: リクエストのBody
- req_body_sel: リクエストのBodyから要素を取り出す
- res_send: レスポンスを送る
- res_error: エラーレスポンスを作成

そもそも、blocklyでオブジェクト指向は難しいです。　
オブジェクトのメソッドとかフィールドにアクセスする直感的な表現ができるといいんですが。。。

# Overall

とりあえず作ってみた。
ファイル構造は前回記事のとおりです。

```html: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>
```
結果はこんな感じ

![img.png](https://qiita-image-store.s3.amazonaws.com/0/150289/a7270a24-98d5-f001-3138-61aa6f5010b6.png)