[{"data":1,"prerenderedAt":100},["ShallowReactive",2],{"pattern-lambda-web-dynamodb-api-nodejs-sam":3,"pattern-group-lambda-web-dynamodb-api-nodejs-sam":74},{"id":4,"title":5,"architectureURL":6,"cleanup":7,"contributors":10,"deploy":12,"description":15,"extension":16,"framework":17,"gitHub":18,"highlight":22,"introBox":23,"language":31,"level":32,"meta":33,"patternArch":34,"patternGroup":54,"patternGroupLabel":6,"resources":55,"stem":69,"testing":70,"videoId":6,"__hash__":73},"patterns\u002Fpatterns\u002Flambda-web-dynamodb-api-nodejs-sam.json","Express.js CRUD API on AWS Lambda Web Functions with Amazon DynamoDB",null,{"text":8},[9],"Delete the stack: \u003Ccode>sam delete --stack-name lambda-web-dynamodb-api-sam\u003C\u002Fcode>.",[11],"content\u002Fcontributors\u002Fjon-loinaz-anton.json",{"text":13},[14],"See the GitHub repo for deployment instructions.","Run an unmodified Express.js REST API as a Lambda Web Function that reads and writes items in an Amazon DynamoDB table, using AWS SAM.","json","AWS SAM",{"template":19},{"patternPath":20,"templateFile":21},"lambda-web-dynamodb-api\u002Fnodejs\u002Fsam","template.yaml","true",{"headline":24,"text":25},"How it works",[26,27,28,29,30],"This pattern deploys a standard Express.js 5 application as an AWS Lambda Web Function with a public HTTPS endpoint and an Amazon DynamoDB table. Lambda Web Functions run a long-lived HTTP server and forward requests to it directly, so the Express app needs no adapter, no Lambda handler and no event-to-request mapping. The same \u003Ccode>index.js\u003C\u002Fcode> runs locally with \u003Ccode>node index.js\u003C\u002Fcode> and on AWS.","The API implements the usual CRUD surface: \u003Ccode>POST \u002Fitems\u003C\u002Fcode> creates an item with a conditional write that returns 409 on a duplicate id, \u003Ccode>GET \u002Fitems\u002F{id}\u003C\u002Fcode> reads one item and returns 404 when it is missing, \u003Ccode>PUT \u002Fitems\u002F{id}\u003C\u002Fcode> updates \u003Ccode>name\u003C\u002Fcode>, \u003Ccode>description\u003C\u002Fcode> or \u003Ccode>metadata\u003C\u002Fcode> and fails with 404 if the item does not exist, and \u003Ccode>GET \u002Fitems\u003C\u002Fcode> scans the table with cursor pagination through the \u003Ccode>limit\u003C\u002Fcode> and \u003Ccode>lastKey\u003C\u002Fcode> query parameters. Missing required fields return 400. Every response includes the Region that served it, which becomes useful when the same code is deployed behind a \u003Ccode>MultiRegion\u003C\u002Fcode> endpoint with a DynamoDB global table.","The DynamoDB \u003Ccode>DocumentClient\u003C\u002Fcode> is created once per sandbox and reused across the many concurrent requests that a single sandbox handles, and it authenticates with the function's execution role. That role is defined explicitly in the template so it can carry \u003Ccode>AWSLambdaBasicExecutionRole\u003C\u002Fcode> for CloudWatch Logs plus \u003Ccode>GetItem\u003C\u002Fcode>, \u003Ccode>PutItem\u003C\u002Fcode>, \u003Ccode>UpdateItem\u003C\u002Fcode> and \u003Ccode>Scan\u003C\u002Fcode> scoped to the table ARN. The table name is generated by CloudFormation and injected through the \u003Ccode>TABLE_NAME\u003C\u002Fcode> environment variable.","A single \u003Ccode>AWS::Serverless::WebFunction\u003C\u002Fcode> resource expands into \u003Ccode>AWS::Lambda::WebFunction\u003C\u002Fcode>, an immutable \u003Ccode>AWS::Lambda::WebFunctionRevision\u003C\u002Fcode> that references the zip in a versioning-enabled S3 bucket, and an \u003Ccode>AWS::Lambda::WebFunctionEndpoint\u003C\u002Fcode> routed 100% to that revision. The endpoint uses \u003Ccode>AuthType\u003C\u002Fcode> \u003Ccode>ApplicationManaged\u003C\u002Fcode>, so it is publicly reachable and the application owns authentication; switch to \u003Ccode>IamAuth\u003C\u002Fcode> to accept only SigV4-signed requests.","Because the code bundle contains \u003Ccode>node_modules\u003C\u002Fcode> and no build step runs at deploy time, install production dependencies before zipping. To ship a change, upload the zip under a new S3 key and deploy again; CloudFormation creates a new immutable revision only when the revision's properties change, and the \u003Ccode>LatestRevision\u003C\u002Fcode> endpoint mode moves traffic to it as soon as it is active.","Node.js","200",{},{"icon1":35,"icon2":40,"icon3":43,"line1":47,"line2":51},{"x":36,"y":37,"service":38,"label":39},20,50,"icon-internet","Client",{"x":37,"y":37,"service":41,"label":42},"lambda-web-functions","Lambda Web Function (Express)",{"x":44,"y":37,"service":45,"label":46},80,"dynamodb","DynamoDB",{"from":48,"to":49,"label":50},"icon1","icon2","HTTPS",{"from":49,"to":52,"label":53},"icon3","SDK v3","lambda-web-dynamodb-api",{"bullets":56},[57,60,63,66],{"text":58,"link":59},"AWS Lambda documentation","https:\u002F\u002Fdocs.aws.amazon.com\u002Flambda\u002Flatest\u002Fdg\u002Fwelcome.html",{"text":61,"link":62},"AWS Serverless Application Model (SAM) documentation","https:\u002F\u002Fdocs.aws.amazon.com\u002Fserverless-application-model\u002Flatest\u002Fdeveloperguide\u002Fwhat-is-sam.html",{"text":64,"link":65},"Amazon DynamoDB developer guide","https:\u002F\u002Fdocs.aws.amazon.com\u002Famazondynamodb\u002Flatest\u002Fdeveloperguide\u002FIntroduction.html",{"text":67,"link":68},"AWS SDK for JavaScript v3: DynamoDB DocumentClient","https:\u002F\u002Fdocs.aws.amazon.com\u002FAWSJavaScriptSDK\u002Fv3\u002Flatest\u002FPackage\u002F-aws-sdk-lib-dynamodb\u002F","patterns\u002Flambda-web-dynamodb-api-nodejs-sam",{"text":71},[72],"See the GitHub repo for detailed testing instructions.","uDqRCw4iLjGinHRhIi32NoZj8S0FUNIuHyf8zr99pbQ",[75],{"id":4,"title":5,"architectureURL":6,"cleanup":76,"contributors":78,"deploy":79,"description":15,"extension":16,"framework":17,"gitHub":81,"highlight":22,"introBox":83,"language":31,"level":32,"meta":85,"patternArch":86,"patternGroup":54,"patternGroupLabel":6,"resources":92,"stem":69,"testing":98,"videoId":6,"__hash__":73},{"text":77},[9],[11],{"text":80},[14],{"template":82},{"patternPath":20,"templateFile":21},{"headline":24,"text":84},[26,27,28,29,30],{},{"icon1":87,"icon2":88,"icon3":89,"line1":90,"line2":91},{"x":36,"y":37,"service":38,"label":39},{"x":37,"y":37,"service":41,"label":42},{"x":44,"y":37,"service":45,"label":46},{"from":48,"to":49,"label":50},{"from":49,"to":52,"label":53},{"bullets":93},[94,95,96,97],{"text":58,"link":59},{"text":61,"link":62},{"text":64,"link":65},{"text":67,"link":68},{"text":99},[72],1791847087584]