<?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: Mauro Gestoso</title>
    <description>The latest articles on DEV Community by Mauro Gestoso (@maurogestoso).</description>
    <link>https://dev.to/maurogestoso</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F16986%2F1ebcdb6c-b39e-4ab6-8fac-64875e18307e.jpg</url>
      <title>DEV Community: Mauro Gestoso</title>
      <link>https://dev.to/maurogestoso</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/maurogestoso"/>
    <language>en</language>
    <item>
      <title>Cómo Obtener un Objeto de S3 en Go</title>
      <dc:creator>Mauro Gestoso</dc:creator>
      <pubDate>Sun, 14 Apr 2019 13:00:00 +0000</pubDate>
      <link>https://dev.to/maurogestoso/como-obtener-un-objeto-de-s3-en-go-16b1</link>
      <guid>https://dev.to/maurogestoso/como-obtener-un-objeto-de-s3-en-go-16b1</guid>
      <description>

&lt;p&gt;&lt;em&gt;Publicado originalmente en &lt;a href="https://maurogestoso.github.io/blog/2019/como-obtener-un-objeto-de-s3-en-go/"&gt;mi blog&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Para este ejemplo, asumo que ya tienes &lt;code&gt;go&lt;/code&gt; instalado y &lt;code&gt;aws-cli&lt;/code&gt; instalado y configurado con un perfil de AWS.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;En este ejemplo quiero mostrar cómo obtener el contenido de un objeto almacenado en AWS S3 de forma programática usando Go.&lt;/p&gt;

&lt;p&gt;Para seguir este ejemplo en tu máquina necesitas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Un nuevo proyecto de Go&lt;/li&gt;
&lt;li&gt;El SDK de AWS para Go, lo puedes descargar con este comando: &lt;code&gt;go get github.com/aws/aws-sdk-go&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Un archivo de texto en un &lt;em&gt;bucket&lt;/em&gt; de S3, un object JSON por ejemplo. Apunta el nombre del &lt;em&gt;bucket&lt;/em&gt; y la dirección al objeto.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  1️⃣ Crea un Cliente de S3
&lt;/h2&gt;

&lt;p&gt;En &lt;a href="https://docs.aws.amazon.com/sdk-for-go/api/service/s3/#New"&gt;la documentación del servicio &lt;code&gt;s3&lt;/code&gt;&lt;/a&gt;, uno de los primeros métodos que encuentro es &lt;code&gt;New()&lt;/code&gt;, que recibe configuración y devuelve un tipo &lt;code&gt;*S3&lt;/code&gt;, que es nuestro cliente inicializado. Este cliente nos da acceso a todos los métodos públicos del servicio S3.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="x"&gt;

&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="x"&gt;
  &lt;/span&gt;&lt;span class="s"&gt;"github.com/aws/aws-sdk-go/aws"&lt;/span&gt;&lt;span class="x"&gt;
  &lt;/span&gt;&lt;span class="s"&gt;"github.com/aws/aws-sdk-go/aws/session"&lt;/span&gt;&lt;span class="x"&gt;
  &lt;/span&gt;&lt;span class="s"&gt;"github.com/aws/aws-sdk-go/service/s3"&lt;/span&gt;&lt;span class="x"&gt;
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="x"&gt;

&lt;/span&gt;&lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="x"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;s3Client&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="n"&gt;s3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;aws&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="x"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;Region&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="n"&gt;aws&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"eu-west-1"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="x"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="x"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="x"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;El primer argumento de &lt;code&gt;s3.New()&lt;/code&gt; es una &lt;code&gt;session&lt;/code&gt;. No se muy bien para que sirve porque todavía no lo necesité.&lt;/li&gt;
&lt;li&gt;El segundo argumento de &lt;code&gt;s3.New()&lt;/code&gt; es del tipo &lt;code&gt;*aws.Config&lt;/code&gt; y aquí especifico en que región de AWS quiero trabajar. No entiendo por qué el SDK no la lee automáticamente de mi configuración de perfil (situada en &lt;code&gt;~/.aws/config&lt;/code&gt;)...&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2️⃣ Invoca el Método &lt;code&gt;GetObject()&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Ahora podemos invocar el método &lt;code&gt;GetObject()&lt;/code&gt; para obtener el objeto que queremos. En &lt;a href="https://docs.aws.amazon.com/sdk-for-go/api/service/s3/#S3.GetObject"&gt;la documentación del método&lt;/a&gt; vemos que recibe un argumento de tipo &lt;code&gt;*GetObjectInput&lt;/code&gt; en el que podemos especificar el nombre del &lt;em&gt;bucket&lt;/em&gt; y la dirección del objeto que habíamos apuntado al principio (si todavía no has creado un objeto en S3, ahora es un buen momento 😉).&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="x"&gt;

&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="x"&gt;
  &lt;/span&gt;&lt;span class="c"&gt;// 👇 imports nuevos 👇&lt;/span&gt;&lt;span class="x"&gt;
  &lt;/span&gt;&lt;span class="s"&gt;"fmt"&lt;/span&gt;&lt;span class="x"&gt;
  &lt;/span&gt;&lt;span class="s"&gt;"log"&lt;/span&gt;&lt;span class="x"&gt;
  &lt;/span&gt;&lt;span class="c"&gt;// ☝️ imports nuevos ️️☝️&lt;/span&gt;&lt;span class="x"&gt;

  &lt;/span&gt;&lt;span class="s"&gt;"github.com/aws/aws-sdk-go/aws"&lt;/span&gt;&lt;span class="x"&gt;
  &lt;/span&gt;&lt;span class="s"&gt;"github.com/aws/aws-sdk-go/aws/session"&lt;/span&gt;&lt;span class="x"&gt;
  &lt;/span&gt;&lt;span class="s"&gt;"github.com/aws/aws-sdk-go/service/s3"&lt;/span&gt;&lt;span class="x"&gt;
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="x"&gt;

&lt;/span&gt;&lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="x"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;s3Client&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="n"&gt;s3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;aws&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="x"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;Region&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="n"&gt;aws&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"eu-west-1"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="x"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="x"&gt;
  &lt;/span&gt;&lt;span class="c"&gt;// ☝️ código existente ☝️&lt;/span&gt;&lt;span class="x"&gt;

  &lt;/span&gt;&lt;span class="c"&gt;// 👇 código nuevo 👇&lt;/span&gt;&lt;span class="x"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;bucket&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="s"&gt;"mi-bucket"&lt;/span&gt;&lt;span class="x"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="s"&gt;"ejemplo.json"&lt;/span&gt;&lt;span class="x"&gt;

  &lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="n"&gt;s3Client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;s3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetObjectInput&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="x"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;Bucket&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="n"&gt;aws&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="x"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="x"&gt;    &lt;/span&gt;&lt;span class="n"&gt;aws&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="x"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="x"&gt;
  &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="x"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="x"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="x"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="x"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="x"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;AWS nos da una utilidad para convertir &lt;em&gt;strings&lt;/em&gt; al formato correcto. No entiendo muy bien por qué no puedo pasar los &lt;em&gt;strings&lt;/em&gt; directamente, pero parace ser una práctica aceptada (copiado y pegado de la documentación)&lt;/li&gt;
&lt;li&gt;En la terminal vemos que imprimimos algo así como:&lt;/li&gt;
&lt;/ul&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  AcceptRanges: "bytes",
  Body: buffer(0xc0003d6100),
  ContentLength: 116,
  ContentType: "binary/octet-stream",
  ETag: "\"65ae86d6ce8c3139528a137657122255\"",
  LastModified: 2019-04-14 10:35:37 +0000 UTC,
  Metadata: {

  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;El contenido del objeto debería estar bajo &lt;code&gt;Body&lt;/code&gt;, pero vemos que recibimos algo llamado &lt;code&gt;buffer&lt;/code&gt; y lo que parece información binaria representada en hexadecimal. Interesante 🤔.&lt;/p&gt;

&lt;h2&gt;
  
  
  3️⃣ Interpreta los Resultados
&lt;/h2&gt;

&lt;p&gt;En &lt;a href="https://docs.aws.amazon.com/sdk-for-go/api/service/s3/#GetObjectOutput"&gt;la documentación del tipo &lt;code&gt;GetObjectOutput&lt;/code&gt;&lt;/a&gt; confirmamos que el contenido del objecto está en la propiedad &lt;code&gt;Body&lt;/code&gt;. Pero por qué no vemos el texto que guardamos en nuestro archivo en S3? La clave está en que S3 puede almacenar cualquier formato de información, por lo que tiene sentido que nos devuelva esa información en el denominador común de la comunicación digital: binario. Ahora es nuestro trabajo interpretar esta información y convertirla a un formato más útil para nosotros.&lt;/p&gt;

&lt;p&gt;En la documentación vemos que &lt;code&gt;Body&lt;/code&gt; es del tipo &lt;code&gt;io.ReadCloser&lt;/code&gt;. La &lt;em&gt;interface&lt;/em&gt; &lt;code&gt;io.Reader&lt;/code&gt; es una de las más usadas en Go, la implementa por ejemplo el resultado de leer un archivo del disco duro. Como yo lo entiendo, es la forma que tiene Go de representar información binaria en memoria que se puede leer. El tipo &lt;code&gt;io.ReadCloser&lt;/code&gt; quiere decir que implementa la &lt;em&gt;interface&lt;/em&gt; &lt;code&gt;Reader&lt;/code&gt; y &lt;code&gt;Closer&lt;/code&gt;, por lo tanto podemos leer la información y convertirla a otro formato.&lt;/p&gt;

&lt;p&gt;Como te podrás imaginar, no soy un experto en Go, así que no te voy a engañar: en este punto fui directamente a preguntarle a Don Google y encontré &lt;a href="https://stackoverflow.com/questions/9644139/from-io-reader-to-string-in-go"&gt;esta pregunta en Stack Overflow&lt;/a&gt;.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="x"&gt;

&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="x"&gt;
  &lt;/span&gt;&lt;span class="s"&gt;"bytes"&lt;/span&gt;&lt;span class="x"&gt;
  &lt;/span&gt;&lt;span class="s"&gt;"fmt"&lt;/span&gt;&lt;span class="x"&gt;
  &lt;/span&gt;&lt;span class="s"&gt;"log"&lt;/span&gt;&lt;span class="x"&gt;

  &lt;/span&gt;&lt;span class="s"&gt;"github.com/aws/aws-sdk-go/aws"&lt;/span&gt;&lt;span class="x"&gt;
  &lt;/span&gt;&lt;span class="s"&gt;"github.com/aws/aws-sdk-go/aws/session"&lt;/span&gt;&lt;span class="x"&gt;
  &lt;/span&gt;&lt;span class="s"&gt;"github.com/aws/aws-sdk-go/service/s3"&lt;/span&gt;&lt;span class="x"&gt;
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="x"&gt;

&lt;/span&gt;&lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="x"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;s3Client&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="n"&gt;s3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;aws&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="x"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;Region&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="n"&gt;aws&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"eu-west-1"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="x"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="x"&gt;

  &lt;/span&gt;&lt;span class="n"&gt;bucket&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="s"&gt;"mi-bucket"&lt;/span&gt;&lt;span class="x"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="s"&gt;"ejemplo.json"&lt;/span&gt;&lt;span class="x"&gt;

  &lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="n"&gt;s3Client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;s3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetObjectInput&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="x"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;Bucket&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="n"&gt;aws&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="x"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="x"&gt;    &lt;/span&gt;&lt;span class="n"&gt;aws&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="x"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="x"&gt;
  &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="x"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="x"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="x"&gt;
  &lt;/span&gt;&lt;span class="c"&gt;// ☝️ código existente ☝️&lt;/span&gt;&lt;span class="x"&gt;

  &lt;/span&gt;&lt;span class="c"&gt;// 👇 código nuevo 👇&lt;/span&gt;&lt;span class="x"&gt;
  &lt;/span&gt;&lt;span class="k"&gt;defer&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="x"&gt;

  &lt;/span&gt;&lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="nb"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="x"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReadFrom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="x"&gt;

  &lt;/span&gt;&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="x"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="x"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Como el &lt;em&gt;buffer&lt;/em&gt; permite cerrarlo (recuerda, también implementa la &lt;em&gt;interface&lt;/em&gt; &lt;code&gt;Closer&lt;/code&gt;), lo diferimos al final de la ejecución de la función con &lt;code&gt;defer&lt;/code&gt;. Esto no es necesario pero es buena práctica.&lt;/li&gt;
&lt;li&gt;El paquete &lt;code&gt;bytes&lt;/code&gt; nos permite crear un &lt;em&gt;buffer&lt;/em&gt; de bytes y luego podemos utilizar el método &lt;code&gt;ReadFrom&lt;/code&gt; para leer de algo que implemente la &lt;em&gt;interface&lt;/em&gt; &lt;code&gt;Reader&lt;/code&gt;, por lo que le pasamos &lt;code&gt;Body&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;El resultado de &lt;code&gt;buf.ReadFrom()&lt;/code&gt; no devuelve la información leída, devuelve el número de bytes leídos. La información esta contenida en nuestro &lt;code&gt;buf Buffer&lt;/code&gt; y la podemos convertir a un &lt;code&gt;string&lt;/code&gt; invocando el método &lt;code&gt;String()&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Una posible modificación que yo haría es extraer la funcionalidad de descargar el contenido del objeto a una función para que el recorrido principal de nuestro programa se lea más claro:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="x"&gt;

&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="x"&gt;
    &lt;/span&gt;&lt;span class="s"&gt;"bytes"&lt;/span&gt;&lt;span class="x"&gt;
    &lt;/span&gt;&lt;span class="s"&gt;"fmt"&lt;/span&gt;&lt;span class="x"&gt;
    &lt;/span&gt;&lt;span class="s"&gt;"log"&lt;/span&gt;&lt;span class="x"&gt;

    &lt;/span&gt;&lt;span class="s"&gt;"github.com/aws/aws-sdk-go/aws"&lt;/span&gt;&lt;span class="x"&gt;
    &lt;/span&gt;&lt;span class="s"&gt;"github.com/aws/aws-sdk-go/aws/session"&lt;/span&gt;&lt;span class="x"&gt;
    &lt;/span&gt;&lt;span class="s"&gt;"github.com/aws/aws-sdk-go/service/s3"&lt;/span&gt;&lt;span class="x"&gt;
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="x"&gt;

&lt;/span&gt;&lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="x"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;s3Client&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="n"&gt;s3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;aws&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="x"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;Region&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="n"&gt;aws&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"eu-west-1"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="x"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="x"&gt;

    &lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="n"&gt;downloadS3Data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s3Client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="s"&gt;"mi-bucket"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="s"&gt;"ejemplo.json"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="x"&gt;
    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="x"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="x"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="x"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="x"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="x"&gt;

&lt;/span&gt;&lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="n"&gt;downloadS3Data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s3Client&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;s3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;S3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="n"&gt;bucket&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="x"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="n"&gt;s3Client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;s3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetObjectInput&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="x"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;Bucket&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="n"&gt;aws&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="x"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="x"&gt;    &lt;/span&gt;&lt;span class="n"&gt;aws&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="x"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="x"&gt;
    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="x"&gt;
        &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="x"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="x"&gt;
    &lt;/span&gt;&lt;span class="k"&gt;defer&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="x"&gt;

    &lt;/span&gt;&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="x"&gt;

    &lt;/span&gt;&lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="nb"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="x"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReadFrom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="x"&gt;

    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Bytes&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="x"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="x"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Fíjate como le paso el cliente de S3 a la función, esto nos permitirá &lt;em&gt;testear&lt;/em&gt; la función mucho más fácil en el futuro ya que le podemos pasar un cliente falso y comprobar que se invoca con los argumentos correctos o falsificar los resultados para que nuestras &lt;em&gt;tests&lt;/em&gt; no dependan del acceso a AWS.&lt;/li&gt;
&lt;li&gt;También modifiqué la funcionalidad para que la función devuelva un &lt;em&gt;slice&lt;/em&gt; de bytes en lugar de un &lt;em&gt;string&lt;/em&gt;, esto hace que la función sea más flexible en cuanto a los formatos de información que puede descargar.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Eso es todo...
&lt;/h2&gt;

&lt;p&gt;Espero que este ejemplo haya sido útil, a mí me ayudo mucho a entender mejor cómo funciona Go, sobre todo el sistema de tipos y las &lt;em&gt;interfaces&lt;/em&gt;. Si tienes alguna pregunta no dudes en dejar un comentario 👍&lt;/p&gt;

&lt;h2&gt;
  
  
  Enlaces
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://gist.github.com/maurogestoso/b437d7f15e8ef45f69d165f0916060a8"&gt;Gist con el código&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Documentación del SDK de AWS:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/sdk-for-go/api/service/s3/#New"&gt;&lt;code&gt;s3.New()&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/sdk-for-go/api/service/s3/#S3.GetObject"&gt;&lt;code&gt;GetObject()&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.aws.amazon.com/sdk-for-go/api/service/s3/#GetObjectInput"&gt;&lt;code&gt;GetObjectInput&lt;/code&gt;&lt;/a&gt; / &lt;a href="https://docs.aws.amazon.com/sdk-for-go/api/service/s3/#GetObjectOutput"&gt;&lt;code&gt;GetObjectOutput&lt;/code&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;Documentación de Go:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://golang.org/pkg/bytes/"&gt;&lt;code&gt;bytes&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://golang.org/pkg/bytes/#Buffer.ReadFrom"&gt;&lt;code&gt;Buffer.ReadFrom()&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=""&gt;&lt;code&gt;io&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://golang.org/pkg/io/#Reader"&gt;&lt;code&gt;type Reader&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://golang.org/pkg/io/#ReadCloser"&gt;&lt;code&gt;type ReadCloser&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Stack Overvflow: &lt;a href="https://stackoverflow.com/questions/9644139/from-io-reader-to-string-in-go"&gt;Cómo convertir un &lt;code&gt;io.Reader&lt;/code&gt; a un &lt;code&gt;string&lt;/code&gt;?&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


</description>
      <category>aws</category>
      <category>principiante</category>
      <category>go</category>
      <category>espaol</category>
    </item>
  </channel>
</rss>
