[
{
"id": "http_sample_tab",
"type": "tab",
"label": "HTTP ノード サンプル",
"disabled": false,
"info": ""
},
{
"id": "http_comment1",
"type": "comment",
"z": "http_sample_tab",
"name": "━━━ 基本: Hello World API ━━━",
"info": "GET http://localhost:1880/api/hello",
"x": 190,
"y": 40,
"wires": []
},
{
"id": "http_in_hello",
"type": "http in",
"z": "http_sample_tab",
"name": "GET /api/hello",
"url": "/api/hello",
"method": "get",
"upload": false,
"skipBodyParsing": false,
"swaggerDoc": "",
"x": 160,
"y": 100,
"wires": [["http_change_hello"]]
},
{
"id": "http_change_hello",
"type": "change",
"z": "http_sample_tab",
"name": "レスポンス設定",
"rules": [
{"t": "set", "p": "payload", "pt": "msg", "to": "{\"message\":\"Hello from Node-RED!\",\"timestamp\":\"\"}", "tot": "json"},
{"t": "set", "p": "payload.timestamp", "pt": "msg", "to": "", "tot": "date"},
{"t": "set", "p": "headers", "pt": "msg", "to": "{\"Content-Type\":\"application/json\"}", "tot": "json"}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 380,
"y": 100,
"wires": [["http_response_hello", "http_debug_hello"]]
},
{
"id": "http_response_hello",
"type": "http response",
"z": "http_sample_tab",
"name": "Response",
"statusCode": "200",
"headers": {},
"x": 580,
"y": 100,
"wires": []
},
{
"id": "http_debug_hello",
"type": "debug",
"z": "http_sample_tab",
"name": "リクエスト確認",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": true,
"complete": "payload",
"targetType": "msg",
"statusVal": "\"リクエスト受信\"",
"statusType": "str",
"x": 600,
"y": 140,
"wires": []
},
{
"id": "http_comment2",
"type": "comment",
"z": "http_sample_tab",
"name": "━━━ POST: データ受信API ━━━",
"info": "POST http://localhost:1880/api/data",
"x": 190,
"y": 200,
"wires": []
},
{
"id": "http_in_post",
"type": "http in",
"z": "http_sample_tab",
"name": "POST /api/data",
"url": "/api/data",
"method": "post",
"upload": false,
"skipBodyParsing": false,
"swaggerDoc": "",
"x": 160,
"y": 260,
"wires": [["http_func_post"]]
},
{
"id": "http_func_post",
"type": "function",
"z": "http_sample_tab",
"name": "データ処理",
"func": "// 受信データを処理\nvar receivedData = msg.payload;\n\n// データを保存(flow変数)\nvar dataStore = flow.get('dataStore') || [];\ndataStore.push({\n id: Date.now(),\n data: receivedData,\n receivedAt: new Date().toISOString()\n});\nflow.set('dataStore', dataStore);\n\n// レスポンス作成\nmsg.payload = {\n success: true,\n message: \"データを受信しました\",\n received: receivedData,\n totalCount: dataStore.length\n};\nmsg.statusCode = 201;\nmsg.headers = {\"Content-Type\": \"application/json\"};\n\nreturn msg;",
"outputs": 1,
"timeout": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 350,
"y": 260,
"wires": [["http_response_post", "http_debug_post"]]
},
{
"id": "http_response_post",
"type": "http response",
"z": "http_sample_tab",
"name": "Response",
"statusCode": "",
"headers": {},
"x": 540,
"y": 260,
"wires": []
},
{
"id": "http_debug_post",
"type": "debug",
"z": "http_sample_tab",
"name": "受信データ",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": true,
"complete": "payload",
"targetType": "msg",
"statusVal": "\"データ受信\"",
"statusType": "str",
"x": 550,
"y": 300,
"wires": []
},
{
"id": "http_comment3",
"type": "comment",
"z": "http_sample_tab",
"name": "━━━ URLパラメータ: /users/:id ━━━",
"info": "GET http://localhost:1880/api/users/1",
"x": 200,
"y": 360,
"wires": []
},
{
"id": "http_in_users",
"type": "http in",
"z": "http_sample_tab",
"name": "GET /api/users/:id",
"url": "/api/users/:id",
"method": "get",
"upload": false,
"skipBodyParsing": false,
"swaggerDoc": "",
"x": 170,
"y": 420,
"wires": [["http_func_users"]]
},
{
"id": "http_func_users",
"type": "function",
"z": "http_sample_tab",
"name": "ユーザー検索",
"func": "// URLパラメータからIDを取得\nvar userId = msg.req.params.id;\n\n// サンプルユーザーデータ\nvar users = {\n \"1\": {name: \"田中太郎\", email: \"tanaka@example.com\"},\n \"2\": {name: \"鈴木花子\", email: \"suzuki@example.com\"},\n \"3\": {name: \"佐藤次郎\", email: \"sato@example.com\"}\n};\n\n// ユーザー検索\nif (users[userId]) {\n msg.payload = {\n success: true,\n user: { id: userId, name: users[userId].name, email: users[userId].email }\n };\n msg.statusCode = 200;\n} else {\n msg.payload = {\n success: false,\n error: \"ユーザーが見つかりません\",\n requestedId: userId\n };\n msg.statusCode = 404;\n}\n\nmsg.headers = {\"Content-Type\": \"application/json\"};\nreturn msg;",
"outputs": 1,
"timeout": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 380,
"y": 420,
"wires": [["http_response_users", "http_debug_users"]]
},
{
"id": "http_response_users",
"type": "http response",
"z": "http_sample_tab",
"name": "Response",
"statusCode": "",
"headers": {},
"x": 580,
"y": 420,
"wires": []
},
{
"id": "http_debug_users",
"type": "debug",
"z": "http_sample_tab",
"name": "検索結果",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": true,
"complete": "payload",
"targetType": "msg",
"statusVal": "req.params.id",
"statusType": "msg",
"x": 570,
"y": 460,
"wires": []
},
{
"id": "http_comment4",
"type": "comment",
"z": "http_sample_tab",
"name": "━━━ 外部API呼び出し ━━━",
"info": "World Time APIで時刻取得",
"x": 180,
"y": 520,
"wires": []
},
{
"id": "http_inject_api",
"type": "inject",
"z": "http_sample_tab",
"name": "東京の時刻取得",
"props": [],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"x": 160,
"y": 580,
"wires": [["http_request_time"]]
},
{
"id": "http_request_time",
"type": "http request",
"z": "http_sample_tab",
"name": "World Time API",
"method": "GET",
"ret": "obj",
"paytoqs": "ignore",
"url": "https://worldtimeapi.org/api/timezone/Asia/Tokyo",
"tls": "",
"persist": false,
"proxy": "",
"insecureHTTPParser": false,
"authType": "",
"senderr": false,
"headers": [],
"x": 360,
"y": 580,
"wires": [["http_func_time"]]
},
{
"id": "http_func_time",
"type": "function",
"z": "http_sample_tab",
"name": "時刻を整形",
"func": "// APIレスポンスから時刻情報を抽出\nvar datetime = msg.payload.datetime;\nvar timezone = msg.payload.timezone;\n\nmsg.payload = {\n timezone: timezone,\n datetime: datetime,\n formatted: new Date(datetime).toLocaleString('ja-JP')\n};\n\nreturn msg;",
"outputs": 1,
"timeout": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 550,
"y": 580,
"wires": [["http_debug_time"]]
},
{
"id": "http_debug_time",
"type": "debug",
"z": "http_sample_tab",
"name": "時刻表示",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": true,
"complete": "payload",
"targetType": "msg",
"statusVal": "payload.formatted",
"statusType": "msg",
"x": 720,
"y": 580,
"wires": []
},
{
"id": "http_comment5",
"type": "comment",
"z": "http_sample_tab",
"name": "━━━ エラーハンドリング ━━━",
"info": "ステータスコードで分岐",
"x": 180,
"y": 640,
"wires": []
},
{
"id": "http_inject_error",
"type": "inject",
"z": "http_sample_tab",
"name": "404テスト",
"props": [],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"x": 150,
"y": 700,
"wires": [["http_request_error"]]
},
{
"id": "http_request_error",
"type": "http request",
"z": "http_sample_tab",
"name": "404エラーテスト",
"method": "GET",
"ret": "obj",
"paytoqs": "ignore",
"url": "https://httpbin.org/status/404",
"tls": "",
"persist": false,
"proxy": "",
"insecureHTTPParser": false,
"authType": "",
"senderr": false,
"headers": [],
"x": 360,
"y": 700,
"wires": [["http_switch_status"]]
},
{
"id": "http_switch_status",
"type": "switch",
"z": "http_sample_tab",
"name": "ステータス判定",
"property": "statusCode",
"propertyType": "msg",
"rules": [
{"t": "btwn", "v": "200", "vt": "num", "v2": "299", "v2t": "num"},
{"t": "btwn", "v": "400", "vt": "num", "v2": "499", "v2t": "num"},
{"t": "gte", "v": "500", "vt": "num"}
],
"checkall": "false",
"repair": false,
"outputs": 3,
"x": 560,
"y": 700,
"wires": [["http_debug_success"], ["http_debug_client_err"], ["http_debug_server_err"]]
},
{
"id": "http_debug_success",
"type": "debug",
"z": "http_sample_tab",
"name": "成功 (2xx)",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": true,
"complete": "statusCode",
"targetType": "msg",
"statusVal": "\"成功\"",
"statusType": "str",
"x": 750,
"y": 660,
"wires": []
},
{
"id": "http_debug_client_err",
"type": "debug",
"z": "http_sample_tab",
"name": "クライアントエラー (4xx)",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": true,
"complete": "statusCode",
"targetType": "msg",
"statusVal": "\"クライアントエラー\"",
"statusType": "str",
"x": 790,
"y": 700,
"wires": []
},
{
"id": "http_debug_server_err",
"type": "debug",
"z": "http_sample_tab",
"name": "サーバーエラー (5xx)",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": true,
"complete": "statusCode",
"targetType": "msg",
"statusVal": "\"サーバーエラー\"",
"statusType": "str",
"x": 780,
"y": 740,
"wires": []
},
{
"id": "http_comment6",
"type": "comment",
"z": "http_sample_tab",
"name": "━━━ HTMLページ提供 ━━━",
"info": "GET http://localhost:1880/page",
"x": 180,
"y": 800,
"wires": []
},
{
"id": "http_in_page",
"type": "http in",
"z": "http_sample_tab",
"name": "GET /page",
"url": "/page",
"method": "get",
"upload": false,
"skipBodyParsing": false,
"swaggerDoc": "",
"x": 140,
"y": 860,
"wires": [["http_in_template"]]
},
{
"id": "http_in_template",
"type": "template",
"z": "http_sample_tab",
"name": "HTML生成",
"field": "payload",
"fieldType": "msg",
"format": "html",
"syntax": "mustache",
"template": "\n\n\n
\n
Node-RED Page\n \n\n\n
\n Node-RED Web Page
\n This page is dynamically generated by Node-RED.
\n \n Current Time: {{timestamp}}
\n Request Host: {{req.headers.host}}
\n \n \n\n",
"output": "str",
"x": 310,
"y": 860,
"wires": [["http_in_change_html"]]
},
{
"id": "http_in_change_html",
"type": "change",
"z": "http_sample_tab",
"name": "タイムスタンプ設定",
"rules": [
{"t": "set", "p": "timestamp", "pt": "msg", "to": "", "tot": "date"},
{"t": "set", "p": "headers", "pt": "msg", "to": "{\"Content-Type\":\"text/html; charset=utf-8\"}", "tot": "json"}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 510,
"y": 860,
"wires": [["http_response_page"]]
},
{
"id": "http_response_page",
"type": "http response",
"z": "http_sample_tab",
"name": "Response",
"statusCode": "200",
"headers": {},
"x": 700,
"y": 860,
"wires": []
},
{
"id": "http_comment7",
"type": "comment",
"z": "http_sample_tab",
"name": "━━━ セルフテスト ━━━",
"info": "HTTP Requestで自分のAPIを呼び出し",
"x": 170,
"y": 920,
"wires": []
},
{
"id": "http_inject_selftest",
"type": "inject",
"z": "http_sample_tab",
"name": "APIテスト",
"props": [],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"x": 140,
"y": 980,
"wires": [["http_request_selftest"]]
},
{
"id": "http_request_selftest",
"type": "http request",
"z": "http_sample_tab",
"name": "自分のAPIを呼出",
"method": "GET",
"ret": "obj",
"paytoqs": "ignore",
"url": "http://localhost:1880/api/hello",
"tls": "",
"persist": false,
"proxy": "",
"insecureHTTPParser": false,
"authType": "",
"senderr": false,
"headers": [],
"x": 350,
"y": 980,
"wires": [["http_debug_selftest"]]
},
{
"id": "http_debug_selftest",
"type": "debug",
"z": "http_sample_tab",
"name": "テスト結果",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": true,
"complete": "payload",
"targetType": "msg",
"statusVal": "payload.message",
"statusType": "msg",
"x": 550,
"y": 980,
"wires": []
}
]