<?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: Marton Veto</title>
    <description>The latest articles on DEV Community by Marton Veto (@marton_veto).</description>
    <link>https://dev.to/marton_veto</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%2F135101%2F2e8f632b-93ae-435c-9352-207d2fef008e.jpg</url>
      <title>DEV Community: Marton Veto</title>
      <link>https://dev.to/marton_veto</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/marton_veto"/>
    <language>en</language>
    <item>
      <title>Route your S3-served static HTMLs beautifully </title>
      <dc:creator>Marton Veto</dc:creator>
      <pubDate>Mon, 18 Feb 2019 10:00:38 +0000</pubDate>
      <link>https://dev.to/marton_veto/route-your-s3-served-static-htmls-beautifully--355</link>
      <guid>https://dev.to/marton_veto/route-your-s3-served-static-htmls-beautifully--355</guid>
      <description>&lt;p&gt;If you are that developer how doesn't play with the big boys and you don't have a fancy React, Angular or &lt;em&gt;insert any fancy frontend framework here which is popular when you read this article&lt;/em&gt; site, which supports client-side routing, but you have some static HTML files (for whatever reason) and you'd like to host it in AWS S3, this article is for you!&lt;/p&gt;

&lt;p&gt;What I'll show you is how to do some basic routing through S3. Your users don't have to add the ugly &lt;em&gt;.html&lt;/em&gt; postfix to the end of their request if they want to reach the &lt;em&gt;/products.html&lt;/em&gt; page, but they will be able to type &lt;em&gt;/products&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;🙀🙀🙀 &lt;/p&gt;

&lt;p&gt;How cool is that? Less typing, more revenue! Let's implement it!&lt;/p&gt;

&lt;p&gt;But first, the boring task:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;create a bucket in S3, with the default settings. We'll adjust everything later. Upload your static files into the bucket (or &lt;a href="https://github.com/mpxr/s3-routing"&gt;mine&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Configuring the permissions
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;In order for your customers to access content at the website endpoint, you must adjust the public access settings of the bucket.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to &lt;strong&gt;Permissions&lt;/strong&gt; &amp;gt; &lt;strong&gt;Public access settings&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Click Edit and make sure that the following 2 options are &lt;strong&gt;unselected&lt;/strong&gt;: 

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Block new public bucket policies&lt;/em&gt;: this allows you to add a new public policy into your bucket. We will do this in the next step.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Block public and cross-account access if bucket has public policies&lt;/em&gt;: this allows users to access the content of a public bucket. If you have this option set only the creator of the bucket and other AWS services have access to this bucket. This is a pretty new feature of S3 (late 2018).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Now we are able to add a bucket policy to our bucket.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to &lt;strong&gt;Permissions&lt;/strong&gt; &amp;gt; &lt;strong&gt;Bucket policy&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Add the following policy document, which allows you to request every object from the bucket:
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Statement"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Principal"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"s3:GetObject"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:s3:::&amp;lt;YOUR_S3_BUCKET_NAME&amp;gt;/*"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Configuring the static website hosting
&lt;/h2&gt;

&lt;p&gt;Now that we have every permissions setting, let's do the interesting part! Assume that I have the following HTML pages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;index.html&lt;/em&gt;, which is my landing page&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;about.html&lt;/em&gt;, &lt;em&gt;products.html&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;and &lt;em&gt;error.html&lt;/em&gt;, which is my error handling page&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I want to have the following routing set:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/&lt;/code&gt; -&amp;gt; &lt;code&gt;index.html&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/about&lt;/code&gt; -&amp;gt; &lt;code&gt;about.html&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/products&lt;/code&gt; -&amp;gt; &lt;code&gt;products.html&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;everything else -&amp;gt; &lt;code&gt;error.html&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The first and last rule is easy to set up because S3 supports it from out-of-the-box with the &lt;em&gt;Static website hosting&lt;/em&gt; feature. On your bucket page go to &lt;strong&gt;Properties&lt;/strong&gt; &amp;gt; &lt;strong&gt;Static website hosting&lt;/strong&gt;. Set the &lt;em&gt;Index document&lt;/em&gt; field to index.html and the &lt;em&gt;Error document&lt;/em&gt; to error.html (or howsoever you named your these files). And now the trickier part: you have to set up some &lt;em&gt;Redirection rules&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;It's configured via XML... 😬&lt;/p&gt;

&lt;p&gt;But it's not that bad. Bear with me.&lt;/p&gt;

&lt;p&gt;You have to set up &lt;em&gt;RoutingRules&lt;/em&gt;, which consists of 2 things: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a &lt;em&gt;Condition&lt;/em&gt; where we provide that what kind of request do we want to catch, eg. &lt;code&gt;/products&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;and where this request will be &lt;em&gt;Redirected&lt;/em&gt;, eg. to &lt;code&gt;/products.html&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You will have a &lt;em&gt;RoutingRules&lt;/em&gt; parent and as many &lt;em&gt;RoutingRule&lt;/em&gt; as the number of HTML sites you want to redirect. So this is how it will look like in the end if I add routing to my two static files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;RoutingRules&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;RoutingRule&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;Condition&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;KeyPrefixEquals&amp;gt;&lt;/span&gt;about&lt;span class="nt"&gt;&amp;lt;/KeyPrefixEquals&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;HttpErrorCodeReturnedEquals&amp;gt;&lt;/span&gt;404&lt;span class="nt"&gt;&amp;lt;/HttpErrorCodeReturnedEquals&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/Condition&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;Redirect&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;ReplaceKeyWith&amp;gt;&lt;/span&gt;about.html&lt;span class="nt"&gt;&amp;lt;/ReplaceKeyWith&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/Redirect&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/RoutingRule&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;RoutingRule&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;Condition&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;KeyPrefixEquals&amp;gt;&lt;/span&gt;products&lt;span class="nt"&gt;&amp;lt;/KeyPrefixEquals&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;HttpErrorCodeReturnedEquals&amp;gt;&lt;/span&gt;404&lt;span class="nt"&gt;&amp;lt;/HttpErrorCodeReturnedEquals&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/Condition&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;Redirect&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;ReplaceKeyWith&amp;gt;&lt;/span&gt;products.html&lt;span class="nt"&gt;&amp;lt;/ReplaceKeyWith&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/Redirect&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/RoutingRule&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/RoutingRules&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The most important part in this is the &lt;code&gt;HttpErrorCodeReturnedEquals&lt;/code&gt; element. When you require a resource from an S3 bucket with a key like "products", S3 won't find it because it doesn't exist (obviously we only have HTML files in our buckets) and it will return a 404 (Not Found) error, which will be propagated to the client, and we won't even access the &lt;em&gt;Redirect&lt;/em&gt; rule.&lt;/p&gt;

&lt;p&gt;That's all. But do not forget, at last in your URL, your users will still see that they're browsing the &lt;code&gt;products.html&lt;/code&gt; and not &lt;code&gt;/products&lt;/code&gt;. But it will ease their user experience with eliminating the need of typing &lt;code&gt;.html&lt;/code&gt; after every request.&lt;/p&gt;

&lt;h3&gt;
  
  
  Routing to external sites
&lt;/h3&gt;

&lt;p&gt;With S3 routing rules, you have the ability to route your request to external websites. If your users request the &lt;code&gt;/facebook&lt;/code&gt; resource from your page, you can redirect them to your Facebook page, &lt;a href="https://facebook.com/YOUR_FACEBOOK_ACCOUNT_POSTFIX"&gt;https://facebook.com/YOUR_FACEBOOK_ACCOUNT_POSTFIX&lt;/a&gt;. This is how you can set up rules like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;RoutingRule&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;Condition&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;KeyPrefixEquals&amp;gt;&lt;/span&gt;facebook&lt;span class="nt"&gt;&amp;lt;/KeyPrefixEquals&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;HttpErrorCodeReturnedEquals&amp;gt;&lt;/span&gt;404&lt;span class="nt"&gt;&amp;lt;/HttpErrorCodeReturnedEquals&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/Condition&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;Redirect&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;HostName&amp;gt;&lt;/span&gt;facebook.com&lt;span class="nt"&gt;&amp;lt;/HostName&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;ReplaceKeyPrefixWith&amp;gt;&lt;/span&gt;/YOUR_FACEBOOK_ACCOUNT_POSTFIX&lt;span class="nt"&gt;&amp;lt;/ReplaceKeyPrefixWith&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/Redirect&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/RoutingRule&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Postscript
&lt;/h2&gt;

&lt;p&gt;I hope this article helped you to do basic routing with S3. When I had to do the same thing, I spent a couple of hours while I found the best solution. I wish you won't have to spend that much time on it. You can find every code I pasted above in a Git &lt;a href="https://github.com/mpxr/s3-routing"&gt;repo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you find any error in the above-written stuff, please blame me publicly in the comment section. Or if it helped you, just drop a "thanks". I'll appreciate it.&lt;/p&gt;

&lt;p&gt;See ya. 👋&lt;/p&gt;

</description>
      <category>aws</category>
      <category>s3</category>
      <category>html</category>
    </item>
    <item>
      <title>File upload with AWS Lambda and S3 in Node</title>
      <dc:creator>Marton Veto</dc:creator>
      <pubDate>Mon, 11 Feb 2019 21:56:06 +0000</pubDate>
      <link>https://dev.to/marton_veto/file-upload-with-aws-lambda-and-s3-in-node-h1n</link>
      <guid>https://dev.to/marton_veto/file-upload-with-aws-lambda-and-s3-in-node-h1n</guid>
      <description>&lt;p&gt;If you have a Lambda function in Node and want to upload files into S3 bucket you have countless options to choose from. In this article, I'll present a solution which uses no web application frameworks (like Express) and uploads a file into S3 through a Lambda function. The HTTP body is sent as a &lt;strong&gt;multipart/form-data&lt;/strong&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  The code
&lt;/h1&gt;

&lt;p&gt;For parsing the multipart/form-data request I use the &lt;strong&gt;&lt;a href="https://www.npmjs.com/package/lambda-multipart"&gt;lambda-multipart&lt;/a&gt;&lt;/strong&gt; package. This package can parse both text and file content and this is how I use it:&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;parseMultipartFormData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;parser&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;Multipart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;parser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;finish&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;files&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;files&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="nx"&gt;parser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&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;In the &lt;code&gt;files&lt;/code&gt; list I will have a list of &lt;code&gt;Buffer&lt;/code&gt; objects.&lt;/p&gt;

&lt;p&gt;This is how I call it and loop through all the files to upload them:&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;files&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;parseMultipartFormData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;uploadFileIntoS3&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&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;And finally, uploading a file into S3:&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;uploadFileIntoS3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;ext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getFileExtension&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&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;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;Bucket&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;file_s3_bucket_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;uuidv4&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s2"&gt;.&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;ext&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;upload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;err&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;I use the &lt;em&gt;uuid&lt;/em&gt; library to get a unique identifier what I'll use as the name of the file. Be aware that if your files are &lt;code&gt;Buffer&lt;/code&gt; objects you can pass them to the &lt;a href="https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#upload-property"&gt;&lt;code&gt;upload&lt;/code&gt;&lt;/a&gt; method of the S3 SDK, but you cannot pass &lt;code&gt;Buffer&lt;/code&gt; objects to the &lt;a href="https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#putObject-property"&gt;&lt;code&gt;putObject&lt;/code&gt;&lt;/a&gt; method! In the &lt;code&gt;catch&lt;/code&gt; block you should add some meaningful error handling. I just logged the error and re-threw it to be able to see it on the caller side.&lt;/p&gt;

&lt;p&gt;You can add some file verifications to check the MIME type of the files and the size. ⚠️ But watch out, currently, Lambda has multiple &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/limits.html"&gt;limitations&lt;/a&gt;. One of them is that it only supports HTTP requests which are less than 6MB in size, so if you want to upload files which are bigger than this limit, you cannot use this solution.&lt;/p&gt;

&lt;p&gt;Don't forget to create some IAM role (and associate it to the Lambda function) to be able to put an object into the S3 bucket.&lt;/p&gt;

&lt;p&gt;This is how I'm getting the extension of the file:&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;getFileExtension&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;headers&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Missing "headers" from request`&lt;/span&gt;&lt;span class="p"&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;contentType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;content-type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contentType&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;image/jpeg&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="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;jpg&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="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Unsupported content type "&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;contentType&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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;And basically, that's all. You can find the full source code &lt;a href="https://github.com/mpxr/lambda-file-upload"&gt;here&lt;/a&gt;. I am using the Serverless Framework for deploying my Lambda functions and for creating an S3 bucket.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>lambda</category>
      <category>s3</category>
      <category>node</category>
    </item>
  </channel>
</rss>
