SKILL.md
唯讀
名稱
typespec-api-operations
描述
為 TypeSpec API 外掛模組新增 GET、POST、PATCH 及 DELETE 操作,包含適當的路由設定、參數配置與 Adaptive Card 展示
新增 TypeSpec API 操作
為現有的 Microsoft 365 Copilot TypeSpec API 外掛模組新增 RESTful 操作。
新增 GET 操作
簡單 GET — 列出所有項目
/**
* List all items.
*/
@route("/items")
@get op listItems(): Item[];
帶 Query 參數的 GET — 篩選結果
/**
* List items filtered by criteria.
* @param userId Optional user ID to filter items
*/
@route("/items")
@get op listItems(@query userId?: integer): Item[];
帶 Path 參數的 GET — 取得單一項目
/**
* Get a specific item by ID.
* @param id The ID of the item to retrieve
*/
@route("/items/{id}")
@get op getItem(@path id: integer): Item;
搭配 Adaptive Card 的 GET
/**
* List items with adaptive card visualization.
*/
@route("/items")
@card(#{
dataPath: "$",
title: "$.title",
file: "item-card.json"
})
@get op listItems(): Item[];
建立 Adaptive Card (appPackage/item-card.json):
{
"type": "AdaptiveCard",
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.5",
"body": [
{
"type": "Container",
"$data": "${$root}",
"items": [
{
"type": "TextBlock",
"text": "**${if(title, title, 'N/A')}**",
"wrap": true
},
{
"type": "TextBlock",
"text": "${if(description, description, 'N/A')}",
"wrap": true
}
]
}
],
"actions": [
{
"type": "Action.OpenUrl",
"title": "View Details",
"url": "https://example.com/items/${id}"
}
]
}
新增 POST 操作
簡單 POST — 建立項目
/**
* Create a new item.
* @param item The item to create
*/
@route("/items")
@post op createItem(@body item: CreateItemRequest): Item;
model CreateItemRequest {
title: string;
description?: string;
userId: integer;
}
帶有確認機制的 POST
/**
* Create a new item with confirmation.
*/
@route("/items")
@post
@capabilities(#{
confirmation: #{
type: "AdaptiveCard",
title: "Create Item",
body: """
Are you sure you want to create this item?
* **Title**: {{ function.parameters.item.title }}
* **User ID**: {{ function.parameters.item.userId }}
"""
}
})
op createItem(@body item: CreateItemRequest): Item;
新增 PATCH 操作
簡單 PATCH — 更新項目
/**
* Update an existing item.
* @param id The ID of the item to update
* @param item The updated item data
*/
@route("/items/{id}")
@patch op updateItem(
@path id: integer,
@body item: UpdateItemRequest
): Item;
model UpdateItemRequest {
title?: string;
description?: string;
status?: "active" | "completed" | "archived";
}
帶有確認機制的 PATCH
/**
* Update an item with confirmation.
*/
@route("/items/{id}")
@patch
@capabilities(#{
confirmation: #{
type: "AdaptiveCard",
title: "Update Item",
body: """
Updating item #{{ function.parameters.id }}:
* **Title**: {{ function.parameters.item.title }}
* **Status**: {{ function.parameters.item.status }}
"""
}
})
op updateItem(
@path id: integer,
@body item: UpdateItemRequest
): Item;
新增 DELETE 操作
簡單 DELETE
/**
* Delete an item.
* @param id The ID of the item to delete
*/
@route("/items/{id}")
@delete op deleteItem(@path id: integer): void;
帶有確認機制的 DELETE
/**
* Delete an item with confirmation.
*/
@route("/items/{id}")
@delete
@capabilities(#{
confirmation: #{
type: "AdaptiveCard",
title: "Delete Item",
body: """
⚠️ Are you sure you want to delete item #{{ function.parameters.id }}?
This action cannot be undone.
"""
}
})
op deleteItem(@path id: integer): void;
完整 CRUD 範例
定義服務與模型
@service
@server("https://api.example.com")
@actions(#{
nameForHuman: "Items API",
descriptionForHuman: "Manage items",
descriptionForModel: "Read, create, update, and delete items"
})
namespace ItemsAPI {
// Models
model Item {
@visibility(Lifecycle.Read)
id: integer;
userId: integer;
title: string;
description?: string;
status: "active" | "completed" | "archived";
@format("date-time")
createdAt: utcDateTime;
@format("date-time")
updatedAt?: utcDateTime;
}
model CreateItemRequest {
userId: integer;
title: string;
description?: string;
}
model UpdateItemRequest {
title?: string;
description?: string;
status?: "active" | "completed" | "archived";
}
// Operations
@route("/items")
@card(#{ dataPath: "$", title: "$.title", file: "item-card.json" })
@get op listItems(@query userId?: integer): Item[];
@route("/items/{id}")
@card(#{ dataPath: "$", title: "$.title", file: "item-card.json" })
@get op getItem(@path id: integer): Item;
@route("/items")
@post
@capabilities(#{
confirmation: #{
type: "AdaptiveCard",
title: "Create Item",
body: "Creating: **{{ function.parameters.item.title }}**"
}
})
op createItem(@body item: CreateItemRequest): Item;
@route("/items/{id}")
@patch
@capabilities(#{
confirmation: #{
type: "AdaptiveCard",
title: "Update Item",
body: "Updating item #{{ function.parameters.id }}"
}
})
op updateItem(@path id: integer, @body item: UpdateItemRequest): Item;
@route("/items/{id}")
@delete
@capabilities(#{
confirmation: #{
type: "AdaptiveCard",
title: "Delete Item",
body: "⚠️ Delete item #{{ function.parameters.id }}?"
}
})
op deleteItem(@path id: integer): void;
}
進階功能
多個 Query 參數
@route("/items")
@get op listItems(
@query userId?: integer,
@query status?: "active" | "completed" | "archived",
@query limit?: integer,
@query offset?: integer
): ItemList;
model ItemList {
items: Item[];
total: integer;
hasMore: boolean;
}
Header 參數
@route("/items")
@get op listItems(
@header("X-API-Version") apiVersion?: string,
@query userId?: integer
): Item[];
自訂回應模型
@route("/items/{id}")
@delete op deleteItem(@path id: integer): DeleteResponse;
model DeleteResponse {
success: boolean;
message: string;
deletedId: integer;
}
錯誤回應
model ErrorResponse {
error: {
code: string;
message: string;
details?: string[];
};
}
@route("/items/{id}")
@get op getItem(@path id: integer): Item | ErrorResponse;
測試提示詞
新增操作後,可以使用以下提示詞進行測試:
GET 操作:
- 「列出所有項目並以表格顯示」
- 「顯示使用者 ID 為 1 的項目」
- 「取得項目 42 的詳細資料」
POST 操作:
- 「為使用者 1 建立一個標題為『My Task』的新項目」
- 「新增一個項目:標題『New Feature』,描述『Add login』」
PATCH 操作:
- 「將項目 10 的標題更新為『Updated Title』」
- 「將項目 5 的狀態變更為已完成 (completed)」
DELETE 操作:
- 「刪除項目 99」
- 「移除 ID 為 15 的項目」
最佳實踐
參數命名
- 使用具描述性的參數名稱:使用
userId而非uid - 在各個操作之間保持一致
- 使用可選參數 (
?) 作為篩選條件
文件說明
- 為所有操作新增 JSDoc 註解
- 說明每個參數的作用
- 記錄預期的回應格式
模型
- 唯讀欄位(如
id)請使用@visibility(Lifecycle.Read) - 日期欄位請使用
@format("date-time") - 列舉 (Enums) 請使用聯合類型 (Union types):
"active" | "completed" - 可選欄位請明確標示
?
確認機制
- 務必為破壞性操作 (DELETE、PATCH) 新增確認機制
- 在確認訊息主體中顯示關鍵細節
- 對於不可逆的操作,使用警告 Emoji (⚠️)
Adaptive Cards
- 保持卡片設計簡潔且主題明確
- 使用
${if(..., ..., 'N/A')}進行條件式渲染 - 包含常用後續步驟的動作按鈕 (Action buttons)
- 使用真實的 API 回應資料測試資料繫結 (Data binding)
路由設定
- 遵循 RESTful 設計規範:
GET /items— 清單列表GET /items/{id}— 取得單一項目POST /items— 建立項目PATCH /items/{id}— 更新項目DELETE /items/{id}— 刪除項目
- 將相關操作歸類在同一個命名空間 (Namespace)
- 階層式資源請使用巢狀路由
常見問題
問題:參數未出現在 Copilot 中
解決方案:檢查參數是否已正確加上 @query、@path 或 @body 裝飾器
問題:Adaptive Card 無法渲染
解決方案:確認 @card 裝飾器中的檔案路徑,並檢查 JSON 語法
問題:確認畫面未顯示
解決方案:確保 @capabilities 裝飾器中的確認物件格式正確
問題:模型屬性未出現在回應中
解決方案:檢查屬性是否需要加上 @visibility(Lifecycle.Read),或者若屬性應為可寫入則將其移除






