// JSONスキーマの例
{
"type": "object",
"properties": {
"kind": { "type": "string" },
"price": { "type": "number" },
"origin": { "type": "string" }
},
"required": ["kind", "price"]
}
📋 サンプルフロー(クリックで展開)
参照元:Node-REDエディター内サンプルフロー
[
{
"id": "e95345f3e4e33dbe",
"type": "tab",
"label": "json",
"disabled": false,
"info": "",
"env": []
},
{
"id": "9976e95d.2f8398",
"type": "inject",
"z": "e95345f3e4e33dbe",
"name": "",
"props": [{"p": "payload"}, {"p": "topic", "vt": "str"}],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 260,
"y": 160,
"wires": [["d94fc083.49d87"]]
},
{
"id": "6684abb1.8eb454",
"type": "comment",
"z": "e95345f3e4e33dbe",
"name": "Example 1: Convert JSON string to JS object",
"info": "",
"x": 320,
"y": 100,
"wires": []
},
{
"id": "d94fc083.49d87",
"type": "template",
"z": "e95345f3e4e33dbe",
"name": "JSON string",
"field": "payload",
"fieldType": "msg",
"format": "json",
"syntax": "plain",
"template": "{\n \"kind\": \"Apple\",\n \"price\": 100,\n \"origin\": \"Canada\"\n}",
"output": "str",
"x": 430,
"y": 160,
"wires": [["1a3dc54a.78598b"]]
},
{
"id": "8950a55d.023988",
"type": "debug",
"z": "e95345f3e4e33dbe",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"statusVal": "",
"statusType": "auto",
"x": 750,
"y": 160,
"wires": []
},
{
"id": "1a3dc54a.78598b",
"type": "json",
"z": "e95345f3e4e33dbe",
"name": "",
"property": "payload",
"action": "",
"pretty": false,
"x": 590,
"y": 160,
"wires": [["8950a55d.023988"]]
},
{
"id": "cb13761f.56c328",
"type": "inject",
"z": "e95345f3e4e33dbe",
"name": "",
"props": [{"p": "payload"}, {"p": "topic", "vt": "str"}],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 260,
"y": 320,
"wires": [["c607642a.78c3c8"]]
},
{
"id": "180b1e22.0074e2",
"type": "comment",
"z": "e95345f3e4e33dbe",
"name": "Example 2: Convert JS object to JSON string",
"info": "",
"x": 320,
"y": 260,
"wires": []
},
{
"id": "c607642a.78c3c8",
"type": "template",
"z": "e95345f3e4e33dbe",
"name": "JS object",
"field": "payload",
"fieldType": "msg",
"format": "json",
"syntax": "plain",
"template": "{\n \"kind\": \"Apple\",\n \"price\": 100,\n \"origin\": \"Canada\"\n}",
"output": "json",
"x": 420,
"y": 320,
"wires": [["bf309844.fa12e8"]]
},
{
"id": "5b6b130b.72a14c",
"type": "debug",
"z": "e95345f3e4e33dbe",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"statusVal": "",
"statusType": "auto",
"x": 750,
"y": 320,
"wires": []
},
{
"id": "bf309844.fa12e8",
"type": "json",
"z": "e95345f3e4e33dbe",
"name": "",
"property": "payload",
"action": "",
"pretty": false,
"x": 590,
"y": 320,
"wires": [["5b6b130b.72a14c"]]
},
{
"id": "2b18621b.e2670e",
"type": "inject",
"z": "e95345f3e4e33dbe",
"name": "OK",
"props": [{"p": "payload"}, {"p": "topic", "vt": "str"}],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 250,
"y": 540,
"wires": [["5986faee.aef954"]]
},
{
"id": "59acf99.9a92308",
"type": "comment",
"z": "e95345f3e4e33dbe",
"name": "Example 3: Validate input JSON string with schema",
"info": "",
"x": 350,
"y": 480,
"wires": []
},
{
"id": "5986faee.aef954",
"type": "template",
"z": "e95345f3e4e33dbe",
"name": "JSON string",
"field": "payload",
"fieldType": "msg",
"format": "json",
"syntax": "plain",
"template": "{\n \"kind\": \"Apple\",\n \"price\": 100,\n \"origin\": \"Canada\"\n}",
"output": "str",
"x": 430,
"y": 540,
"wires": [["f8a67c6d.4f1f1"]]
},
{
"id": "ca27c92c.ad7cb8",
"type": "debug",
"z": "e95345f3e4e33dbe",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 930,
"y": 540,
"wires": []
},
{
"id": "2fad9978.ea1916",
"type": "json",
"z": "e95345f3e4e33dbe",
"name": "",
"property": "payload",
"action": "",
"pretty": false,
"x": 770,
"y": 540,
"wires": [["ca27c92c.ad7cb8"]]
},
{
"id": "f8a67c6d.4f1f1",
"type": "template",
"z": "e95345f3e4e33dbe",
"name": "Schema",
"field": "schema",
"fieldType": "msg",
"format": "json",
"syntax": "plain",
"template": "{\n \"type\": \"object\",\n \"properties\": {\n \"kind\": { \"type\": \"string\" },\n \"price\": { \"type\": \"number\" },\n \"origin\": { \"type\": \"string\" }\n }\n}",
"output": "json",
"x": 610,
"y": 540,
"wires": [["2fad9978.ea1916"]]
},
{
"id": "8337e847.ac18d8",
"type": "inject",
"z": "e95345f3e4e33dbe",
"name": "NG",
"props": [{"p": "payload"}, {"p": "topic", "vt": "str"}],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 250,
"y": 620,
"wires": [["fa14d8bf.1ac938"]]
},
{
"id": "fa14d8bf.1ac938",
"type": "template",
"z": "e95345f3e4e33dbe",
"name": "JSON string (invalid)",
"field": "payload",
"fieldType": "msg",
"format": "json",
"syntax": "plain",
"template": "{\n \"kind\": \"Apple\",\n \"price\": \"100\",\n \"origin\": \"Canada\"\n}",
"output": "str",
"x": 460,
"y": 620,
"wires": [["f8a67c6d.4f1f1"]]
}
]
動作: JSON文字列とオブジェクトの相互変換(自動)
プロパティ: msg.payload
入力: '{"kind":"Apple","price":100,"origin":"Canada"}' ← 文字列(引用符付き)
出力: {kind: "Apple", price: 100, origin: "Canada"} ← オブジェクト
動作: JSON文字列とオブジェクトの相互変換(自動)
プロパティ: msg.payload
入力: {kind: "Apple", price: 100, origin: "Canada"} ← オブジェクト
出力: '{"kind":"Apple","price":100,"origin":"Canada"}' ← 文字列
// スキーマ: priceは数値型を期待
{
"type": "object",
"properties": {
"kind": { "type": "string" },
"price": { "type": "number" }
}
}
// OK: price が数値
{"kind": "Apple", "price": 100} → 検証成功
// NG: price が文字列
{"kind": "Apple", "price": "100"} → 検証エラー
整形出力: ON
入力: {kind: "Apple", price: 100, origin: "Canada"}
出力:
'{
"kind": "Apple",
"price": 100,
"origin": "Canada"
}'
// HTTP Requestノードからの応答がJSON文字列の場合
// JSONノードでオブジェクトに変換してから処理
// HTTP Response例:
'{"status":"success","data":{"temperature":25.5}}'
// JSONノード出力:
{status: "success", data: {temperature: 25.5}}
// Functionノードでデータを取り出す:
msg.payload = msg.payload.data.temperature; // 25.5
演習3: JSONスキーマによる検証中級
📝 課題:
注文データをJSONスキーマで検証し、エラー時にはCatchノードで捕捉してください。
🎯 要求仕様:
- Inject、Template(2つ)、JSON、Debug、Catchノードを使用
- スキーマ: productは文字列、quantityは数値、priceは数値
- 正常データとエラーデータの両方でテスト
📊 期待される動作:
- 正常データ: Debugに変換されたオブジェクトが表示
- エラーデータ: Catchノードでエラーを捕捉
✅ 成功の条件:
- 正常データ(quantity が数値)を送ると、デバッグパネルにオブジェクト型のpayloadが表示される
- エラーデータ(quantity が文字列 "5個")を送ると、Catchノードがエラーを捕捉してデバッグに出力される
- 正常データ処理時は
product、quantity、price の3プロパティが正しい型で含まれている
- スキーマ検証によってデータの型チェックが機能している
💡 ヒント
Template(スキーマ)ノードの設定:
- プロパティ: msg.schema
- 出力形式: JSONオブジェクト
- テンプレート: {"type":"object","properties":{"product":{"type":"string"},"quantity":{"type":"number"},"price":{"type":"number"}}}
Catchノードの設定:
テストデータ:
- 正常: {"product":"りんご","quantity":5,"price":150}
- エラー: {"product":"りんご","quantity":"5個","price":150}(quantityが文字列)
✅ 解答例フロー
[
{
"id": "ex3_inject_ok",
"type": "inject",
"name": "正常データ",
"props": [{"p": "payload"}],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "{\"product\":\"りんご\",\"quantity\":5,\"price\":150}",
"payloadType": "str",
"x": 130,
"y": 80,
"wires": [["ex3_schema"]]
},
{
"id": "ex3_inject_ng",
"type": "inject",
"name": "エラーデータ",
"props": [{"p": "payload"}],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "{\"product\":\"りんご\",\"quantity\":\"5個\",\"price\":150}",
"payloadType": "str",
"x": 130,
"y": 140,
"wires": [["ex3_schema"]]
},
{
"id": "ex3_schema",
"type": "template",
"name": "スキーマ設定",
"field": "schema",
"fieldType": "msg",
"format": "json",
"syntax": "plain",
"template": "{\n \"type\": \"object\",\n \"properties\": {\n \"product\": {\"type\": \"string\"},\n \"quantity\": {\"type\": \"number\"},\n \"price\": {\"type\": \"number\"}\n }\n}",
"output": "json",
"x": 320,
"y": 100,
"wires": [["ex3_json"]]
},
{
"id": "ex3_json",
"type": "json",
"name": "JSON検証",
"property": "payload",
"action": "",
"pretty": false,
"x": 480,
"y": 100,
"wires": [["ex3_debug_ok"]]
},
{
"id": "ex3_debug_ok",
"type": "debug",
"name": "成功",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"x": 630,
"y": 100,
"wires": []
},
{
"id": "ex3_catch",
"type": "catch",
"name": "エラー捕捉",
"scope": ["ex3_json"],
"uncaught": false,
"x": 490,
"y": 160,
"wires": [["ex3_debug_ng"]]
},
{
"id": "ex3_debug_ng",
"type": "debug",
"name": "エラー",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"x": 630,
"y": 160,
"wires": []
}
]
HTTP Requestノード(APIコール)
↓
JSONノード(レスポンスをパース)
↓
Changeノード(必要なデータを抽出)
↓
処理...
用途: 外部サービスのAPIからデータを取得して処理
MQTT Inノード(センサーデータ受信)
↓
JSONノード(JSON文字列をパース)
↓
Switchノード(条件分岐)
↓
各種処理...
用途: IoTセンサーからのJSONメッセージを処理
File Inノード(設定ファイル読み込み)
↓
JSONノード(パース)
↓
設定値を使用...
↓
JSONノード(文字列化、整形ON)
↓
File Outノード(保存)
用途: JSON形式の設定ファイルの読み書き
HTTP Inノード(外部からのリクエスト)
↓
Templateノード(スキーマ設定)
↓
JSONノード(スキーマ検証付きパース)
↓ ↘
成功 Catchノード → エラーレスポンス
↓
ビジネスロジック処理
用途: 入力データのバリデーション