关于 typespec-api-operations
typespec-api-operations 是一项技能,用于为 Microsoft 365 Copilot 的现有 TypeSpec API 插件添加 REST 操作。内容涵盖 CRUD 模式、参数、确认机制、自适应卡片和测试提示词。
主要功能
- 01GET、POST、PATCH 和 DELETE 示例
- 02路径、查询、正文和标头参数
- 03确认机制与自适应卡片模式
- 04响应模型和错误响应
- 05路由与文档编写指南
适用场景
- 01为 TypeSpec API 添加 CRUD 操作
- 02定义筛选条件和条目标识符
- 03为破坏性操作添加确认
- 04通过提示词检查 Copilot API 操作
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ github/ awesome-copilot --skill typespec-api-operations安装后在 Claude Code 中输入/typespec-api-operations确认已加载。
详细介绍
添加 TypeSpec API 操作
为现有 Microsoft 365 Copilot 的 TypeSpec API 插件添加 RESTful 操作。
添加 GET 操作
简单 GET - 列出所有项目
/**
* List all items.
*/
@route("/items")
@get op listItems(): Item[];
带查询参数的 GET - 筛选结果
/**
* List items filtered by criteria.
* @param userId Optional user ID to filter items
*/
@route("/items")
@get op listItems(@query userId?: integer): Item[];
带路径参数的 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;
带自适应卡片的 GET
/**
* List items with adaptive card visualization.
*/
@route("/items")
@card(#{
dataPath: "$",
title: "$.title",
file: "item-card.json"
})
@get op listItems(): Item[];
创建自适应卡片(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;
}
高级功能
多个查询参数
@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;
}
标头参数
@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") - 对枚举使用联合类型:
"active" | "completed" - 使用
?明确标记可选字段
确认
- 始终为破坏性操作(DELETE、PATCH)添加确认
- 在确认正文中显示关键详情
- 对不可逆操作使用警告 emoji(⚠️)
自适应卡片
- 保持卡片简洁且聚焦
- 使用
${if(..., ..., 'N/A')}进行条件渲染 - 为常见后续步骤添加操作按钮
- 使用实际 API 响应测试数据绑定
路由
- 使用 RESTful 约定:
GET /items- 列出GET /items/{id}- 获取单个POST /items- 创建PATCH /items/{id}- 更新DELETE /items/{id}- 删除
- 将相关操作归入同一命名空间
- 对分层资源使用嵌套路由
常见问题
问题:参数未在 Copilot 中显示
解决方案:检查参数是否正确使用了 @query、@path 或 @body 装饰
问题:自适应卡片未渲染
解决方案:验证 @card 装饰器中的文件路径,并检查 JSON 语法
问题:确认未出现
解决方案:确保 @capabilities 装饰器与 confirmation 对象格式正确
问题:模型属性未在响应中出现
解决方案:检查该属性是否需要 @visibility(Lifecycle.Read),如果应可写则移除该装饰
评论
支持 Markdown