[{"data":1,"prerenderedAt":81},["ShallowReactive",2],{"content-guides-refactoring-serverless-send_message_via_pipes":3},{"markdown":4,"frontMatterAttributes":5,"bodyRaw":7,"contributorPaths":8,"menuType":12,"contentName":13,"slug":14,"readingTime":15,"menu":16,"nextDocItem":74,"previousDocItem":66},"\u003Cp>Original:\u003Cbr>\u003Cimg src=\"\u002Fassets\u002Fexternal\u002Fguides\u002Frefactoring-serverless\u002Fassets\u002Fimages\u002FSendMessagePipesOriginal.png\" alt=\"\">\u003C\u002Fp>\n\u003Cp>Refactored: \n\u003Cimg src=\"\u002Fassets\u002Fexternal\u002Fguides\u002Frefactoring-serverless\u002Fassets\u002Fimages\u002FSendMessagePipesRefactored.png\" alt=\"\">\u003C\u002Fp>\n\u003Ch2>Description\u003C\u002Fh2>\n\u003Cp>Updating a DynamoDB item and then sending a message to EventBridge or SNS from Lambda function code creates tighter coupling between event source and destination. It also runs the risk of inconsistent state in case one operation fails.\u003C\u002Fp>\n\u003Cp>An example might look as follows:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-js\"># Initialise clients\nconst AWS = require(&#39;aws-sdk&#39;);\nconst dynamodb = new AWS.DynamoDB.DocumentClient();\nconst eventBridge = new AWS.EventBridge();\n\ndomain_object =   # business logic here\n\nawait dynamodb.put(domain_object).promise();\n\ndomain_object_status_changed_event = {\n    # set fields\n}\nawait eventBridge.putEvents(\n      Entries: [\n        {\n          Source: &#39;my-source&#39;,\n          DetailType: &#39;order-details&#39;,\n          Detail: JSON.stringify(domain_object_status_changed_event),\n          EventBusName: process.env.EVENT_BUS_NAME\n        },\n      ],\n    }).promise();\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2>Solution\u003C\u002Fh2>\n\u003Cp>Connect an Amazon EventBridge Pipes instance to a DynamoDB Stream (see \u003Ca href=\"https:\u002F\u002Fdocs.aws.amazon.com\u002Feventbridge\u002Flatest\u002Fuserguide\u002Feb-pipes-dynamodb.html\">docs\u003C\u002Fa>) and remove message sending from the source code.\u003C\u002Fp>\n\u003Cp>See the CDK implementation of this pattern in Typescript on \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Faws-samples\u002Faws-refactoring-to-serverless\u002Fblob\u002Fmain\u002Fimplementation\u002Fsend-message-via-pipes\u002FREADME.md\">GitHub\u003C\u002Fa>.\u003C\u002Fp>\n\u003Ch2>Considerations\u003C\u002Fh2>\n\u003Ch4>Advantages\u003C\u002Fh4>\n\u003Cul>\n\u003Cli>Sending the event message is now handled by the serverless run-time without any additional code\u003C\u002Fli>\n\u003Cli>The event destination is now explicitly set within automation code as opposed to in the application code via an environment variable. This makes the application topology more explicit.\u003C\u002Fli>\n\u003Cli>The event format can be changed without changing the source code\u003C\u002Fli>\n\u003Cli>DynamoDB assures transactional integrity across updating the table and sending the event\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch4>Applicability\u003C\u002Fh4>\n\u003Cul>\n\u003Cli>\u003Cp>DynamoDB streams populate the event in the DynamoDB format, which isn&#39;t well suited for downstream consumers. Use the Pipes transformation step to convert the event into a domain-oriented format without DynamoDB specifics.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\u003Cp>The additional Pipes instance will incur a run-time cost\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\u003Cp>Pipes has less flexibility over some field definitions than the source code, e.g. \u003Ccode>Source\u003C\u002Fcode> and \u003Ccode>DetailType\u003C\u002Fcode>\u003C\u002Fp>\n\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch2>Related Refactorings\u003C\u002Fh2>\n\u003Cul>\n\u003Cli>\u003Ca href=\".\u002Fextract_send_message\">Extract Send Message\u003C\u002Fa>\u003C\u002Fli>\n\u003C\u002Ful>\n",{"title":6},"Send Message via Pipes","Original:  \n![](\u002Fassets\u002Fexternal\u002Fguides\u002Frefactoring-serverless\u002Fassets\u002Fimages\u002FSendMessagePipesOriginal.png)\n\nRefactored: \n![](\u002Fassets\u002Fexternal\u002Fguides\u002Frefactoring-serverless\u002Fassets\u002Fimages\u002FSendMessagePipesRefactored.png)\n\n## Description\n\nUpdating a DynamoDB item and then sending a message to EventBridge or SNS from Lambda function code creates tighter coupling between event source and destination. It also runs the risk of inconsistent state in case one operation fails.\n\nAn example might look as follows:\n\n```js\n# Initialise clients\nconst AWS = require('aws-sdk');\nconst dynamodb = new AWS.DynamoDB.DocumentClient();\nconst eventBridge = new AWS.EventBridge();\n\ndomain_object =   # business logic here\n\nawait dynamodb.put(domain_object).promise();\n\ndomain_object_status_changed_event = {\n    # set fields\n}\nawait eventBridge.putEvents(\n      Entries: [\n        {\n          Source: 'my-source',\n          DetailType: 'order-details',\n          Detail: JSON.stringify(domain_object_status_changed_event),\n          EventBusName: process.env.EVENT_BUS_NAME\n        },\n      ],\n    }).promise();\n```\n\n## Solution\n\nConnect an Amazon EventBridge Pipes instance to a DynamoDB Stream (see [docs](https:\u002F\u002Fdocs.aws.amazon.com\u002Feventbridge\u002Flatest\u002Fuserguide\u002Feb-pipes-dynamodb.html)) and remove message sending from the source code.\n\nSee the CDK implementation of this pattern in Typescript on [GitHub](https:\u002F\u002Fgithub.com\u002Faws-samples\u002Faws-refactoring-to-serverless\u002Fblob\u002Fmain\u002Fimplementation\u002Fsend-message-via-pipes\u002FREADME.md).\n\n## Considerations \n\n#### Advantages\n* Sending the event message is now handled by the serverless run-time without any additional code\n* The event destination is now explicitly set within automation code as opposed to in the application code via an environment variable. This makes the application topology more explicit.\n* The event format can be changed without changing the source code\n* DynamoDB assures transactional integrity across updating the table and sending the event\n\n#### Applicability\n\n* DynamoDB streams populate the event in the DynamoDB format, which isn't well suited for downstream consumers. Use the Pipes transformation step to convert the event into a domain-oriented format without DynamoDB specifics.\n\n* The additional Pipes instance will incur a run-time cost\n\n* Pipes has less flexibility over some field definitions than the source code, e.g. `Source` and `DetailType`\n\n## Related Refactorings\n- [Extract Send Message](.\u002Fextract_send_message)\n",[9,10,11],"content\u002Fcontributors\u002Fgregor-hohpe.json","content\u002Fcontributors\u002Fsindhu-pillai.json","content\u002Fcontributors\u002Fbhuvan-annamreddi.json","LIST","Refactoring to Serverless","\u002Fcontent\u002Fguides\u002Frefactoring-serverless\u002Fsend_message_via_pipes","2 min",[17,42],{"title":18,"content":19},"Introduction",[20],{"title":13,"order":21,"callout":22,"resources":26,"time":38,"path":39,"id":40,"link":41},1,{"title":23,"description":24,"link":25},"Watch the video","This session shows how you can refactor an existing serverless application to fully utilize AWS managed services and make service dependencies explicit, resulting in cleaner and more robust code.","https:\u002F\u002Fwww.youtube.com\u002Fwatch?v=F7wxgWaccHs",[27,31,34],{"link":28,"text":29,"type":30},"https:\u002F\u002Fwww.youtube.com\u002Fwatch?v=ttJAIQf7cTw","Building modern cloud applications? Think integration!","video",{"link":32,"text":33,"type":30},"https:\u002F\u002Fwww.youtube.com\u002Fwatch?v=Ud9h1hJgoKk","Modern cloud applications - do they lock you in?",{"link":35,"text":36,"type":37},"https:\u002F\u002Fcdkpatterns.com\u002Fpatterns\u002F","CDK Patterns Collection","website","3 min","introduction","introduction.md","\u002Fcontent\u002Fguides\u002Frefactoring-serverless\u002Fintroduction",{"title":43,"content":44},"Refactorings",[45,50,55,60,66,71,74],{"title":46,"time":15,"path":47,"id":48,"link":49},"Extract Send Message","extract_send_message","extract_send_message.md","\u002Fcontent\u002Fguides\u002Frefactoring-serverless\u002Fextract_send_message",{"title":51,"time":15,"path":52,"id":53,"link":54},"Extract function invocation","extract_function_invocation","extract_function_invocation.md","\u002Fcontent\u002Fguides\u002Frefactoring-serverless\u002Fextract_function_invocation",{"title":56,"time":15,"path":57,"id":58,"link":59},"Replace Lambda with Service Integration","service_integration","service_integration.md","\u002Fcontent\u002Fguides\u002Frefactoring-serverless\u002Fservice_integration",{"title":61,"time":62,"path":63,"id":64,"link":65},"Direct database access","1 min","direct_database_access","direct_database_access.md","\u002Fcontent\u002Fguides\u002Frefactoring-serverless\u002Fdirect_database_access",{"title":67,"time":62,"path":68,"id":69,"link":70},"Replace Polling with Callback","replace_polling_with_callback","replace_polling_with_callback.md","\u002Fcontent\u002Fguides\u002Frefactoring-serverless\u002Freplace_polling_with_callback",{"title":6,"time":15,"path":72,"id":73,"link":14},"send_message_via_pipes","send_message_via_pipes.md",{"title":75,"authors":76,"time":38,"path":78,"id":79,"link":80},"Convert Choreography to Orchestration",[77],"Bhuvan Annamreddi","choreography-to-orchestration","choreography-to-orchestration.md","\u002Fcontent\u002Fguides\u002Frefactoring-serverless\u002Fchoreography-to-orchestration",1792578866260]