You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过AWS CDK2代码向SNS发布JSON消息?

使用AWS CDK2实现SNS JSON消息发布(API集成场景)

方案一:Lambda + SNS(灵活可控,支持消息预处理)

这种方案通过Lambda作为中间层接收API请求,处理JSON消息后发布到SNS,适合需要对消息做验证、转换等逻辑的场景。

CDK代码示例(TypeScript)

import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as sns from 'aws-cdk-lib/aws-sns';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as apigateway from 'aws-cdk-lib/aws-apigateway';

export class SnsApiIntegrationStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // 创建SNS主题
    const snsTopic = new sns.Topic(this, 'JsonMessageTopic', {
      displayName: 'JSON消息接收主题',
    });

    // 创建处理消息发布的Lambda函数
    const publishLambda = new lambda.Function(this, 'PublishSnsLambda', {
      runtime: lambda.Runtime.NODEJS_18_X,
      handler: 'index.handler',
      code: lambda.Code.fromInline(`
        const AWS = require('aws-sdk');
        const sns = new AWS.SNS();

        exports.handler = async (event) => {
          try {
            // 解析API请求的JSON Body
            const jsonMessage = JSON.parse(event.body);
            
            // 发布JSON消息到SNS
            await sns.publish({
              TopicArn: process.env.SNS_TOPIC_ARN,
              Message: JSON.stringify(jsonMessage),
              MessageStructure: 'string'
            }).promise();

            return {
              statusCode: 200,
              body: JSON.stringify({ success: true, msg: '消息已发布到SNS' })
            };
          } catch (err) {
            return {
              statusCode: 500,
              body: JSON.stringify({ success: false, err: err.message })
            };
          }
        };
      `),
      environment: {
        SNS_TOPIC_ARN: snsTopic.topicArn,
      },
    });

    // 自动赋予Lambda发布SNS消息的权限
    snsTopic.grantPublish(publishLambda);

    // 配置API Gateway,将POST请求转发到Lambda
    const api = new apigateway.RestApi(this, 'SnsPublishApi', {
      restApiName: 'SNS消息发布API',
    });

    const publishResource = api.root.addResource('publish');
    publishResource.addMethod('POST', new apigateway.LambdaIntegration(publishLambda, { proxy: true }));

    // 输出API访问地址和SNS主题ARN
    new cdk.CfnOutput(this, 'ApiEndpoint', { value: `${api.url}publish` });
    new cdk.CfnOutput(this, 'SnsTopicArn', { value: snsTopic.topicArn });
  }
}

核心说明

  • Lambda使用AWS SDK v2(Node.js 18+ runtime自带)调用SNS publish接口,将JSON消息序列化为字符串发布
  • 通过grantPublish方法自动生成IAM权限,无需手动编写Policy
  • API Gateway采用Lambda代理集成,直接传递请求参数和响应

方案二:API Gateway直接集成SNS(轻量无服务器,无Lambda依赖)

如果不需要对消息做额外处理,可直接通过API Gateway的AWS集成调用SNS,省去Lambda层。

CDK代码示例(TypeScript)

import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as sns from 'aws-cdk-lib/aws-sns';
import * as apigateway from 'aws-cdk-lib/aws-apigateway';
import * as iam from 'aws-cdk-lib/aws-iam';

export class DirectSnsApiIntegrationStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // 创建SNS主题
    const snsTopic = new sns.Topic(this, 'DirectJsonTopic');

    // 创建API Gateway
    const api = new apigateway.RestApi(this, 'DirectSnsPublishApi');

    // 配置API Gateway到SNS的集成
    const snsIntegration = new apigateway.AwsIntegration({
      service: 'sns',
      action: 'Publish',
      options: {
        // 创建API Gateway调用SNS的IAM角色
        credentialsRole: new iam.Role(this, 'ApiGatewaySnsRole', {
          assumedBy: new iam.ServicePrincipal('apigateway.amazonaws.com'),
          managedPolicies: [
            iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonSNSFullAccess')
          ]
        }),
        // 映射请求参数到SNS Publish接口
        requestTemplates: {
          'application/json': `{
            "TopicArn": "${snsTopic.topicArn}",
            "Message": "$input.body"
          }`
        },
        integrationResponses: [
          {
            statusCode: '200',
            responseTemplates: {
              'application/json': '{ "success": true, "msg": "消息发布成功" }'
            }
          }
        ]
      }
    });

    // 添加API资源和POST方法
    const publishResource = api.root.addResource('direct-publish');
    publishResource.addMethod('POST', snsIntegration, {
      methodResponses: [{ statusCode: '200' }]
    });

    // 输出API访问地址
    new cdk.CfnOutput(this, 'DirectApiEndpoint', { value: `${api.url}direct-publish` });
  }
}

核心说明

  • 直接利用API Gateway的AWS集成能力调用SNS的Publish动作
  • 需创建IAM角色赋予API Gateway调用SNS的权限
  • 通过请求模板将API的JSON Body直接映射为SNS的Message参数

部署验证

  1. 执行cdk deploy部署栈
  2. 调用输出的API地址,发送POST请求,Body为JSON格式数据
  3. 查看SNS主题的订阅者(如邮箱、Lambda)是否收到消息

内容的提问来源于stack exchange,提问作者Sam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 20:15:11