<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Sharad Khambe</title>
    <description>The latest articles on DEV Community by Sharad Khambe (@smkhub).</description>
    <link>https://dev.to/smkhub</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2223864%2F05e6ccfb-03ec-4d93-9a43-9fe64e52479a.png</url>
      <title>DEV Community: Sharad Khambe</title>
      <link>https://dev.to/smkhub</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/smkhub"/>
    <language>en</language>
    <item>
      <title>API Gateway integration with AWS Services.</title>
      <dc:creator>Sharad Khambe</dc:creator>
      <pubDate>Tue, 29 Oct 2024 06:42:37 +0000</pubDate>
      <link>https://dev.to/smkhub/api-gateway-integration-with-aws-services-4940</link>
      <guid>https://dev.to/smkhub/api-gateway-integration-with-aws-services-4940</guid>
      <description>&lt;p&gt;&lt;strong&gt;In this blog post we will discuss on how API gateway can be used for integration with other AWS services such as dynamodb, lambda functions, step functions, SNS etc.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is AWS API Gateway ?
&lt;/h2&gt;

&lt;p&gt;AWS API Gateway us managed service that is highly available, scalable . API gateway provides easy integration with various AWS services like lambda, dynamodb, step functions and external/internal HTTP endpoints for integration purposes. It acts as entrypoint for your API traffic. &lt;br&gt;
It provides features like authorization, throttling, CORS, caching, transformations, openAPI specs, custom domain names to name few. &lt;/p&gt;
&lt;h2&gt;
  
  
  API Gateway High Level Architecture
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcj4qbdzylbpqukveb07g.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcj4qbdzylbpqukveb07g.jpg" alt="Image description" width="800" height="815"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Integration Type
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Lambda Function:&lt;/strong&gt; lambda function can be integrated with API gateway in 2 different ways. &lt;/p&gt;

&lt;p&gt;First called as Lambda Proxy and second one Lambda Direct Integration. In lambda proxy integration pattern, when client makes request to api, API Gw wraps body into events and some contextual data in context and pass it both event and context to lambda function. The response from lambda function is passed as-is back to api client which means lambda function will need to prepare response in way that includes status code, http headers, body etc.This is supported by HTTP and Rest api.&lt;/p&gt;

&lt;p&gt;Second called Lambda Direct Integration in which case we can use VTL to perform some modifications on request body or headers and pass it lambda and then in response similar modifications can be done to response. VTL is bit complex and hard to understand at first place but its very powerful tool for message transformation and enrichment between request and response. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AWS Services Integration&lt;/strong&gt;: This pattern allows you to integrate API Gw with various AWS Services directly without using lambda as middleware. This integration lets an API expose AWS service actions. In AWS integration, you will need to configure both the integration request and integration response and set up necessary data mappings from the method request to the integration request, and from the integration response to the method response.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HTTP Endpoints Integrations&lt;/strong&gt;: In this pattern you place your API GW in front of http endpoints be it internal or external services. This can be either HTTP or HTTP_PROXY mode integration. In HTTP Proxy mode API Gateway passes the incoming request from the client to the HTTP endpoint and passes the outgoing response from the HTTP endpoint to the client.&lt;br&gt;
In HTTP mode, you can use integration or VTL mapping to update request and responses. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mock Integration&lt;/strong&gt;This type of integration lets API Gateway return a response without sending the request further to the backend. API response is defined at API gateway and used for mock responses for testing purposes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Private Integrations&lt;/strong&gt;: It allows you to integrate with services running in VPC by using VPC private links through network load balancer or to on premises services using AWS direct connect. You can also integrate with application load balancer using VPC private link in this case. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Now we will look at use case on how API gateway be integrated with AWS S3 bucket to list files, download or upload file to specific bucket. We will use CDK(if you want to know more about CDK,read it here&lt;/em&gt; &lt;a href="https://dev.to/smkhub/aws-cdk--45l0"&gt;https://dev.to/smkhub/aws-cdk--45l0&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdi436x8i5zwp5sifwsxt.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdi436x8i5zwp5sifwsxt.jpg" alt="Image description" width="800" height="171"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Complete CDK code in javascript for this use case can be found at GitHub repo &lt;a href="https://github.com/SMKHub/cdk-s3-api" rel="noopener noreferrer"&gt;https://github.com/SMKHub/cdk-s3-api&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create directory named "cdk-s3-api" and Initialise cdk app using "cdk init app --language=javascript" from cdk-s3-api directory. &lt;/p&gt;

&lt;p&gt;In cdk-s3-app-stack.js file under constructor function first create S3 bucket, code below will create S3 bucket named s3-api-bucket with sane default values set by cdk as best practises.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;   &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;s3ApiBucket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Bucket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;s3ApiBucket&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;bucketName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;s3-api-bucket&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;removalPolicy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;cdk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;RemovalPolicy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DESTROY&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create Rest API gateway with endpoint type as edge. Since we are dealing with s3 objects we will need to set values for "&lt;em&gt;binaryMediaTypes&lt;/em&gt;". This is required to handle binary media types and for our API we are setting it to &lt;em&gt;octet-stream and image/png&lt;/em&gt; types.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;restApi&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;apigw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;RestApi&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;s3Api&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;restApiName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;s3Api&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
      &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Rest API for accessing S3 bucket and its object&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
      &lt;span class="na"&gt;endpointConfiguration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="p"&gt;:[&lt;/span&gt; &lt;span class="nx"&gt;apigw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;EndpointType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;EDGE&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt; 
      &lt;span class="na"&gt;binaryMediaTypes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/octet-stream&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;image/png&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next define AWS Integration with S3 service. Code below define following properties for integration.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;service : specifies name of AWS service to be integrated in our case it's s3 &lt;/li&gt;
&lt;li&gt;path : s3 bucket name&lt;/li&gt;
&lt;li&gt;integrationHttpMethod : specifies integration method type. &lt;/li&gt;
&lt;li&gt;options. passthroughBehavior : Allows pass-through when the integration has NO content types mapped to templates. &lt;/li&gt;
&lt;li&gt;role to be used by API Gateway while making calls to S3 API's&lt;/li&gt;
&lt;li&gt;set integration request path bucket to method path folder from incoming api call. &lt;/li&gt;
&lt;li&gt;options. integrationResponses : Response that API Gateway provides after a method's backend completes processing a request with additional information mentioned below. &lt;/li&gt;
&lt;li&gt;set response headers to match integration for content type, content length and date headers. this is so that when client receives response it understand response content type as it might be xml, jpg image or normal text file stored in s3 bucket. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Note that setting up integration requests parameters and response parameters is necessary for API GW to successfully call S3 apis and send response back to client&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;listBucketApiIntegration&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;apigw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;AwsIntegration&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;s3&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
      &lt;span class="na"&gt;region&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;us-east-1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
      &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;s3ApiBucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bucketName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
      &lt;span class="na"&gt;integrationHttpMethod&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;GET&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
      &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;credentialsRole&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;apiGatewayRole&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="na"&gt;passthroughBehavior&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;apigw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PassthroughBehavior&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;WHEN_NO_TEMPLATES&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;requestParameters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;integration.request.path.bucket&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;method.request.path.folder&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="na"&gt;integrationResponses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;200&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
            &lt;span class="na"&gt;responseParameters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
              &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;method.response.header.Date&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;integration.response.header.Date&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;method.response.header.Content-Length&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;integration.response.header.Content-Length&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
              &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;method.response.header.Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;integration.response.header.Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next add method to list bucket objects. Here we are using IAM authorization for making call to this http GET method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;bucketRootResource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GET&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;listBucketApiIntegration&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
      &lt;span class="p"&gt;{&lt;/span&gt; 
        &lt;span class="na"&gt;authorizationType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;apigw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;AuthorizationType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;IAM&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="na"&gt;requestParameters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;method.request.path.folder&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt; 
        &lt;span class="na"&gt;methodResponses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;200&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
            &lt;span class="na"&gt;responseParameters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
              &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;method.response.header.Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;method.response.header.Date&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;method.response.header.Content-Length&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
              &lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we will add resource under root with path as "/{object}" and then define GET and PUT method separately for downloading object and uploading object to S3 bucket.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bucketItemResource&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;bucketRootResource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addResource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;{item}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getBucketItemApiIntegration&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;apigw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;AwsIntegration&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;s3&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
      &lt;span class="na"&gt;region&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;us-east-1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
      &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;s3ApiBucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bucketName&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/{object}&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;integrationHttpMethod&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;GET&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
      &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;credentialsRole&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;apiGatewayRole&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="na"&gt;passthroughBehavior&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;apigw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PassthroughBehavior&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;WHEN_NO_TEMPLATES&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="na"&gt;requestParameters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;integration.request.path.bucket&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;method.request.path.folder&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
          &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;integration.request.path.object&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;method.request.path.item&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;integration.request.header.Accept&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;method.request.header.Accept&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt; 
        &lt;span class="na"&gt;integrationResponses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;          
            &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="na"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;200&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
              &lt;span class="na"&gt;responseParameters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
                &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;method.response.header.Date&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;integration.response.header.Date&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;method.response.header.Content-Length&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;integration.response.header.Content-Length&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;method.response.header.Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;integration.response.header.Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
              &lt;span class="p"&gt;}&lt;/span&gt;

          &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;bucketItemResource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GET&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getBucketItemApiIntegration&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
      &lt;span class="p"&gt;{&lt;/span&gt; 
        &lt;span class="na"&gt;authorizationType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;apigw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;AuthorizationType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;IAM&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="na"&gt;requestParameters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;method.request.path.folder&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;method.request.path.item&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
          &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;method.request.header.Accept&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt; 
        &lt;span class="na"&gt;methodResponses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;200&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
            &lt;span class="na"&gt;responseParameters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
              &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;method.response.header.Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;method.response.header.Date&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;method.response.header.Content-Length&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
              &lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run cdk synth to validate if code is fine and then run cdk deploy to create stack resources in AWS account. &lt;/p&gt;

&lt;p&gt;Integration response and request parameters that we have mapped in cdk code can be seen in API GW console as below. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7acf9aye4k6t2qs7179u.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7acf9aye4k6t2qs7179u.jpg" alt="Image description" width="800" height="369"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjp9n514b64gegd7dqffi.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjp9n514b64gegd7dqffi.jpg" alt="Image description" width="800" height="386"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Testing of API can be done using postman. Note that you will need to set access key and secret access key as API Gw authentication is set to IAM in CDK construct. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgb4rd2ojva8goamw1tv1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgb4rd2ojva8goamw1tv1.png" alt="Image description" width="800" height="538"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally don't forget to delete resources from AWS account using "cdk destroy" command. Note you might need to delete objects from S3 bucket manually before cdk destroy command if you have uploaded objects as part of testing API else stack deletion will fail stating S3 bucket is not empty. &lt;/p&gt;

</description>
      <category>cdk</category>
      <category>aws</category>
      <category>apigateway</category>
      <category>s3</category>
    </item>
    <item>
      <title>AWS CDK</title>
      <dc:creator>Sharad Khambe</dc:creator>
      <pubDate>Thu, 17 Oct 2024 14:17:01 +0000</pubDate>
      <link>https://dev.to/smkhub/aws-cdk--45l0</link>
      <guid>https://dev.to/smkhub/aws-cdk--45l0</guid>
      <description>&lt;p&gt;&lt;em&gt;In this blog, we will cover up basic of what is AWS CDK, it's features, use cases, cdk commands, how to use them and deploy into AWS.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  AWS Cloud Development Kit
&lt;/h2&gt;

&lt;p&gt;AWS Cloud Development Kit is open source development framework used to model and provision cloud resources using familiar programming languages such as JS, TS, Python, Go etc. &lt;br&gt;
You can use any of supported languages to define your cloud resources  and when deployed those resources are provisioned through AWS CloudFormation. &lt;/p&gt;

&lt;h2&gt;
  
  
  Key Benifits of using CDK
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Familiar&lt;/strong&gt; : Benefits of using programming language of your's/team's choice. This gives advantage of using same programming language for your infrastructure build as well as for your application development. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tools Support&lt;/strong&gt; : Lot of languages have in built support for linting, testing, debugging which is inherited by cdk framework. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Abstraction&lt;/strong&gt; : CDK provides secure first defaults properties for most of resources according best practices and implementation. e.g. when you create S3 bucket it will have public access disabled by default. However you have option to set each properties as well if you chose to do so. &lt;/p&gt;

&lt;h2&gt;
  
  
  CDK Main Components
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Core Framework&lt;/strong&gt; : With core framework you can create App which can contain one more multiple structured components called as Stacks. &lt;br&gt;
Stacks are logical unit of infrastructure which contains one or many resources. Resources are mapped one-to-one to Cloudformation resources. Stack in CDK is one to one relationship with CloudFormation stack. Similar to CloudFormation you can have nested stack in CDK(we will discuss this in another blog with example!). &lt;br&gt;
It's good practice to divide resources into stack that have different purpose or lifecycles. E.g. stateless(SQS) vs stateful(RDS) OR front-end applications Vs backend API's for front end. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxogubzvu33nl9rezua6s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxogubzvu33nl9rezua6s.png" alt="CDK Core Framework" width="521" height="351"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. AWS Construct Library&lt;/strong&gt;: AWS construct library is set of components designed and created by AWS to create resources for specific services. These are build considering best practices and security implementation for given services. AWS constructs are categorised into three levels&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Level 1(L1) constructs&lt;/strong&gt;&lt;/em&gt; : These constructs are mapped one to one with single CloudFormation resource specification. E.g. S3 bucket. They are named starting with "&lt;strong&gt;Cfn&lt;/strong&gt;". e.g. CfnBucket&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Level 2(L2) constructs&lt;/strong&gt;&lt;/em&gt; : These constructs provide higher level abstraction compared to L1 constructs. L2 constructs is very simple and requires very little input to generate complex CloudFormation templates. However they can have many defaults properties and options to be set.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Level 3(L3) constructs&lt;/strong&gt;&lt;/em&gt; : These constructs are known as patterns and it can contain collection of resources that are configured to work together to achieve specific functionality. E.g. Appsync API with dynamoDB and step functions integration. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. AWS CDK CLI&lt;/strong&gt; : CLI commands helps to interact with core framework such as initialise our project, inspect differences between   various deployments versions. Let's look at workflow on how to use CLI to develop infrastructure and deployment into AWS. &lt;/p&gt;

&lt;h2&gt;
  
  
  Development and Deployment Workflow
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;cdk bootstrap&lt;/strong&gt; &lt;br&gt;
CDK requires specific dedicated resources to be created for you to be able to deploy resources using cdk. &lt;em&gt;cdk bootstrap&lt;/em&gt; cli command helps with achieving necessary preconfiguration to be done. This is just one time activity. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkvcpwort9id0a2x4v8nn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkvcpwort9id0a2x4v8nn.png" alt="cdk bootstrap" width="800" height="131"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Workflow&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg386qbz5z0urvsrcr4uf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg386qbz5z0urvsrcr4uf.png" alt="workflow" width="800" height="229"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Create new project with name of directory e.g. "cdk-todo-app-api".&lt;/em&gt;&lt;br&gt;
🔄 &lt;strong&gt;cdk init app --language=javascript&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Build Project&lt;/em&gt;&lt;br&gt;
🦾 &lt;strong&gt;npm run build&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Create templates from given code&lt;/em&gt;&lt;br&gt;
🧬 &lt;strong&gt;cdk synth&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Validate change set that will result as part of deployment&lt;/em&gt;&lt;br&gt;
🔎 &lt;strong&gt;cdk diff&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Deploy changes to resources into cloud.&lt;/em&gt;&lt;br&gt;
🚀 &lt;strong&gt;cdk deploy&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cdk</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
