Créer une passerelle API dynamique avec des routages HTTP et une orchestration de workflow

Avancé

Ceci est unContent Creation, Multimodal AIworkflow d'automatisation du domainecontenant 24 nœuds.Utilise principalement des nœuds comme If, Set, Code, Webhook, ExecuteWorkflow. Créer une passerelle API dynamique avec des routes HTTP et une orchestration de workflows

Prérequis
  • Point de terminaison HTTP Webhook (généré automatiquement par n8n)
Aperçu du workflow
Visualisation des connexions entre les nœuds, avec support du zoom et du déplacement
Exporter le workflow
Copiez la configuration JSON suivante dans n8n pour importer et utiliser ce workflow
{
  "meta": {
    "instanceId": "2af7d602b9c59038b521d73a8d986df022306cc34b7d66460334237434b5f4ad"
  },
  "nodes": [
    {
      "id": "e6445f6f-1087-4e51-b8e5-ddb99456f868",
      "name": "HEAD",
      "type": "n8n-nodes-base.set",
      "position": [
        -336,
        1440
      ],
      "parameters": {
        "mode": "raw",
        "options": {},
        "jsonOutput": "{\n  \"method\": \"HEAD\"\n}\n"
      },
      "typeVersion": 3.4
    },
    {
      "id": "bb48dadb-e960-4e34-bb51-f0a0528c0369",
      "name": "Exécuter le flux de travail",
      "type": "n8n-nodes-base.executeWorkflow",
      "onError": "continueErrorOutput",
      "position": [
        896,
        672
      ],
      "parameters": {
        "mode": "each",
        "options": {
          "waitForSubWorkflow": true
        },
        "workflowId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Resolve').item.json.workflowIdToExecute }}",
          "cachedResultUrl": "/workflow/=%7B%7B%20$('Resolve').item.json.workflowIdToExecute%20%7D%7D"
        },
        "workflowInputs": {
          "value": {},
          "schema": [],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": true
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "050ed363-ea07-4301-a53b-28c5c6328857",
      "name": "Succès",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        1088,
        672
      ],
      "parameters": {
        "options": {
          "responseCode": 200
        },
        "respondWith": "json",
        "responseBody": "={{ $json }}"
      },
      "typeVersion": 1.4
    },
    {
      "id": "1659fc43-7139-49c8-a5a8-e1557dc89bae",
      "name": "Agréger les branches de méthode",
      "type": "n8n-nodes-base.set",
      "position": [
        -128,
        672
      ],
      "parameters": {
        "mode": "raw",
        "options": {},
        "jsonOutput": "={{ $json }}"
      },
      "typeVersion": 3.4
    },
    {
      "id": "3bdd165b-3ce6-4292-b696-bfc99a984ee3",
      "name": "PUT",
      "type": "n8n-nodes-base.set",
      "position": [
        -336,
        1280
      ],
      "parameters": {
        "mode": "raw",
        "options": {},
        "jsonOutput": "{\n  \"method\": \"PUT\"\n}\n"
      },
      "typeVersion": 3.4
    },
    {
      "id": "3aeaa1f4-9b71-46da-ae4f-277a356c1dc2",
      "name": "PATCH",
      "type": "n8n-nodes-base.set",
      "position": [
        -336,
        1120
      ],
      "parameters": {
        "mode": "raw",
        "options": {},
        "jsonOutput": "{\n  \"method\": \"PATCH\"\n}\n"
      },
      "typeVersion": 3.4
    },
    {
      "id": "56b8e967-39b4-43d4-b610-77e009227d07",
      "name": "DELETE",
      "type": "n8n-nodes-base.set",
      "position": [
        -336,
        960
      ],
      "parameters": {
        "mode": "raw",
        "options": {},
        "jsonOutput": "{\n  \"method\": \"DELETE\"\n}\n"
      },
      "typeVersion": 3.4
    },
    {
      "id": "6e369b93-0468-4cb3-8198-09bcd21a5b17",
      "name": "POST",
      "type": "n8n-nodes-base.set",
      "position": [
        -336,
        816
      ],
      "parameters": {
        "mode": "raw",
        "options": {},
        "jsonOutput": "{\n  \"method\": \"POST\"\n}\n"
      },
      "typeVersion": 3.4
    },
    {
      "id": "cb22c4e7-1a77-455d-a4c8-d6be32d6136e",
      "name": "GET",
      "type": "n8n-nodes-base.set",
      "position": [
        -336,
        672
      ],
      "parameters": {
        "mode": "raw",
        "options": {},
        "jsonOutput": "{\n  \"method\": \"GET\"\n}\n"
      },
      "typeVersion": 3.4
    },
    {
      "id": "42dcf978-3dbc-40bc-b514-a0fb5c01f5df",
      "name": "Configuration des routes",
      "type": "n8n-nodes-base.set",
      "position": [
        288,
        672
      ],
      "parameters": {
        "mode": "raw",
        "options": {},
        "jsonOutput": "{\n  \"routes\": [\n    {\n      \"action\": \"doSomething\",\n      \"allowedMethods\": [\"GET\"],\n      \"subflowId\": -1\n    },\n    {\n      \"action\": \"doSomethingElse\",\n      \"allowedMethods\": [\"GET\", \"POST\"],\n      \"subflowId\": -1\n    },\n    {\n      \"action\": \"deleteSomething\",\n      \"allowedMethods\": [\"DELETE\"],\n      \"subflowId\": -1\n    }\n  ]\n}\n"
      },
      "typeVersion": 3.4
    },
    {
      "id": "91b1d0a9-431f-4806-b291-fd76973301d7",
      "name": "Le paramètre de requête existe ?",
      "type": "n8n-nodes-base.if",
      "position": [
        64,
        672
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "d010b9f7-91c1-45b8-8f57-0dd17c4db7d2",
              "operator": {
                "type": "string",
                "operation": "exists",
                "singleValue": true
              },
              "leftValue": "={{ $('Universal Receiver').item.json.query?.action }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "4a9798ab-c963-4e42-9a0b-8d8e9f2ac2ed",
      "name": "Récepteur universel",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -544,
        672
      ],
      "webhookId": "a4696443-7af7-4183-8158-e2036fab13ef",
      "parameters": {
        "path": "universalReceiver",
        "options": {},
        "httpMethod": [
          "GET",
          "POST",
          "DELETE",
          "PATCH",
          "PUT",
          "HEAD"
        ],
        "responseMode": "responseNode",
        "multipleMethods": true
      },
      "typeVersion": 2.1
    },
    {
      "id": "116a35d5-68cc-478c-8630-4f9a36bdba36",
      "name": "Sticky : Détection de méthode",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -336,
        496
      ],
      "parameters": {
        "color": 7,
        "width": 308,
        "height": 152,
        "content": "Method branches: Each branch hardcodes the HTTP method because n8n’s Webhook node does not expose the method as a property directly. We aggregate these branches so other nodes can reference a single `method` value."
      },
      "typeVersion": 1
    },
    {
      "id": "1664cfd5-d8fb-4417-a99e-43e7ccf7568b",
      "name": "Sticky : Configuration des routes",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        208,
        496
      ],
      "parameters": {
        "color": 7,
        "width": 228,
        "height": 152,
        "content": "Route configuration: Map action names to subflow IDs and allowed HTTP methods. You can override this with other methods for receiving data, such as database queries or similar."
      },
      "typeVersion": 1
    },
    {
      "id": "b95edefc-f4cf-4696-8d09-5271233f1d38",
      "name": "Sticky : Résolveur",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        464,
        496
      ],
      "parameters": {
        "color": 7,
        "width": 180,
        "height": 152,
        "content": "Resolve Route: Reads the query action and method, checks the config and decides whether to run a subflow. "
      },
      "typeVersion": 1
    },
    {
      "id": "784a1ad8-d454-41fe-ab3b-801e81cce923",
      "name": "Sticky : Exécuter et répondre",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        880,
        496
      ],
      "parameters": {
        "color": 7,
        "width": 308,
        "height": 152,
        "content": "Execution & Response: Executes the target subflow when valid and returns its output."
      },
      "typeVersion": 1
    },
    {
      "id": "c712a136-97f8-49fe-b01a-77ed001fe10f",
      "name": "[Erreur] Paramètre de requête obligatoire manquant",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        288,
        848
      ],
      "parameters": {
        "options": {
          "responseCode": 400
        },
        "respondWith": "json",
        "responseBody": "{\n  \"error\": \"Required information not provided!\"\n}"
      },
      "typeVersion": 1.4
    },
    {
      "id": "d10087c4-96d7-4df6-9918-81b95a95cd6c",
      "name": "Résoudre",
      "type": "n8n-nodes-base.code",
      "position": [
        496,
        672
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "// inputs\nconst method = $('Aggregate Method Branches').item.json.method;\nconst action = $(\"Universal Receiver\").item.json.query?.action;\nconst cfg = $(\"Routes Config\").item.json;\nconst routes = Array.isArray(cfg?.routes) ? cfg.routes : [];\nconst body = $(\"Universal Receiver\").item.json.query?.body || null;\n\n// Try to find a matching route (action + method)\nconst routeByAction = routes.find(r => String(r.action || '').toLowerCase() === String(action || '').toLowerCase());\nconst routeByActionAndMethod = routes.find(r => {\n  const actionFound = String(r.action || '').toLowerCase() === String(action || '').toLowerCase();\n  const methodAllowed = Array.isArray(r.allowedMethods) && r.allowedMethods.includes(method);\n  return (actionFound && methodAllowed)\n});\n\nlet error = null;\nlet status = 200;\nlet allowHeader = null;\nlet workflowId = null;\n\nif (!action) {\n  error = 'MISSING_ACTION';\n  status = 400;\n} else if (!routeByAction) {\n  error = 'ROUTE_NOT_FOUND';\n  status = 404;\n} else if (!routeByActionAndMethod) {\n  error = 'METHOD_NOT_ALLOWED';\n  status = 405;\n  allowHeader = Array.isArray(routeByAction.allowedMethods) ? routeByAction.allowedMethods.join(', ') : '';\n} else {\n  workflowId = routeByActionAndMethod.subflowId ?? null;\n  if (workflowId == null) {\n    error = 'MISSING_SUBFLOW_ID';\n    status = 500;\n  }\n}\n\nreturn {\n  action,\n  method,\n  error,\n  status,\n  allow: allowHeader,\n  workflowIdToExecute: workflowId,\n  body\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "80b31830-b665-4f01-a2d6-4a08779e3ebb",
      "name": "La route est OK ?",
      "type": "n8n-nodes-base.if",
      "position": [
        688,
        672
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "d010b9f7-91c1-45b8-8f57-0dd17c4db7d2",
              "operator": {
                "type": "number",
                "operation": "exists",
                "singleValue": true
              },
              "leftValue": "={{ $('Resolve').item.json.workflowIdToExecute }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "99fb75ed-9d41-4396-b4e6-ecead6e005d9",
      "name": "Statut = 405 ?",
      "type": "n8n-nodes-base.if",
      "position": [
        896,
        992
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "9928d071-7d13-4d05-9843-9f2f1b00b60e",
              "operator": {
                "type": "number",
                "operation": "equals"
              },
              "leftValue": "={{ $('Resolve').item.json.status }}",
              "rightValue": 405
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "c1882d8f-bfd1-482c-9f52-113c6111868f",
      "name": "[Erreur] Méthode non autorisée",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        1088,
        992
      ],
      "parameters": {
        "options": {
          "responseCode": 405,
          "responseHeaders": {
            "entries": [
              {
                "name": "Allow",
                "value": "={{ $('Resolve').item.json.allow || '' }}"
              }
            ]
          }
        },
        "respondWith": "json",
        "responseBody": "={\n  \"error\": \"{{ $('Resolve').item.json.error }}\"\n}"
      },
      "typeVersion": 1
    },
    {
      "id": "6325c215-2175-4703-8746-f18e5e8dd208",
      "name": "Erreur - Non OK",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        1088,
        1168
      ],
      "parameters": {
        "options": {
          "responseCode": "={{ $('Resolve').item.json.status || 400 }}"
        },
        "respondWith": "json",
        "responseBody": "={ \"error\": \"{{ $('Resolve').item.json.error || 'Bad request' }}\" }"
      },
      "typeVersion": 1
    },
    {
      "id": "b4f491b6-ea8b-470c-ad4b-d1c8922ae479",
      "name": "Erreur - Sous-flux",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        1088,
        832
      ],
      "parameters": {
        "options": {
          "responseCode": 500
        },
        "respondWith": "json",
        "responseBody": "{\n  \"error\": \"Unexpected error in the executed subflow!\"\n}"
      },
      "typeVersion": 1
    },
    {
      "id": "2fe4296a-f97f-4dce-b49e-983a25720dd8",
      "name": "Sticky : Détection de méthode 1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1104,
        496
      ],
      "parameters": {
        "color": 7,
        "width": 500,
        "height": 520,
        "content": "This flow acts as a centralized API router using a single webhook URL to receive incoming HTTP requests with different methods (GET, POST, DELETE, PATCH, PUT, HEAD).\n\n- The flow separates and hardcodes each HTTP method into dedicated branches (Set nodes for GET, POST, etc.) since the webhook node doesn't expose the method directly. These branches are then consolidated in \"Aggregate Method Branches\" for easier reference.\n- It checks if the required query parameter action exists. If missing, it returns an error response.\n- The `Routes Config` node defines a list of routes mapping the action parameter and allowed HTTP methods to specific subflow IDs. This allows controlling which workflow to execute based on the request.\n- The `Resolve` code node matches the incoming action and method against the configured routes, returns error codes like 404 or 405 if no route/method matches, or identifies the subflow to execute.\n- Based on this result, the flow either executes the matched subflow or returns an appropriate error message and status code (400, 404, 405, 500).\n- After executing a subflow, it returns the subflow result as the response. If the subflow fails, a generic error is sent back.\n- This setup provides a flexible and maintainable way to route multiple API actions via a single webhook endpoint, with centralized management of routes, error handling, and response management."
      },
      "typeVersion": 1
    }
  ],
  "pinData": {},
  "connections": {
    "cb22c4e7-1a77-455d-a4c8-d6be32d6136e": {
      "main": [
        [
          {
            "node": "1659fc43-7139-49c8-a5a8-e1557dc89bae",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "3bdd165b-3ce6-4292-b696-bfc99a984ee3": {
      "main": [
        [
          {
            "node": "1659fc43-7139-49c8-a5a8-e1557dc89bae",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "e6445f6f-1087-4e51-b8e5-ddb99456f868": {
      "main": [
        [
          {
            "node": "1659fc43-7139-49c8-a5a8-e1557dc89bae",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "6e369b93-0468-4cb3-8198-09bcd21a5b17": {
      "main": [
        [
          {
            "node": "1659fc43-7139-49c8-a5a8-e1557dc89bae",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "3aeaa1f4-9b71-46da-ae4f-277a356c1dc2": {
      "main": [
        [
          {
            "node": "1659fc43-7139-49c8-a5a8-e1557dc89bae",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "56b8e967-39b4-43d4-b610-77e009227d07": {
      "main": [
        [
          {
            "node": "1659fc43-7139-49c8-a5a8-e1557dc89bae",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "d10087c4-96d7-4df6-9918-81b95a95cd6c": {
      "main": [
        [
          {
            "node": "80b31830-b665-4f01-a2d6-4a08779e3ebb",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "80b31830-b665-4f01-a2d6-4a08779e3ebb": {
      "main": [
        [
          {
            "node": "bb48dadb-e960-4e34-bb51-f0a0528c0369",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "99fb75ed-9d41-4396-b4e6-ecead6e005d9",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "42dcf978-3dbc-40bc-b514-a0fb5c01f5df": {
      "main": [
        [
          {
            "node": "d10087c4-96d7-4df6-9918-81b95a95cd6c",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "99fb75ed-9d41-4396-b4e6-ecead6e005d9": {
      "main": [
        [
          {
            "node": "c1882d8f-bfd1-482c-9f52-113c6111868f",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "6325c215-2175-4703-8746-f18e5e8dd208",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "bb48dadb-e960-4e34-bb51-f0a0528c0369": {
      "main": [
        [
          {
            "node": "050ed363-ea07-4301-a53b-28c5c6328857",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "b4f491b6-ea8b-470c-ad4b-d1c8922ae479",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "4a9798ab-c963-4e42-9a0b-8d8e9f2ac2ed": {
      "main": [
        [
          {
            "node": "cb22c4e7-1a77-455d-a4c8-d6be32d6136e",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "6e369b93-0468-4cb3-8198-09bcd21a5b17",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "56b8e967-39b4-43d4-b610-77e009227d07",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "3aeaa1f4-9b71-46da-ae4f-277a356c1dc2",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "3bdd165b-3ce6-4292-b696-bfc99a984ee3",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "e6445f6f-1087-4e51-b8e5-ddb99456f868",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "91b1d0a9-431f-4806-b291-fd76973301d7": {
      "main": [
        [
          {
            "node": "42dcf978-3dbc-40bc-b514-a0fb5c01f5df",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "c712a136-97f8-49fe-b01a-77ed001fe10f",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "1659fc43-7139-49c8-a5a8-e1557dc89bae": {
      "main": [
        [
          {
            "node": "91b1d0a9-431f-4806-b291-fd76973301d7",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Foire aux questions

Comment utiliser ce workflow ?

Copiez le code de configuration JSON ci-dessus, créez un nouveau workflow dans votre instance n8n et sélectionnez "Importer depuis le JSON", collez la configuration et modifiez les paramètres d'authentification selon vos besoins.

Dans quelles scénarios ce workflow est-il adapté ?

Avancé - Création de contenu, IA Multimodale

Est-ce payant ?

Ce workflow est entièrement gratuit et peut être utilisé directement. Veuillez noter que les services tiers utilisés dans le workflow (comme l'API OpenAI) peuvent nécessiter un paiement de votre part.

Informations sur le workflow
Niveau de difficulté
Avancé
Nombre de nœuds24
Catégorie2
Types de nœuds7
Description de la difficulté

Adapté aux utilisateurs avancés, avec des workflows complexes contenant 16+ nœuds

Liens externes
Voir sur n8n.io

Partager ce workflow

Catégories

Catégories: 34