typespec-api-operations
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAdd TypeSpec API Operations
为TypeSpec API添加操作
Add RESTful operations to an existing TypeSpec API plugin for Microsoft 365 Copilot.
为Microsoft 365 Copilot的现有TypeSpec API插件添加RESTful操作。
Adding GET Operations
添加GET操作
Simple GET - List All Items
简单GET - 列出所有条目
typescript
/**
* List all items.
*/
@route("/items")
@get op listItems(): Item[];typescript
/**
* List all items.
*/
@route("/items")
@get op listItems(): Item[];GET with Query Parameter - Filter Results
带查询参数的GET - 过滤结果
typescript
/**
* List items filtered by criteria.
* @param userId Optional user ID to filter items
*/
@route("/items")
@get op listItems(@query userId?: integer): Item[];typescript
/**
* List items filtered by criteria.
* @param userId Optional user ID to filter items
*/
@route("/items")
@get op listItems(@query userId?: integer): Item[];GET with Path Parameter - Get Single Item
带路径参数的GET - 获取单个条目
typescript
/**
* 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;typescript
/**
* 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 with Adaptive Card
带自适应卡片的GET
typescript
/**
* List items with adaptive card visualization.
*/
@route("/items")
@card(#{
dataPath: "$",
title: "$.title",
file: "item-card.json"
})
@get op listItems(): Item[];Create the Adaptive Card ():
appPackage/item-card.jsonjson
{
"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}"
}
]
}typescript
/**
* List items with adaptive card visualization.
*/
@route("/items")
@card(#{
dataPath: "$",
title: "$.title",
file: "item-card.json"
})
@get op listItems(): Item[];创建自适应卡片 ():
appPackage/item-card.jsonjson
{
"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}"
}
]
}Adding POST Operations
添加POST操作
Simple POST - Create Item
简单POST - 创建条目
typescript
/**
* 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;
}typescript
/**
* 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 with Confirmation
带确认机制的POST
typescript
/**
* 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;typescript
/**
* 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;Adding PATCH Operations
添加PATCH操作
Simple PATCH - Update Item
简单PATCH - 更新条目
typescript
/**
* 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";
}typescript
/**
* 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 with Confirmation
带确认机制的PATCH
typescript
/**
* 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;typescript
/**
* 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;Adding DELETE Operations
添加DELETE操作
Simple DELETE
简单DELETE
typescript
/**
* Delete an item.
* @param id The ID of the item to delete
*/
@route("/items/{id}")
@delete op deleteItem(@path id: integer): void;typescript
/**
* Delete an item.
* @param id The ID of the item to delete
*/
@route("/items/{id}")
@delete op deleteItem(@path id: integer): void;DELETE with Confirmation
带确认机制的DELETE
typescript
/**
* 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;typescript
/**
* 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;Complete CRUD Example
完整CRUD示例
Define the Service and Models
定义服务与模型
typescript
@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;
}typescript
@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;
}Advanced Features
高级功能
Multiple Query Parameters
多查询参数
typescript
@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;
}typescript
@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 Parameters
请求头参数
typescript
@route("/items")
@get op listItems(
@header("X-API-Version") apiVersion?: string,
@query userId?: integer
): Item[];typescript
@route("/items")
@get op listItems(
@header("X-API-Version") apiVersion?: string,
@query userId?: integer
): Item[];Custom Response Models
自定义响应模型
typescript
@route("/items/{id}")
@delete op deleteItem(@path id: integer): DeleteResponse;
model DeleteResponse {
success: boolean;
message: string;
deletedId: integer;
}typescript
@route("/items/{id}")
@delete op deleteItem(@path id: integer): DeleteResponse;
model DeleteResponse {
success: boolean;
message: string;
deletedId: integer;
}Error Responses
错误响应
typescript
model ErrorResponse {
error: {
code: string;
message: string;
details?: string[];
};
}
@route("/items/{id}")
@get op getItem(@path id: integer): Item | ErrorResponse;typescript
model ErrorResponse {
error: {
code: string;
message: string;
details?: string[];
};
}
@route("/items/{id}")
@get op getItem(@path id: integer): Item | ErrorResponse;Testing Prompts
测试提示
After adding operations, test with these prompts:
GET Operations:
- "List all items and show them in a table"
- "Show me items for user ID 1"
- "Get the details of item 42"
POST Operations:
- "Create a new item with title 'My Task' for user 1"
- "Add an item: title 'New Feature', description 'Add login'"
PATCH Operations:
- "Update item 10 with title 'Updated Title'"
- "Change the status of item 5 to completed"
DELETE Operations:
- "Delete item 99"
- "Remove the item with ID 15"
添加操作后,使用以下提示进行测试:
GET操作测试:
- "List all items and show them in a table"
- "Show me items for user ID 1"
- "Get the details of item 42"
POST操作测试:
- "Create a new item with title 'My Task' for user 1"
- "Add an item: title 'New Feature', description 'Add login'"
PATCH操作测试:
- "Update item 10 with title 'Updated Title'"
- "Change the status of item 5 to completed"
DELETE操作测试:
- "Delete item 99"
- "Remove the item with ID 15"
Best Practices
最佳实践
Parameter Naming
参数命名
- Use descriptive parameter names: not
userIduid - Be consistent across operations
- Use optional parameters () for filters
?
- 使用具有描述性的参数名称:而非
userIduid - 保持所有操作的参数命名一致性
- 对筛选条件使用可选参数()
?
Documentation
文档编写
- Add JSDoc comments to all operations
- Describe what each parameter does
- Document expected responses
- 为所有操作添加JSDoc注释
- 描述每个参数的作用
- 记录预期的响应结果
Models
模型设计
- Use for read-only fields like
@visibility(Lifecycle.Read)id - Use for date fields
@format("date-time") - Use union types for enums:
"active" | "completed" - Make optional fields explicit with
?
- 对等只读字段使用
id@visibility(Lifecycle.Read) - 对日期字段使用
@format("date-time") - 使用联合类型定义枚举值:
"active" | "completed" - 用明确标记可选字段
?
Confirmations
确认机制
- Always add confirmations to destructive operations (DELETE, PATCH)
- Show key details in confirmation body
- Use warning emoji (⚠️) for irreversible actions
- 对DELETE、PATCH等破坏性操作始终添加确认机制
- 在确认内容中显示关键信息
- 对不可逆操作使用警告表情(⚠️)
Adaptive Cards
自适应卡片
- Keep cards simple and focused
- Use conditional rendering with
${if(..., ..., 'N/A')} - Include action buttons for common next steps
- Test data binding with actual API responses
- 保持卡片简洁且聚焦核心信息
- 使用实现条件渲染
${if(..., ..., 'N/A')} - 包含常用后续操作的按钮
- 结合实际API响应测试数据绑定
Routing
路由设计
- Use RESTful conventions:
- - List
GET /items - - Get one
GET /items/{id} - - Create
POST /items - - Update
PATCH /items/{id} - - Delete
DELETE /items/{id}
- Group related operations in the same namespace
- Use nested routes for hierarchical resources
- 遵循RESTful规范:
- - 列出所有条目
GET /items - - 获取单个条目
GET /items/{id} - - 创建条目
POST /items - - 更新条目
PATCH /items/{id} - - 删除条目
DELETE /items/{id}
- 将相关操作归到同一命名空间
- 对层级化资源使用嵌套路由
Common Issues
常见问题排查
Issue: Parameter not showing in Copilot
问题:参数未在Copilot中显示
Solution: Check parameter is properly decorated with , , or
@query@path@body解决方案: 检查参数是否正确使用、或装饰器
@query@path@bodyIssue: Adaptive card not rendering
问题:自适应卡片未渲染
Solution: Verify file path in decorator and check JSON syntax
@card解决方案: 验证装饰器中的文件路径,并检查JSON语法是否正确
@cardIssue: Confirmation not appearing
问题:确认机制未触发
Solution: Ensure decorator is properly formatted with confirmation object
@capabilities解决方案: 确保装饰器中的确认对象格式正确
@capabilitiesIssue: Model property not appearing in response
问题:模型属性未在响应中显示
Solution: Check if property needs or remove it if it should be writable
@visibility(Lifecycle.Read)解决方案: 检查该字段是否需要添加,若为可写字段则移除该装饰器
@visibility(Lifecycle.Read)