AsyncAPI撰写技能Skill asyncapi-authoring

此技能用于撰写和验证AsyncAPI 3.0规范,专注于事件驱动API设计、消息代理和异步通信模式,包括通道、操作、消息定义等,支持架构规划和最佳实践。关键词:AsyncAPI, 事件驱动, API设计, 消息代理, 异步通信, 规范验证, 架构设计

架构设计 0 次安装 0 次浏览 更新于 3/11/2026

name: asyncapi-authoring description: 撰写和验证AsyncAPI 3.0规范,用于事件驱动API设计、消息代理和异步通信模式 allowed-tools: Read, Write, Edit, Glob, Grep, Bash

AsyncAPI 撰写技能

何时使用此技能

在以下情况下使用此技能:

  • AsyncAPI 撰写任务 - 处理撰写和验证AsyncAPI 3.0规范,用于事件驱动API设计、消息代理和异步通信模式
  • 规划或设计 - 需要AsyncAPI 撰写方法的指导
  • 最佳实践 - 希望遵循已建立的模式和标准

概述

为事件驱动架构和异步通信模式撰写AsyncAPI 3.0规范。

AsyncAPI 3.0 结构

根文档

asyncapi: "3.0.0"

info:
  title: "{服务名称} 事件 API"
  version: "1.0.0"
  description: |
    用于{service}领域事件和命令的事件驱动API。
  contact:
    name: "{团队名称}"
    email: "{team@company.com}"
  license:
    name: "MIT"

servers:
  production:
    host: "kafka.example.com:9092"
    protocol: "kafka"
    description: "生产Kafka集群"
    security:
      - $ref: "#/components/securitySchemes/sasl"

  development:
    host: "localhost:9092"
    protocol: "kafka"
    description: "本地开发环境"

defaultContentType: "application/json"

channels:
  # 通道定义

operations:
  # 操作定义

components:
  # 可重用组件

通道 (AsyncAPI 3.0)

channels:
  orderEvents:
    address: "orders.events.{orderId}"
    description: "订单生命周期事件的通道"
    parameters:
      orderId:
        description: "订单唯一标识符"
        schema:
          type: string
          format: uuid
    messages:
      orderCreated:
        $ref: "#/components/messages/OrderCreated"
      orderShipped:
        $ref: "#/components/messages/OrderShipped"
      orderDelivered:
        $ref: "#/components/messages/OrderDelivered"
      orderCancelled:
        $ref: "#/components/messages/OrderCancelled"

  orderCommands:
    address: "orders.commands"
    description: "订单命令消息的通道"
    messages:
      createOrder:
        $ref: "#/components/messages/CreateOrderCommand"
      cancelOrder:
        $ref: "#/components/messages/CancelOrderCommand"

  inventoryUpdates:
    address: "inventory.updates.{productId}"
    description: "实时库存级别更新"
    parameters:
      productId:
        schema:
          type: string
    messages:
      inventoryChanged:
        $ref: "#/components/messages/InventoryChanged"

操作 (AsyncAPI 3.0)

operations:
  # 发布操作(此服务发送)
  publishOrderCreated:
    action: send
    channel:
      $ref: "#/channels/orderEvents"
    summary: "发布订单创建事件"
    description: |
      当新订单成功创建时发布。
      消费者应使用此事件触发下游流程。
    messages:
      - $ref: "#/channels/orderEvents/messages/orderCreated"
    tags:
      - name: "orders"
      - name: "lifecycle"

  publishOrderShipped:
    action: send
    channel:
      $ref: "#/channels/orderEvents"
    summary: "发布订单发货事件"
    messages:
      - $ref: "#/channels/orderEvents/messages/orderShipped"

  # 接收操作(此服务接收)
  receiveCreateOrderCommand:
    action: receive
    channel:
      $ref: "#/channels/orderCommands"
    summary: "处理创建订单命令"
    description: |
      接收创建新订单的命令。
      成功后将发布OrderCreated事件。
    messages:
      - $ref: "#/channels/orderCommands/messages/createOrder"

  # 订阅操作
  subscribeInventoryUpdates:
    action: receive
    channel:
      $ref: "#/channels/inventoryUpdates"
    summary: "订阅库存变更"
    description: |
      订阅实时库存更新。
      用于维护本地库存缓存。
    messages:
      - $ref: "#/channels/inventoryUpdates/messages/inventoryChanged"

消息定义

components:
  messages:
    OrderCreated:
      name: "OrderCreated"
      title: "订单创建事件"
      summary: "表示新订单已创建"
      contentType: "application/json"
      headers:
        $ref: "#/components/schemas/EventHeaders"
      payload:
        $ref: "#/components/schemas/OrderCreatedPayload"
      correlationId:
        location: "$message.header#/correlationId"
      traits:
        - $ref: "#/components/messageTraits/commonHeaders"

    OrderShipped:
      name: "OrderShipped"
      title: "订单发货事件"
      summary: "表示订单已发货"
      contentType: "application/json"
      headers:
        $ref: "#/components/schemas/EventHeaders"
      payload:
        $ref: "#/components/schemas/OrderShippedPayload"
      traits:
        - $ref: "#/components/messageTraits/commonHeaders"

    OrderCancelled:
      name: "OrderCancelled"
      title: "订单取消事件"
      summary: "表示订单已取消"
      contentType: "application/json"
      headers:
        $ref: "#/components/schemas/EventHeaders"
      payload:
        $ref: "#/components/schemas/OrderCancelledPayload"

    CreateOrderCommand:
      name: "CreateOrderCommand"
      title: "创建订单命令"
      summary: "创建新订单的命令"
      contentType: "application/json"
      headers:
        $ref: "#/components/schemas/CommandHeaders"
      payload:
        $ref: "#/components/schemas/CreateOrderPayload"

    InventoryChanged:
      name: "InventoryChanged"
      title: "库存变更事件"
      summary: "实时库存级别更新"
      contentType: "application/json"
      payload:
        $ref: "#/components/schemas/InventoryChangedPayload"

负载模式

components:
  schemas:
    # 事件头部
    EventHeaders:
      type: object
      required:
        - eventId
        - eventType
        - timestamp
        - version
      properties:
        eventId:
          type: string
          format: uuid
          description: "唯一事件标识符"
        eventType:
          type: string
          description: "事件类型名称"
        timestamp:
          type: string
          format: date-time
          description: "事件时间戳 (ISO 8601)"
        version:
          type: string
          description: "事件模式版本"
          example: "1.0"
        correlationId:
          type: string
          format: uuid
          description: "用于追踪的相关ID"
        causationId:
          type: string
          format: uuid
          description: "导致此事件的事件/命令ID"

    CommandHeaders:
      type: object
      required:
        - commandId
        - commandType
        - timestamp
      properties:
        commandId:
          type: string
          format: uuid
          description: "唯一命令标识符"
        commandType:
          type: string
          description: "命令类型名称"
        timestamp:
          type: string
          format: date-time
        correlationId:
          type: string
          format: uuid
        userId:
          type: string
          description: "发起命令的用户"

    # 事件负载
    OrderCreatedPayload:
      type: object
      required:
        - orderId
        - customerId
        - items
        - totalAmount
        - createdAt
      properties:
        orderId:
          type: string
          format: uuid
        customerId:
          type: string
          format: uuid
        items:
          type: array
          items:
            $ref: "#/components/schemas/OrderItem"
        totalAmount:
          $ref: "#/components/schemas/Money"
        shippingAddress:
          $ref: "#/components/schemas/Address"
        createdAt:
          type: string
          format: date-time

    OrderShippedPayload:
      type: object
      required:
        - orderId
        - trackingNumber
        - carrier
        - shippedAt
      properties:
        orderId:
          type: string
          format: uuid
        trackingNumber:
          type: string
        carrier:
          type: string
          enum:
            - "fedex"
            - "ups"
            - "usps"
            - "dhl"
        estimatedDelivery:
          type: string
          format: date
        shippedAt:
          type: string
          format: date-time

    OrderCancelledPayload:
      type: object
      required:
        - orderId
        - reason
        - cancelledAt
      properties:
        orderId:
          type: string
          format: uuid
        reason:
          type: string
          enum:
            - "customer_request"
            - "payment_failed"
            - "out_of_stock"
            - "fraud_detected"
        refundAmount:
          $ref: "#/components/schemas/Money"
        cancelledAt:
          type: string
          format: date-time
        cancelledBy:
          type: string
          description: "取消订单的用户或系统"

    # 命令负载
    CreateOrderPayload:
      type: object
      required:
        - customerId
        - items
      properties:
        customerId:
          type: string
          format: uuid
        items:
          type: array
          minItems: 1
          items:
            $ref: "#/components/schemas/OrderItemRequest"
        shippingAddress:
          $ref: "#/components/schemas/Address"
        billingAddress:
          $ref: "#/components/schemas/Address"
        couponCode:
          type: string

    # 领域模式
    OrderItem:
      type: object
      required:
        - productId
        - productName
        - quantity
        - unitPrice
      properties:
        productId:
          type: string
          format: uuid
        productName:
          type: string
        quantity:
          type: integer
          minimum: 1
        unitPrice:
          $ref: "#/components/schemas/Money"

    OrderItemRequest:
      type: object
      required:
        - productId
        - quantity
      properties:
        productId:
          type: string
          format: uuid
        quantity:
          type: integer
          minimum: 1

    Money:
      type: object
      required:
        - amount
        - currency
      properties:
        amount:
          type: number
          format: decimal
          minimum: 0
        currency:
          type: string
          pattern: "^[A-Z]{3}$"
          example: "USD"

    Address:
      type: object
      required:
        - street
        - city
        - country
      properties:
        street:
          type: string
        city:
          type: string
        state:
          type: string
        postalCode:
          type: string
        country:
          type: string
          pattern: "^[A-Z]{2}$"

    InventoryChangedPayload:
      type: object
      required:
        - productId
        - previousQuantity
        - newQuantity
        - reason
        - changedAt
      properties:
        productId:
          type: string
          format: uuid
        previousQuantity:
          type: integer
        newQuantity:
          type: integer
        reason:
          type: string
          enum:
            - "sale"
            - "return"
            - "restock"
            - "adjustment"
            - "reservation"
        changedAt:
          type: string
          format: date-time

消息特性和安全

components:
  messageTraits:
    commonHeaders:
      headers:
        type: object
        properties:
          x-trace-id:
            type: string
            description: "分布式追踪ID"
          x-span-id:
            type: string
            description: "用于追踪的Span ID"

  securitySchemes:
    sasl:
      type: scramSha256
      description: "SASL/SCRAM-SHA-256认证"

    apiKey:
      type: apiKey
      in: user
      description: "API密钥认证"

    oauth2:
      type: oauth2
      flows:
        clientCredentials:
          tokenUrl: "https://auth.example.com/token"
          scopes:
            "events:publish": "发布事件"
            "events:subscribe": "订阅事件"

  serverBindings:
    kafka:
      schemaRegistryUrl: "https://schema-registry.example.com"
      schemaRegistryVendor: "confluent"

AsyncAPI的C#模型

namespace SpecDrivenDevelopment.AsyncApi;

/// <summary>
/// 表示一个AsyncAPI 3.0规范文档
/// </summary>
public record AsyncApiSpec
{
    public required string AsyncApi { get; init; } = "3.0.0";
    public required AsyncApiInfo Info { get; init; }
    public Dictionary<string, AsyncApiServer> Servers { get; init; } = [];
    public string? DefaultContentType { get; init; }
    public Dictionary<string, AsyncApiChannel> Channels { get; init; } = [];
    public Dictionary<string, AsyncApiOperation> Operations { get; init; } = [];
    public AsyncApiComponents? Components { get; init; }
}

public record AsyncApiInfo
{
    public required string Title { get; init; }
    public required string Version { get; init; }
    public string? Description { get; init; }
    public AsyncApiContact? Contact { get; init; }
    public AsyncApiLicense? License { get; init; }
}

public record AsyncApiContact
{
    public string? Name { get; init; }
    public string? Email { get; init; }
    public string? Url { get; init; }
}

public record AsyncApiLicense
{
    public required string Name { get; init; }
    public string? Url { get; init; }
}

public record AsyncApiServer
{
    public required string Host { get; init; }
    public required string Protocol { get; init; }
    public string? ProtocolVersion { get; init; }
    public string? Description { get; init; }
    public List<Dictionary<string, List<string>>>? Security { get; init; }
    public Dictionary<string, object>? Bindings { get; init; }
}

public record AsyncApiChannel
{
    public required string Address { get; init; }
    public string? Description { get; init; }
    public Dictionary<string, AsyncApiParameter>? Parameters { get; init; }
    public Dictionary<string, AsyncApiMessage>? Messages { get; init; }
    public Dictionary<string, object>? Bindings { get; init; }
}

public record AsyncApiParameter
{
    public string? Description { get; init; }
    public AsyncApiSchema? Schema { get; init; }
    public string? Location { get; init; }
}

public record AsyncApiOperation
{
    public required OperationAction Action { get; init; }
    public required AsyncApiChannelRef Channel { get; init; }
    public string? Summary { get; init; }
    public string? Description { get; init; }
    public List<AsyncApiMessageRef>? Messages { get; init; }
    public List<AsyncApiTag>? Tags { get; init; }
    public List<Dictionary<string, List<string>>>? Security { get; init; }
    public Dictionary<string, object>? Bindings { get; init; }
}

public enum OperationAction
{
    Send,
    Receive
}

public record AsyncApiChannelRef
{
    public string? Ref { get; init; }
}

public record AsyncApiMessageRef
{
    public string? Ref { get; init; }
}

public record AsyncApiMessage
{
    public string? Name { get; init; }
    public string? Title { get; init; }
    public string? Summary { get; init; }
    public string? Description { get; init; }
    public string? ContentType { get; init; }
    public AsyncApiSchema? Headers { get; init; }
    public AsyncApiSchema? Payload { get; init; }
    public AsyncApiCorrelationId? CorrelationId { get; init; }
    public List<AsyncApiMessageTraitRef>? Traits { get; init; }
    public Dictionary<string, object>? Bindings { get; init; }
}

public record AsyncApiCorrelationId
{
    public string? Description { get; init; }
    public required string Location { get; init; }
}

public record AsyncApiMessageTraitRef
{
    public string? Ref { get; init; }
}

public record AsyncApiTag
{
    public required string Name { get; init; }
    public string? Description { get; init; }
}

public record AsyncApiSchema
{
    public string? Type { get; init; }
    public string? Format { get; init; }
    public string? Description { get; init; }
    public List<string>? Enum { get; init; }
    public object? Default { get; init; }
    public object? Example { get; init; }
    public List<string>? Required { get; init; }
    public Dictionary<string, AsyncApiSchema>? Properties { get; init; }
    public AsyncApiSchema? Items { get; init; }
    public int? MinItems { get; init; }
    public int? MaxItems { get; init; }
    public int? MinLength { get; init; }
    public int? MaxLength { get; init; }
    public decimal? Minimum { get; init; }
    public decimal? Maximum { get; init; }
    public string? Pattern { get; init; }
    public List<AsyncApiSchema>? AllOf { get; init; }
    public List<AsyncApiSchema>? OneOf { get; init; }
    public List<AsyncApiSchema>? AnyOf { get; init; }
    public string? Ref { get; init; }
}

public record AsyncApiComponents
{
    public Dictionary<string, AsyncApiSchema>? Schemas { get; init; }
    public Dictionary<string, AsyncApiMessage>? Messages { get; init; }
    public Dictionary<string, AsyncApiParameter>? Parameters { get; init; }
    public Dictionary<string, AsyncApiSecurityScheme>? SecuritySchemes { get; init; }
    public Dictionary<string, AsyncApiMessageTrait>? MessageTraits { get; init; }
    public Dictionary<string, AsyncApiOperationTrait>? OperationTraits { get; init; }
}

public record AsyncApiSecurityScheme
{
    public required string Type { get; init; }
    public string? Description { get; init; }
    public string? In { get; init; }
    public string? Name { get; init; }
    public AsyncApiOAuthFlows? Flows { get; init; }
}

public record AsyncApiOAuthFlows
{
    public AsyncApiOAuthFlow? ClientCredentials { get; init; }
}

public record AsyncApiOAuthFlow
{
    public required string TokenUrl { get; init; }
    public required Dictionary<string, string> Scopes { get; init; }
}

public record AsyncApiMessageTrait
{
    public AsyncApiSchema? Headers { get; init; }
    public string? ContentType { get; init; }
}

public record AsyncApiOperationTrait
{
    public string? Summary { get; init; }
    public string? Description { get; init; }
    public List<AsyncApiTag>? Tags { get; init; }
}

事件设计模式

事件命名约定

event_naming:
  format: "{聚合}{动作}"

  past_tense_events:
    description: "事件描述已发生的事情"
    examples:
      - "OrderCreated"
      - "OrderShipped"
      - "PaymentProcessed"
      - "UserRegistered"
      - "InventoryReserved"

  command_naming:
    format: "{动作}{聚合}Command"
    examples:
      - "CreateOrderCommand"
      - "CancelOrderCommand"
      - "ProcessPaymentCommand"

  channel_naming:
    pattern: "{领域}.{类型}.{资源}"
    examples:
      - "orders.events" (所有订单事件)
      - "orders.events.{orderId}" (特定订单)
      - "orders.commands" (订单命令)
      - "inventory.updates.{productId}" (库存变更)

事件信封模式

event_envelope:
  description: "所有事件的标准包装器"

  structure:
    metadata:
      eventId: "UUID - 唯一事件ID"
      eventType: "字符串 - 事件类型名称"
      version: "字符串 - 模式版本"
      timestamp: "ISO 8601时间戳"
      correlationId: "UUID - 请求相关ID"
      causationId: "UUID - 导致此事件的事件/命令ID"
      source: "字符串 - 生产服务"

    data: "实际事件负载"

  example:
    metadata:
      eventId: "550e8400-e29b-41d4-a716-446655440000"
      eventType: "OrderCreated"
      version: "1.0"
      timestamp: "2025-01-15T10:30:00Z"
      correlationId: "660e8400-e29b-41d4-a716-446655440001"
      source: "order-service"
    data:
      orderId: "order-123"
      customerId: "customer-456"
      totalAmount:
        amount: 99.99
        currency: "USD"

模式演化

schema_evolution:
  strategies:
    backward_compatible:
      description: "新模式可以读取旧数据"
      allowed_changes:
        - "添加可选字段"
        - "在末尾添加新枚举值"
        - "扩展数字范围"
      disallowed_changes:
        - "移除必需字段"
        - "更改字段类型"
        - "重命名字段"

    forward_compatible:
      description: "旧模式可以读取新数据"
      approach: "忽略未知字段"

    full_compatible:
      description: "双向兼容"
      best_practice: "大多数系统的默认实践"

  versioning:
    header_based:
      example: "version: '1.0'"

    channel_based:
      example: "orders.events.v2"

    semantic:
      format: "主版本.次版本"
      major: "重大变更"
      minor: "向后兼容的添加"

验证检查清单

asyncapi_validation_checklist:
  structure:
    - "有效的AsyncAPI 3.0.0语法"
    - "所有必需字段存在"
    - "没有未定义的$ref引用"
    - "一致的命名约定"

  channels:
    - "清晰的通道寻址方案"
    - "为动态通道定义参数"
    - "所有引用的消息存在"

  operations:
    - "操作(发送/接收)正确指定"
    - "通道引用有效"
    - "提供摘要和描述"
    - "分配适当的标签"

  messages:
    - "唯一的消息名称"
    - "清晰的标题和摘要"
    - "定义头部模式"
    - "完整的负载模式"
    - "需要时指定相关ID"

  schemas:
    - "列出所有必需字段"
    - "指定类型和格式"
    - "提供示例"
    - "适当的验证约束"

  security:
    - "为生产环境定义安全方案"
    - "操作指定安全需求"

  documentation:
    - "API描述解释目的"
    - "提供联系信息"
    - "所有环境的服务器URL"

参考资料

  • references/messaging-patterns.md - 事件驱动消息模式
  • references/protocol-bindings.md - 协议特定配置

最后更新: 2025-12-26