<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:series="https://publishpress.com/"
	>

<channel>
	<title>localstack Archives - Tomoshare</title>
	<atom:link href="https://blog.tomosia.com.vn/tag/localstack/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.tomosia.com.vn/tag/localstack/</link>
	<description>Kênh chia sẻ kiến thức Tomosia Việt Nam</description>
	<lastBuildDate>Sun, 08 Oct 2023 14:42:57 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://blog.tomosia.com.vn/wp-content/uploads/2023/09/cropped-icon-32x32.png</url>
	<title>localstack Archives - Tomoshare</title>
	<link>https://blog.tomosia.com.vn/tag/localstack/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Sử dụng localstack để giả lập upload file s3</title>
		<link>https://blog.tomosia.com.vn/su-dung-localstack-de-gia-lap-upload-file-s3/</link>
					<comments>https://blog.tomosia.com.vn/su-dung-localstack-de-gia-lap-upload-file-s3/#comments</comments>
		
		<dc:creator><![CDATA[admin_tomosia]]></dc:creator>
		<pubDate>Sun, 08 Oct 2023 10:04:01 +0000</pubDate>
				<category><![CDATA[AWS]]></category>
		<category><![CDATA[s3]]></category>
		<category><![CDATA[localstack]]></category>
		<guid isPermaLink="false">https://blog.tomosia.com.vn/?p=847</guid>

					<description><![CDATA[<p>Hí anh em! Tôi&#160;saiury92&#160;đây ! Trong một thập niên qua và cũng có thể một vài thập niên&#8230;</p>
<p>The post <a href="https://blog.tomosia.com.vn/su-dung-localstack-de-gia-lap-upload-file-s3/">Sử dụng localstack để giả lập upload file s3</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Hí anh em! Tôi&nbsp;<a rel="noreferrer noopener" href="https://saiury92.github.io/" target="_blank">saiury92&nbsp;</a>đây ! Trong một thập niên qua và cũng có thể một vài thập niên tới AWS vẫn làm bố của các Cloud Service Providers, 10 dự án thì tới 9 dự án cần upload file lên Amazon S3. Trong bài viết hôm nay, tôi sẽ giúp các đồng dâm thực hiện việc giả lập upload file s3 ở local mà không cần AWS account. Let&#8217;s go !!!!</p>



<h4 id="localstack" class="wp-block-heading"><strong>LocalStack ?</strong></h4>



<p>LocalStack là một nền tảng mã nguồn mở cho phép bạn chạy và giả lập các dịch vụ AWS ở local. LocalStack hỗ trợ nhiều dịch vụ AWS khác nhau : S3, Lambda, SNS, ES, SES, API Gateway, &#8230;. Dịch vụ cần quan tâm của chúng ta là S3.</p>



<h4 id="start-localstack-bang-docker" class="wp-block-heading">Start LocalStack bằng docker ?</h4>



<p>Chúng ta có thể setup LocalStack trực tiếp trên máy thông qua pip:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#282A36"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="pip install localstack" style="color:#F8F8F2;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F8F8F2">pip install localstack</span></span></code></pre></div>



<p>Nhưng bây giờ là thời đại của containerization, chúng ta mà không sử dụng docker là bị sếp nói là lạc hậu đấy ! Để chạy localstack với docker compose cho S3, anh em có thể sử dụng docker-compose.yml file dưới đây:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#282A36"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="version: '3.9'
services:
  localstack:
    image: localstack/localstack:latest
    container_name: localstack_s3_demo
    environment:
      SERVICES: s3
    ports:
      - '127.0.0.1:4566:4566'" style="color:#F8F8F2;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #8BE9FD">version</span><span style="color: #FF79C6">:</span><span style="color: #F8F8F2"> </span><span style="color: #E9F284">&#39;</span><span style="color: #F1FA8C">3.9</span><span style="color: #E9F284">&#39;</span></span>
<span class="line"><span style="color: #8BE9FD">services</span><span style="color: #FF79C6">:</span></span>
<span class="line"><span style="color: #F8F8F2">  </span><span style="color: #8BE9FD">localstack</span><span style="color: #FF79C6">:</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #8BE9FD">image</span><span style="color: #FF79C6">:</span><span style="color: #F8F8F2"> </span><span style="color: #F1FA8C">localstack/localstack:latest</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #8BE9FD">container_name</span><span style="color: #FF79C6">:</span><span style="color: #F8F8F2"> </span><span style="color: #F1FA8C">localstack_s3_demo</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #8BE9FD">environment</span><span style="color: #FF79C6">:</span></span>
<span class="line"><span style="color: #F8F8F2">      </span><span style="color: #8BE9FD">SERVICES</span><span style="color: #FF79C6">:</span><span style="color: #F8F8F2"> </span><span style="color: #F1FA8C">s3</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #8BE9FD">ports</span><span style="color: #FF79C6">:</span></span>
<span class="line"><span style="color: #F8F8F2">      </span><span style="color: #FF79C6">-</span><span style="color: #F8F8F2"> </span><span style="color: #E9F284">&#39;</span><span style="color: #F1FA8C">127.0.0.1:4566:4566</span><span style="color: #E9F284">&#39;</span></span></code></pre></div>



<p>Start LocalStack container để sử dụng nào:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#282A36"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="docker-compose up -d" style="color:#F8F8F2;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #50FA7B">docker-compose</span><span style="color: #F8F8F2"> </span><span style="color: #F1FA8C">up</span><span style="color: #F8F8F2"> </span><span style="color: #BD93F9">-d</span></span></code></pre></div>



<p>Tạo mới một s3 bucket với tên &#8220;<em>bucket-demo</em>&#8220;:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#282A36"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="docker exec -it localstack_s3_demo awslocal s3 mb s3://bucket-demo" style="color:#F8F8F2;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #50FA7B">docker</span><span style="color: #F8F8F2"> </span><span style="color: #F1FA8C">exec</span><span style="color: #F8F8F2"> </span><span style="color: #BD93F9">-it</span><span style="color: #F8F8F2"> </span><span style="color: #F1FA8C">localstack_s3_demo</span><span style="color: #F8F8F2"> </span><span style="color: #F1FA8C">awslocal</span><span style="color: #F8F8F2"> </span><span style="color: #F1FA8C">s3</span><span style="color: #F8F8F2"> </span><span style="color: #F1FA8C">mb</span><span style="color: #F8F8F2"> </span><span style="color: #F1FA8C">s3://bucket-demo</span></span></code></pre></div>



<h4 id="upload-file-to-s3" class="wp-block-heading"><strong>Upload file to S3 ?</strong></h4>



<p>Để demo việc upload lên file tới S3 tôi sử dụng package <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">@aws-sdk/client-s3</mark> cho gần gũi với đại chúng anh em coder, anh em có thể tham khảo đoạn code dưới đây:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#282A36"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="import { S3Client, PutObjectCommand } from &quot;@aws-sdk/client-s3&quot;;
import fs from &quot;fs&quot;;

const S3_AWS_ACCESS_KEY_ID = &quot;dummy&quot;;
const S3_AWS_SECRET_KEY = &quot;dummy&quot;;
const S3_AWS_BUCKET_NAME = &quot;bucket-demo&quot;;
const useLocal = true; // false if not using LocalStack

const client = new S3Client({
  region: &quot;us-east-1&quot;,
  endpoint: useLocal ? &quot;http://127.0.0.1:4566&quot; : undefined,
  credentials: {
    accessKeyId: S3_AWS_ACCESS_KEY_ID,
    secretAccessKey: S3_AWS_SECRET_KEY,
  },
});

const params = {
  Bucket: S3_AWS_BUCKET_NAME,
  Key: &quot;example.jpg&quot;,
  ContentType: &quot;image/jpeg&quot;,
  Body: fs.readFileSync(&quot;./example.jpg&quot;),
  s3ForcePathStyle: true,
};

const command = new PutObjectCommand(params);

try {
  const response = await client.send(command);
  console.log(response);
  console.log(&quot;File uploaded successfully!&quot;);
} catch (error) {
  console.error(error);
}" style="color:#F8F8F2;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #FF79C6">import</span><span style="color: #F8F8F2"> { S3Client, PutObjectCommand } </span><span style="color: #FF79C6">from</span><span style="color: #F8F8F2"> </span><span style="color: #E9F284">&quot;</span><span style="color: #F1FA8C">@aws-sdk/client-s3</span><span style="color: #E9F284">&quot;</span><span style="color: #F8F8F2">;</span></span>
<span class="line"><span style="color: #FF79C6">import</span><span style="color: #F8F8F2"> fs </span><span style="color: #FF79C6">from</span><span style="color: #F8F8F2"> </span><span style="color: #E9F284">&quot;</span><span style="color: #F1FA8C">fs</span><span style="color: #E9F284">&quot;</span><span style="color: #F8F8F2">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #FF79C6">const</span><span style="color: #F8F8F2"> S3_AWS_ACCESS_KEY_ID </span><span style="color: #FF79C6">=</span><span style="color: #F8F8F2"> </span><span style="color: #E9F284">&quot;</span><span style="color: #F1FA8C">dummy</span><span style="color: #E9F284">&quot;</span><span style="color: #F8F8F2">;</span></span>
<span class="line"><span style="color: #FF79C6">const</span><span style="color: #F8F8F2"> S3_AWS_SECRET_KEY </span><span style="color: #FF79C6">=</span><span style="color: #F8F8F2"> </span><span style="color: #E9F284">&quot;</span><span style="color: #F1FA8C">dummy</span><span style="color: #E9F284">&quot;</span><span style="color: #F8F8F2">;</span></span>
<span class="line"><span style="color: #FF79C6">const</span><span style="color: #F8F8F2"> S3_AWS_BUCKET_NAME </span><span style="color: #FF79C6">=</span><span style="color: #F8F8F2"> </span><span style="color: #E9F284">&quot;</span><span style="color: #F1FA8C">bucket-demo</span><span style="color: #E9F284">&quot;</span><span style="color: #F8F8F2">;</span></span>
<span class="line"><span style="color: #FF79C6">const</span><span style="color: #F8F8F2"> useLocal </span><span style="color: #FF79C6">=</span><span style="color: #F8F8F2"> </span><span style="color: #BD93F9">true</span><span style="color: #F8F8F2">; </span><span style="color: #6272A4">// false if not using LocalStack</span></span>
<span class="line"></span>
<span class="line"><span style="color: #FF79C6">const</span><span style="color: #F8F8F2"> client </span><span style="color: #FF79C6">=</span><span style="color: #F8F8F2"> </span><span style="color: #FF79C6; font-weight: bold">new</span><span style="color: #F8F8F2"> </span><span style="color: #50FA7B">S3Client</span><span style="color: #F8F8F2">({</span></span>
<span class="line"><span style="color: #F8F8F2">  region</span><span style="color: #FF79C6">:</span><span style="color: #F8F8F2"> </span><span style="color: #E9F284">&quot;</span><span style="color: #F1FA8C">us-east-1</span><span style="color: #E9F284">&quot;</span><span style="color: #F8F8F2">,</span></span>
<span class="line"><span style="color: #F8F8F2">  endpoint</span><span style="color: #FF79C6">:</span><span style="color: #F8F8F2"> useLocal </span><span style="color: #FF79C6">?</span><span style="color: #F8F8F2"> </span><span style="color: #E9F284">&quot;</span><span style="color: #F1FA8C">http://127.0.0.1:4566</span><span style="color: #E9F284">&quot;</span><span style="color: #F8F8F2"> </span><span style="color: #FF79C6">:</span><span style="color: #F8F8F2"> </span><span style="color: #BD93F9">undefined</span><span style="color: #F8F8F2">,</span></span>
<span class="line"><span style="color: #F8F8F2">  credentials</span><span style="color: #FF79C6">:</span><span style="color: #F8F8F2"> {</span></span>
<span class="line"><span style="color: #F8F8F2">    accessKeyId</span><span style="color: #FF79C6">:</span><span style="color: #F8F8F2"> S3_AWS_ACCESS_KEY_ID,</span></span>
<span class="line"><span style="color: #F8F8F2">    secretAccessKey</span><span style="color: #FF79C6">:</span><span style="color: #F8F8F2"> S3_AWS_SECRET_KEY,</span></span>
<span class="line"><span style="color: #F8F8F2">  },</span></span>
<span class="line"><span style="color: #F8F8F2">});</span></span>
<span class="line"></span>
<span class="line"><span style="color: #FF79C6">const</span><span style="color: #F8F8F2"> params </span><span style="color: #FF79C6">=</span><span style="color: #F8F8F2"> {</span></span>
<span class="line"><span style="color: #F8F8F2">  Bucket</span><span style="color: #FF79C6">:</span><span style="color: #F8F8F2"> S3_AWS_BUCKET_NAME,</span></span>
<span class="line"><span style="color: #F8F8F2">  Key</span><span style="color: #FF79C6">:</span><span style="color: #F8F8F2"> </span><span style="color: #E9F284">&quot;</span><span style="color: #F1FA8C">example.jpg</span><span style="color: #E9F284">&quot;</span><span style="color: #F8F8F2">,</span></span>
<span class="line"><span style="color: #F8F8F2">  ContentType</span><span style="color: #FF79C6">:</span><span style="color: #F8F8F2"> </span><span style="color: #E9F284">&quot;</span><span style="color: #F1FA8C">image/jpeg</span><span style="color: #E9F284">&quot;</span><span style="color: #F8F8F2">,</span></span>
<span class="line"><span style="color: #F8F8F2">  Body</span><span style="color: #FF79C6">:</span><span style="color: #F8F8F2"> fs.</span><span style="color: #50FA7B">readFileSync</span><span style="color: #F8F8F2">(</span><span style="color: #E9F284">&quot;</span><span style="color: #F1FA8C">./example.jpg</span><span style="color: #E9F284">&quot;</span><span style="color: #F8F8F2">),</span></span>
<span class="line"><span style="color: #F8F8F2">  s3ForcePathStyle</span><span style="color: #FF79C6">:</span><span style="color: #F8F8F2"> </span><span style="color: #BD93F9">true</span><span style="color: #F8F8F2">,</span></span>
<span class="line"><span style="color: #F8F8F2">};</span></span>
<span class="line"></span>
<span class="line"><span style="color: #FF79C6">const</span><span style="color: #F8F8F2"> command </span><span style="color: #FF79C6">=</span><span style="color: #F8F8F2"> </span><span style="color: #FF79C6; font-weight: bold">new</span><span style="color: #F8F8F2"> </span><span style="color: #50FA7B">PutObjectCommand</span><span style="color: #F8F8F2">(params);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #FF79C6">try</span><span style="color: #F8F8F2"> {</span></span>
<span class="line"><span style="color: #F8F8F2">  </span><span style="color: #FF79C6">const</span><span style="color: #F8F8F2"> response </span><span style="color: #FF79C6">=</span><span style="color: #F8F8F2"> </span><span style="color: #FF79C6">await</span><span style="color: #F8F8F2"> client.</span><span style="color: #50FA7B">send</span><span style="color: #F8F8F2">(command);</span></span>
<span class="line"><span style="color: #F8F8F2">  console.</span><span style="color: #50FA7B">log</span><span style="color: #F8F8F2">(response);</span></span>
<span class="line"><span style="color: #F8F8F2">  console.</span><span style="color: #50FA7B">log</span><span style="color: #F8F8F2">(</span><span style="color: #E9F284">&quot;</span><span style="color: #F1FA8C">File uploaded successfully!</span><span style="color: #E9F284">&quot;</span><span style="color: #F8F8F2">);</span></span>
<span class="line"><span style="color: #F8F8F2">} </span><span style="color: #FF79C6">catch</span><span style="color: #F8F8F2"> (error) {</span></span>
<span class="line"><span style="color: #F8F8F2">  console.</span><span style="color: #50FA7B">error</span><span style="color: #F8F8F2">(error);</span></span>
<span class="line"><span style="color: #F8F8F2">}</span></span></code></pre></div>



<p>Start upload file :</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#282A36"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code=" &gt; node upload.js
 
{
  '$metadata': {
    httpStatusCode: 200,
    requestId: 'CE5CQBpI8HEwPsSI4pChERwgSYOvFLIjv5xTPbO9Zg1GLEEp80vN',
    extendedRequestId: 'MzRISOwyjmnupAC6A5B7CD242F7B57/JypPGXLh0OVFGcJaaO3KW/hRAqKOpIEEp',
    cfId: undefined,
    attempts: 1,
    totalRetryDelay: 0
  },
  ETag: '&quot;2067c44cf823bd1b9c2cb66ba8f407e2&quot;'
}
File uploaded successfully!
 " style="color:#F8F8F2;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #F8F8F2"> </span><span style="color: #FF79C6">&gt;</span><span style="color: #F8F8F2"> </span><span style="color: #50FA7B">node</span><span style="color: #F8F8F2"> </span><span style="color: #F1FA8C">upload.js</span></span>
<span class="line"><span style="color: #F8F8F2"> </span></span>
<span class="line"><span style="color: #F8F8F2">{</span></span>
<span class="line"><span style="color: #F8F8F2">  </span><span style="color: #50FA7B">&#39;$metadata&#39;</span><span style="color: #8BE9FD">:</span><span style="color: #F8F8F2"> </span><span style="color: #F1FA8C">{</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #50FA7B">httpStatusCode:</span><span style="color: #F8F8F2"> </span><span style="color: #BD93F9">200</span><span style="color: #F1FA8C">,</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #50FA7B">requestId:</span><span style="color: #F8F8F2"> </span><span style="color: #E9F284">&#39;</span><span style="color: #F1FA8C">CE5CQBpI8HEwPsSI4pChERwgSYOvFLIjv5xTPbO9Zg1GLEEp80vN</span><span style="color: #E9F284">&#39;</span><span style="color: #F1FA8C">,</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #50FA7B">extendedRequestId:</span><span style="color: #F8F8F2"> </span><span style="color: #E9F284">&#39;</span><span style="color: #F1FA8C">MzRISOwyjmnupAC6A5B7CD242F7B57/JypPGXLh0OVFGcJaaO3KW/hRAqKOpIEEp</span><span style="color: #E9F284">&#39;</span><span style="color: #F1FA8C">,</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #50FA7B">cfId:</span><span style="color: #F8F8F2"> </span><span style="color: #F1FA8C">undefined,</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #50FA7B">attempts:</span><span style="color: #F8F8F2"> </span><span style="color: #BD93F9">1</span><span style="color: #F1FA8C">,</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #50FA7B">totalRetryDelay:</span><span style="color: #F8F8F2"> </span><span style="color: #BD93F9">0</span></span>
<span class="line"><span style="color: #F8F8F2">  },</span></span>
<span class="line"><span style="color: #F8F8F2">  </span><span style="color: #50FA7B">ETag:</span><span style="color: #F8F8F2"> </span><span style="color: #E9F284">&#39;</span><span style="color: #F1FA8C">&quot;2067c44cf823bd1b9c2cb66ba8f407e2&quot;</span><span style="color: #E9F284">&#39;</span></span>
<span class="line"><span style="color: #F8F8F2">}</span></span>
<span class="line"><span style="color: #50FA7B">File</span><span style="color: #F8F8F2"> </span><span style="color: #F1FA8C">uploaded</span><span style="color: #F8F8F2"> </span><span style="color: #F1FA8C">successfully!</span></span>
<span class="line"><span style="color: #F8F8F2"> </span></span></code></pre></div>



<p>Sử dụng package<mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">@aws-sdk/s3-request-presigner</mark>để lấy presigned URL:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#282A36"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="// getSignedUrl.js

import { S3Client, GetObjectCommand } from &quot;@aws-sdk/client-s3&quot;;
import { getSignedUrl } from &quot;@aws-sdk/s3-request-presigner&quot;;

const S3_AWS_ACCESS_KEY_ID = &quot;dummy&quot;;
const S3_AWS_SECRET_KEY = &quot;dummy&quot;;
const S3_AWS_BUCKET_NAME = &quot;bucket-demo&quot;;
const useLocal = true;

const client = new S3Client({
  region: &quot;us-east-1&quot;,
  endpoint: useLocal ? &quot;http://127.0.0.1:4566&quot; : undefined,
  credentials: {
    accessKeyId: S3_AWS_ACCESS_KEY_ID,
    secretAccessKey: S3_AWS_SECRET_KEY,
  },
});

const params = {
  Bucket: S3_AWS_BUCKET_NAME,
  Key: &quot;example.jpg&quot;,
  Expires: 3600, // The URL will expire in 3600 seconds.
};

const command = new GetObjectCommand(params);

try {
  const url = await getSignedUrl(client, command);
  console.log(url);
} catch (error) {
  console.error(error);
}" style="color:#F8F8F2;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #6272A4">// getSignedUrl.js</span></span>
<span class="line"></span>
<span class="line"><span style="color: #FF79C6">import</span><span style="color: #F8F8F2"> { S3Client, GetObjectCommand } </span><span style="color: #FF79C6">from</span><span style="color: #F8F8F2"> </span><span style="color: #E9F284">&quot;</span><span style="color: #F1FA8C">@aws-sdk/client-s3</span><span style="color: #E9F284">&quot;</span><span style="color: #F8F8F2">;</span></span>
<span class="line"><span style="color: #FF79C6">import</span><span style="color: #F8F8F2"> { getSignedUrl } </span><span style="color: #FF79C6">from</span><span style="color: #F8F8F2"> </span><span style="color: #E9F284">&quot;</span><span style="color: #F1FA8C">@aws-sdk/s3-request-presigner</span><span style="color: #E9F284">&quot;</span><span style="color: #F8F8F2">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #FF79C6">const</span><span style="color: #F8F8F2"> S3_AWS_ACCESS_KEY_ID </span><span style="color: #FF79C6">=</span><span style="color: #F8F8F2"> </span><span style="color: #E9F284">&quot;</span><span style="color: #F1FA8C">dummy</span><span style="color: #E9F284">&quot;</span><span style="color: #F8F8F2">;</span></span>
<span class="line"><span style="color: #FF79C6">const</span><span style="color: #F8F8F2"> S3_AWS_SECRET_KEY </span><span style="color: #FF79C6">=</span><span style="color: #F8F8F2"> </span><span style="color: #E9F284">&quot;</span><span style="color: #F1FA8C">dummy</span><span style="color: #E9F284">&quot;</span><span style="color: #F8F8F2">;</span></span>
<span class="line"><span style="color: #FF79C6">const</span><span style="color: #F8F8F2"> S3_AWS_BUCKET_NAME </span><span style="color: #FF79C6">=</span><span style="color: #F8F8F2"> </span><span style="color: #E9F284">&quot;</span><span style="color: #F1FA8C">bucket-demo</span><span style="color: #E9F284">&quot;</span><span style="color: #F8F8F2">;</span></span>
<span class="line"><span style="color: #FF79C6">const</span><span style="color: #F8F8F2"> useLocal </span><span style="color: #FF79C6">=</span><span style="color: #F8F8F2"> </span><span style="color: #BD93F9">true</span><span style="color: #F8F8F2">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #FF79C6">const</span><span style="color: #F8F8F2"> client </span><span style="color: #FF79C6">=</span><span style="color: #F8F8F2"> </span><span style="color: #FF79C6; font-weight: bold">new</span><span style="color: #F8F8F2"> </span><span style="color: #50FA7B">S3Client</span><span style="color: #F8F8F2">({</span></span>
<span class="line"><span style="color: #F8F8F2">  region</span><span style="color: #FF79C6">:</span><span style="color: #F8F8F2"> </span><span style="color: #E9F284">&quot;</span><span style="color: #F1FA8C">us-east-1</span><span style="color: #E9F284">&quot;</span><span style="color: #F8F8F2">,</span></span>
<span class="line"><span style="color: #F8F8F2">  endpoint</span><span style="color: #FF79C6">:</span><span style="color: #F8F8F2"> useLocal </span><span style="color: #FF79C6">?</span><span style="color: #F8F8F2"> </span><span style="color: #E9F284">&quot;</span><span style="color: #F1FA8C">http://127.0.0.1:4566</span><span style="color: #E9F284">&quot;</span><span style="color: #F8F8F2"> </span><span style="color: #FF79C6">:</span><span style="color: #F8F8F2"> </span><span style="color: #BD93F9">undefined</span><span style="color: #F8F8F2">,</span></span>
<span class="line"><span style="color: #F8F8F2">  credentials</span><span style="color: #FF79C6">:</span><span style="color: #F8F8F2"> {</span></span>
<span class="line"><span style="color: #F8F8F2">    accessKeyId</span><span style="color: #FF79C6">:</span><span style="color: #F8F8F2"> S3_AWS_ACCESS_KEY_ID,</span></span>
<span class="line"><span style="color: #F8F8F2">    secretAccessKey</span><span style="color: #FF79C6">:</span><span style="color: #F8F8F2"> S3_AWS_SECRET_KEY,</span></span>
<span class="line"><span style="color: #F8F8F2">  },</span></span>
<span class="line"><span style="color: #F8F8F2">});</span></span>
<span class="line"></span>
<span class="line"><span style="color: #FF79C6">const</span><span style="color: #F8F8F2"> params </span><span style="color: #FF79C6">=</span><span style="color: #F8F8F2"> {</span></span>
<span class="line"><span style="color: #F8F8F2">  Bucket</span><span style="color: #FF79C6">:</span><span style="color: #F8F8F2"> S3_AWS_BUCKET_NAME,</span></span>
<span class="line"><span style="color: #F8F8F2">  Key</span><span style="color: #FF79C6">:</span><span style="color: #F8F8F2"> </span><span style="color: #E9F284">&quot;</span><span style="color: #F1FA8C">example.jpg</span><span style="color: #E9F284">&quot;</span><span style="color: #F8F8F2">,</span></span>
<span class="line"><span style="color: #F8F8F2">  Expires</span><span style="color: #FF79C6">:</span><span style="color: #F8F8F2"> </span><span style="color: #BD93F9">3600</span><span style="color: #F8F8F2">, </span><span style="color: #6272A4">// The URL will expire in 3600 seconds.</span></span>
<span class="line"><span style="color: #F8F8F2">};</span></span>
<span class="line"></span>
<span class="line"><span style="color: #FF79C6">const</span><span style="color: #F8F8F2"> command </span><span style="color: #FF79C6">=</span><span style="color: #F8F8F2"> </span><span style="color: #FF79C6; font-weight: bold">new</span><span style="color: #F8F8F2"> </span><span style="color: #50FA7B">GetObjectCommand</span><span style="color: #F8F8F2">(params);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #FF79C6">try</span><span style="color: #F8F8F2"> {</span></span>
<span class="line"><span style="color: #F8F8F2">  </span><span style="color: #FF79C6">const</span><span style="color: #F8F8F2"> url </span><span style="color: #FF79C6">=</span><span style="color: #F8F8F2"> </span><span style="color: #FF79C6">await</span><span style="color: #F8F8F2"> </span><span style="color: #50FA7B">getSignedUrl</span><span style="color: #F8F8F2">(client, command);</span></span>
<span class="line"><span style="color: #F8F8F2">  console.</span><span style="color: #50FA7B">log</span><span style="color: #F8F8F2">(url);</span></span>
<span class="line"><span style="color: #F8F8F2">} </span><span style="color: #FF79C6">catch</span><span style="color: #F8F8F2"> (error) {</span></span>
<span class="line"><span style="color: #F8F8F2">  console.</span><span style="color: #50FA7B">error</span><span style="color: #F8F8F2">(error);</span></span>
<span class="line"><span style="color: #F8F8F2">}</span></span></code></pre></div>



<p>Get presigned URL:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#282A36"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="&gt; node getSignedUrl.js

http://127.0.0.1:4566/bucket-demo/example.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&amp;X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&amp;X-Amz-Credential=dummy%2F20231008%2Fus-east-1%2Fs3%2Faws4_request&amp;X-Amz-Date=20231008T100241Z&amp;X-Amz-Expires=900&amp;X-Amz-Signature=73d10095729f1d47feee9926aa0c0d31d086c979206f93b475265bee2dc4cd4f&amp;X-Amz-SignedHeaders=host&amp;x-id=GetObject" style="color:#F8F8F2;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dracula" style="background-color: #282A36" tabindex="0"><code><span class="line"><span style="color: #FF79C6">&gt;</span><span style="color: #F8F8F2"> node getSignedUrl.js</span></span>
<span class="line"></span>
<span class="line"><span style="color: #50FA7B">http://127.0.0.1:4566/bucket-demo/example.jpg?X-Amz-Algorithm</span><span style="color: #F8F8F2">=AWS4-HMAC-SHA256&amp;</span><span style="color: #BD93F9">X-Amz-Content-Sha256</span><span style="color: #FF79C6">=</span><span style="color: #F1FA8C">UNSIGNED-PAYLOAD</span><span style="color: #F8F8F2">&amp;</span><span style="color: #BD93F9">X-Amz-Credential</span><span style="color: #FF79C6">=</span><span style="color: #F1FA8C">dummy%2F20231008%2Fus-east-1%2Fs3%2Faws4_request</span><span style="color: #F8F8F2">&amp;</span><span style="color: #BD93F9">X-Amz-Date</span><span style="color: #FF79C6">=</span><span style="color: #BD93F9">20231008</span><span style="color: #F1FA8C">T100241Z</span><span style="color: #F8F8F2">&amp;</span><span style="color: #BD93F9">X-Amz-Expires</span><span style="color: #FF79C6">=</span><span style="color: #BD93F9">900</span><span style="color: #F8F8F2">&amp;</span><span style="color: #BD93F9">X-Amz-Signature</span><span style="color: #FF79C6">=</span><span style="color: #BD93F9">73</span><span style="color: #F1FA8C">d10095729f1d47feee9926aa0c0d31d086c979206f93b475265bee2dc4cd4f</span><span style="color: #F8F8F2">&amp;</span><span style="color: #BD93F9">X-Amz-SignedHeaders</span><span style="color: #FF79C6">=</span><span style="color: #F1FA8C">host</span><span style="color: #F8F8F2">&amp;</span><span style="color: #BD93F9">x-id</span><span style="color: #FF79C6">=</span><span style="color: #F1FA8C">GetObject</span></span></code></pre></div>



<p>Đơn giản thực sự đúng không anh em ! Nếu các đồng chí có bất kỳ thắc mắc hay chạy các đoạn script trên có bất cứ bug nào hãy comment cho mình được biết nha ! Cảm ơn các đồng dâm ! Thân ái và hẹn gặp lại !</p>
<p>The post <a href="https://blog.tomosia.com.vn/su-dung-localstack-de-gia-lap-upload-file-s3/">Sử dụng localstack để giả lập upload file s3</a> appeared first on <a href="https://blog.tomosia.com.vn">Tomoshare</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.tomosia.com.vn/su-dung-localstack-de-gia-lap-upload-file-s3/feed/</wfw:commentRss>
			<slash:comments>8</slash:comments>
		
		
			</item>
	</channel>
</rss>
