通过交互式动手教程学习API基础知识
高级
这是一个AI领域的自动化工作流,包含 28 个节点。主要使用 If, Set, Wait, Webhook, HttpRequest 等节点,结合人工智能技术实现智能自动化。 通过交互式动手教程学习API基础知识
前置要求
- •HTTP Webhook 端点(n8n 会自动生成)
- •可能需要目标 API 的认证凭证
分类
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
"meta": {
"instanceId": "e409ea34548a2afe2dffba31130cd1cf2e98ebe2afaeed2a63caf2a0582d1da0"
},
"nodes": [
{
"id": "500527a4-9764-4e12-92f5-cac0dcc6d10b",
"name": "Start Tutorial",
"type": "n8n-nodes-base.manualTrigger",
"position": [
-900,
360
],
"parameters": {},
"typeVersion": 1
},
{
"id": "41f0f626-eb75-40c9-ae3c-2ad247731885",
"name": "1. The Kitchen (GET /menu)",
"type": "n8n-nodes-base.webhook",
"position": [
120,
360
],
"webhookId": "a1b2c3d4-e5f6-7890-1234-567890abcdef",
"parameters": {
"path": "/tutorial/api/menu",
"options": {},
"responseMode": "lastNode"
},
"typeVersion": 2
},
{
"id": "5d0c582c-9de2-4bbd-b514-cf8833c0078a",
"name": "Respond with Menu",
"type": "n8n-nodes-base.set",
"position": [
340,
360
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "12345",
"name": "item",
"type": "string",
"value": "Pizza"
},
{
"id": "67890",
"name": "price",
"type": "number",
"value": 12
}
]
}
},
"typeVersion": 3.4
},
{
"id": "6b72ccb7-2a86-4853-b5c5-2e05063231a2",
"name": "1. The Customer (GET Menu Item)",
"type": "n8n-nodes-base.httpRequest",
"position": [
-180,
360
],
"parameters": {
"url": "={{ $('Base URL').last().json.your_n8n_base_url }}/menu",
"options": {}
},
"typeVersion": 4.1
},
{
"id": "61453ac8-362c-4bf9-8c7f-3546a8f51bf6",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1180,
-20
],
"parameters": {
"color": 7,
"width": 880,
"height": 560,
"content": "### Tutorial - What is an API?\n\nWelcome! This workflow will teach you the basics of APIs (Application Programming Interfaces).\n\n**What is an API?**\nThink of it like ordering food at a restaurant.\n- **You** are the \"Client\" (the **HTTP Request** node). You want something.\n- The **Kitchen** is the \"Server\" (the **Webhook** node). It has the data/service you want.\n- The **API** is the **Waiter and the Menu**. It's the set of rules and options you have for making a request and getting a response.\n\n\n**How to use this tutorial:**\n1. Click **\"Execute Workflow\"**. The workflow will run from top to bottom.\n2. Explore each \"Lesson\" by clicking on the **HTTP Request** node (the Customer) and its corresponding **Webhook** node (the Kitchen).\n3. Read the sticky note for each lesson to understand the concept being demonstrated."
},
"typeVersion": 1
},
{
"id": "963b1dce-eb8b-460a-a332-85e690f9ebd1",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-260,
60
],
"parameters": {
"width": 880,
"height": 480,
"content": "#### Lesson 1: The Basics (Method & URL)\n\nThis is the simplest possible request.\n\n- **URL (Uniform Resource Locator):** This is the **address of the restaurant's kitchen**. The HTTP Request node needs to know exactly where to send the order. We use a special n8n expression to get the Webhook's test address automatically.\n\n- **Method: `GET`**: This is **what you want to do**. `GET` means you simply want to **retrieve** or **get** information. It's like asking the waiter, \"What's on the menu today?\"\n\n\n**➡️ Look at the output of the HTTP Request node. It received exactly what the Webhook is configured to listen to!**"
},
"typeVersion": 1
},
{
"id": "067de22c-8dde-45b0-b12c-2581fe5ee82c",
"name": "2. The Customer (GET with Query Params)",
"type": "n8n-nodes-base.httpRequest",
"position": [
-180,
940
],
"parameters": {
"url": "={{ $('Base URL').last().json.your_n8n_base_url }}/order",
"options": {},
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "extra_cheese",
"value": "true"
}
]
}
},
"typeVersion": 4.1
},
{
"id": "dfc50d7c-f4b4-41e6-9fde-1afd45bd740d",
"name": "2. The Kitchen (GET /order)",
"type": "n8n-nodes-base.webhook",
"position": [
120,
940
],
"webhookId": "b2c3d4e5-f6a7-8901-2345-67890abcdef1",
"parameters": {
"path": "/tutorial/api/order",
"options": {},
"responseMode": "lastNode"
},
"typeVersion": 2
},
{
"id": "4d2ec461-1ce8-4bb2-a816-5b5032c6376a",
"name": "Respond with Cheese",
"type": "n8n-nodes-base.set",
"position": [
560,
840
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "12345",
"name": "order",
"type": "string",
"value": "Pizza with extra cheese"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "f06d2605-3114-42a2-9678-d1c6fcc78e62",
"name": "Respond with Plain",
"type": "n8n-nodes-base.set",
"position": [
560,
1040
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "12345",
"name": "order",
"type": "string",
"value": "Plain Pizza"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "f0796062-a671-473e-8fa8-becf4df1ce1d",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-260,
580
],
"parameters": {
"width": 1120,
"height": 640,
"content": "#### Lesson 2: Customizing a Request (Query Parameters)\n\nWhat if you want to customize your order? That's what Query Parameters are for.\n\n**Query Parameters:** These are simple options added to the end of the URL after a `?`. They are key-value pairs used to filter, sort, or specify what you want.\n\nIt's like telling the waiter, \"I'll have the pizza... **and can you add extra cheese?**\"\n\n`?extra_cheese=true` is the query parameter.\n\n**➡️ The Webhook node uses an IF node to check for this parameter and changes its response accordingly.\nTry setting the value to `false` in the HTTP Request node and run it again!**"
},
"typeVersion": 1
},
{
"id": "e789ea65-f365-4657-af7c-3cb48d5f2c52",
"name": "3. The Customer (POST with Body)",
"type": "n8n-nodes-base.httpRequest",
"position": [
-180,
1540
],
"parameters": {
"url": "={{ $('Base URL').last().json.your_n8n_base_url }}/review",
"method": "POST",
"options": {},
"sendBody": true,
"bodyParameters": {
"parameters": [
{
"name": "comment",
"value": "I'm so happy !!"
}
]
}
},
"typeVersion": 4.1
},
{
"id": "66688c28-04cd-4c2e-8533-82aa2450becf",
"name": "3. The Kitchen (POST /review)",
"type": "n8n-nodes-base.webhook",
"position": [
120,
1540
],
"webhookId": "c3d4e5f6-a7b8-9012-3456-7890abcdef12",
"parameters": {
"path": "/tutorial/api/review",
"options": {},
"httpMethod": "POST",
"responseMode": "lastNode"
},
"typeVersion": 2
},
{
"id": "7f894c9c-d2b0-42dd-bc23-4f9475e0e5df",
"name": "Respond to Review",
"type": "n8n-nodes-base.set",
"position": [
340,
1540
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "12345",
"name": "status",
"type": "string",
"value": "review_received"
},
{
"id": "67890",
"name": "your_comment",
"type": "string",
"value": "={{ $json.body.comment }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "d899505f-127b-4b21-9616-de10fe08b3e9",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
-260,
1260
],
"parameters": {
"width": 880,
"height": 460,
"content": "#### Lesson 3: Sending Data (POST & Body)\n\nSometimes, you don't want to *get* data, you want to *send* it.\n\n- **Method: `POST`**: This method is used to **send new data** to the server. It's like handing the waiter a completed customer feedback card.\n\n- **Body:** This is the **actual data you are sending**. Since you're sending more complex information than a simple query parameter, it goes in a separate \"package\" called the body.\n\n\n**➡️ The HTTP Request sends a JSON object in its body. The Webhook receives it and includes your comment in its response.**"
},
"typeVersion": 1
},
{
"id": "8b797af9-1ef7-4171-b1ef-f1d2bd19daf8",
"name": "4. The Customer (GET with Headers/Auth)",
"type": "n8n-nodes-base.httpRequest",
"position": [
-180,
2100
],
"parameters": {
"url": "={{ $('Base URL').last().json.your_n8n_base_url }}/secret-dish",
"options": {},
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "x-api-key",
"value": "your-api-key-for-example"
}
]
}
},
"typeVersion": 4.1
},
{
"id": "3d51cbcb-1bc4-4fb7-9356-1c4a92744026",
"name": "4. The Kitchen (GET /secret-dish)",
"type": "n8n-nodes-base.webhook",
"position": [
120,
2100
],
"webhookId": "d4e5f6a7-b8c9-0123-4567-890abcdef123",
"parameters": {
"path": "/tutorial/api/secret-dish",
"options": {},
"responseMode": "lastNode"
},
"typeVersion": 2
},
{
"id": "b54cfc3b-d778-473e-98f0-e44625112c52",
"name": "Respond with Secret",
"type": "n8n-nodes-base.set",
"position": [
560,
2000
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "12345",
"name": "dish",
"type": "string",
"value": "The Chef's Special Truffle Pasta"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "aa2fffb1-e28c-4b91-8b17-6784d0aaafb5",
"name": "Respond with Error",
"type": "n8n-nodes-base.set",
"position": [
560,
2200
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "12345",
"name": "error",
"type": "string",
"value": "You are not authorized"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "a8233025-dcc9-49e9-8e9c-3aeb993cd81d",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
-260,
1760
],
"parameters": {
"width": 1120,
"height": 620,
"content": "#### Lesson 4: Identification (Headers & Auth)\n\nHeaders contain meta-information *about* your request. They're not part of the data itself, but they provide important context. Authentication is a common use case.\n\n- **Headers:** Think of this as **showing your VIP membership card** or whispering a secret password to the waiter. It's information that proves who you are or what your request's properties are.\n\n- **Authentication (Auth):** This is the process of proving your identity. Here, we use a custom header (`x-auth-token`) as a \"secret key\".\n\n\n**➡️ The Webhook checks for the correct secret key in the headers. If it's wrong or missing, it denies the request!**"
},
"typeVersion": 1
},
{
"id": "f4329ae3-5b44-4d04-a18a-e5ad9475cdbe",
"name": "5. The Customer (Request with Timeout)",
"type": "n8n-nodes-base.httpRequest",
"onError": "continueRegularOutput",
"position": [
-180,
2740
],
"parameters": {
"url": "={{ $('Base URL').last().json.your_n8n_base_url }}/slow-service",
"options": {
"timeout": 2000
}
},
"typeVersion": 4.1
},
{
"id": "70657e1b-f8a8-443a-9d01-98d0dc073d96",
"name": "5. The Kitchen (GET /slow-service)",
"type": "n8n-nodes-base.webhook",
"position": [
120,
2740
],
"webhookId": "e5f6a7b8-c9d0-1234-5678-90abcdef1234",
"parameters": {
"path": "/tutorial/api/slow-service",
"options": {},
"responseMode": "lastNode"
},
"typeVersion": 2
},
{
"id": "ecb8a39c-88a0-4b6a-9f8b-5ac5e63cce3c",
"name": "Respond Slowly",
"type": "n8n-nodes-base.set",
"position": [
560,
2740
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "12345",
"name": "status",
"type": "string",
"value": "Finally, your food is here!"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "087db781-41f5-4de2-b4a3-e9f53ffb7ab5",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
-260,
2420
],
"parameters": {
"width": 1080,
"height": 500,
"content": "#### Lesson 5: Being Patient (Timeout)\n\nAn API request isn't instant. What if the kitchen is really busy?\n\n- **Timeout:** This is the **maximum amount of time (in milliseconds) you are willing to wait** for a response before you give up and walk away.\n\n\nIn this example:\n- The **Kitchen (Webhook)** has a 3-second delay.\n- The **Customer (HTTP Request)** is only willing to wait for 2 seconds (2000 ms).\n\n**➡️ This request is designed to FAIL! The customer gives up before the kitchen can finish the order. This is crucial for preventing your workflows from getting stuck forever waiting for a slow service.**"
},
"typeVersion": 1
},
{
"id": "10fa759b-3729-41d8-88c4-b06852261f12",
"name": "Wait 3 seconds",
"type": "n8n-nodes-base.wait",
"position": [
340,
2740
],
"webhookId": "9a79d11e-fb6d-4bc1-89a3-0276182bd9f9",
"parameters": {
"amount": 3
},
"typeVersion": 1.1
},
{
"id": "c0baeacb-f28f-47d6-be03-0886a4ef9d37",
"name": "Base URL",
"type": "n8n-nodes-base.set",
"position": [
-680,
360
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "7edededc-2f40-4b8e-b8db-ab4816f1a28e",
"name": "your_n8n_base_url",
"type": "string",
"value": "={{ $env.WEBHOOK_URL + ($env.N8N_ENDPOINT_WEBHOOK ?? \"webhook\") }}/tutorial/api"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "bd3288ba-e7cf-43b1-b918-ac37bd437788",
"name": "IF Authorized",
"type": "n8n-nodes-base.if",
"position": [
340,
2100
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "ca861c2d-78d9-403b-8bab-28d8e7dcf39c",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.headers['x-api-key'] }}",
"rightValue": "your-api-key-for-example"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "c0bbea62-d40a-4966-bf0a-c30970192686",
"name": "IF extra cheese",
"type": "n8n-nodes-base.if",
"position": [
340,
940
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "ca861c2d-78d9-403b-8bab-28d8e7dcf39c",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{ $json.query.extra_cheese }}",
"rightValue": "your-api-key-for-example"
}
]
},
"looseTypeValidation": true
},
"typeVersion": 2.2
}
],
"pinData": {
"4. The Kitchen (GET /secret-dish)": [
{
"body": {},
"query": {},
"params": {},
"headers": {
"via": "1.1 Caddy",
"host": "api.ia2s.app",
"accept": "application/json,text/html,application/xhtml+xml,application/xml,text/*;q=0.9, image/*;q=0.8, */*;q=0.7",
"api-key": "your-api-key-for-example",
"user-agent": "axios/1.8.3",
"accept-encoding": "gzip, compress, deflate, br",
"x-forwarded-for": "192.168.80.1",
"x-forwarded-host": "api.ia2s.app",
"x-forwarded-proto": "https"
},
"webhookUrl": "https://api.ia2s.app/webhook/tutorial/api/secret-dish",
"executionMode": "production"
}
]
},
"connections": {
"Base URL": {
"main": [
[
{
"node": "1. The Customer (GET Menu Item)",
"type": "main",
"index": 0
},
{
"node": "2. The Customer (GET with Query Params)",
"type": "main",
"index": 0
},
{
"node": "3. The Customer (POST with Body)",
"type": "main",
"index": 0
},
{
"node": "4. The Customer (GET with Headers/Auth)",
"type": "main",
"index": 0
},
{
"node": "5. The Customer (Request with Timeout)",
"type": "main",
"index": 0
}
]
]
},
"IF Authorized": {
"main": [
[
{
"node": "Respond with Secret",
"type": "main",
"index": 0
}
],
[
{
"node": "Respond with Error",
"type": "main",
"index": 0
}
]
]
},
"Start Tutorial": {
"main": [
[
{
"node": "Base URL",
"type": "main",
"index": 0
}
]
]
},
"Wait 3 seconds": {
"main": [
[
{
"node": "Respond Slowly",
"type": "main",
"index": 0
}
]
]
},
"IF extra cheese": {
"main": [
[
{
"node": "Respond with Cheese",
"type": "main",
"index": 0
}
],
[
{
"node": "Respond with Plain",
"type": "main",
"index": 0
}
]
]
},
"1. The Kitchen (GET /menu)": {
"main": [
[
{
"node": "Respond with Menu",
"type": "main",
"index": 0
}
]
]
},
"2. The Kitchen (GET /order)": {
"main": [
[
{
"node": "IF extra cheese",
"type": "main",
"index": 0
}
]
]
},
"3. The Kitchen (POST /review)": {
"main": [
[
{
"node": "Respond to Review",
"type": "main",
"index": 0
}
]
]
},
"1. The Customer (GET Menu Item)": {
"main": [
[]
]
},
"3. The Customer (POST with Body)": {
"main": [
[]
]
},
"4. The Kitchen (GET /secret-dish)": {
"main": [
[
{
"node": "IF Authorized",
"type": "main",
"index": 0
}
]
]
},
"5. The Kitchen (GET /slow-service)": {
"main": [
[
{
"node": "Wait 3 seconds",
"type": "main",
"index": 0
}
]
]
},
"2. The Customer (GET with Query Params)": {
"main": [
[]
]
},
"4. The Customer (GET with Headers/Auth)": {
"main": [
[]
]
}
}
}常见问题
如何使用这个工作流?
复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。
这个工作流适合什么场景?
高级 - 人工智能
需要付费吗?
本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。
相关工作流推荐
AI智能助手:与Supabase存储和Google Drive文件对话
AI智能助手:与Supabase存储和Google Drive文件对话
If
Set
Wait
+20
62 节点Mark Shcherbakov
工程
使用AI将Reddit帖子转换为短视频
使用AI将Reddit帖子转换为短视频
If
Set
Code
+11
43 节点Artur
人工智能
YouTube RAG 搜索前端(使用 Apify、Qdrant 和 AI)
基于 Apify、Qdrant 和 AI 的 YouTube RAG 搜索前端
If
Set
Html
+23
62 节点Jimleuk
人工智能
🎓 使用并行处理优化速度关键工作流(扇出-扇入)
🎓 使用并行处理(扇出/扇入)优化速度关键工作流
If
Set
Code
+10
34 节点Lucas Peyrin
工程
带等待节点的长运行工作流状态管理系统
带等待节点的长运行工作流状态管理系统
If
Set
Code
+10
42 节点Lucas Peyrin
工程
自动n8n更新器(Docker)
自动n8n更新器(Docker)
If
Set
Ssh
+6
26 节点Lucas Peyrin
人工智能
工作流信息
难度等级
高级
节点数量28
分类1
节点类型7
作者
Lucas Peyrin
@lucaspeyrinInnovative builder with a passion for crafting automation solutions that solve real-world challenges. From streamlining workflows to driving efficiency, my work empowers teams and individuals to achieve more with less effort. Experienced in developing scalable tools and strategies that deliver results with n8n, supabase and cline.
外部链接
在 n8n.io 查看 →
分享此工作流