title: Golang Read JSON from S3 into struct in memory
body: <p>I have a JSON file in S3 that takes the format of the following struct:</p>
  
  <pre><code>type StockInfo []struct {
      Ticker         string `json:"ticker"`
      BoughtPrice    string `json:"boughtPrice"`
      NumberOfShares string `json:"numberOfShares"`
  }
  </code></pre>
  
  <p>and I want to read it into a struct value from S3. In python the code would look something like this:</p>
  
  <pre><code>import boto3
  import json
  
  s3 = boto3.client('s3', 'us-east-1')
  obj = s3.get_object(Bucket=os.environ["BucketName"], Key=os.environ["Key"])
  fileContents = obj['Body'].read().decode('utf-8')
  json_content = json.loads(fileContents)
  </code></pre>
  
  <p>However I'm kinda stuck on how to make this happen in Go. I've gotten this far:</p>
  
  <pre><code>package main
  
  import (
      "archive/tar"
      "bytes"
      "fmt"
      "log"
      "os"
  
      "github.com/aws/aws-sdk-go/aws"
      "github.com/aws/aws-sdk-go/aws/session"
      "github.com/aws/aws-sdk-go/service/s3"
      "github.com/aws/aws-sdk-go/service/s3/s3manager"
      "github.com/joho/godotenv"
  )
  
  type StockInfo []struct {
      Ticker         string `json:"ticker"`
      BoughtPrice    string `json:"boughtPrice"`
      NumberOfShares string `json:"numberOfShares"`
  }
  
  func init() {
      // loads values from .env into the system
      if err := godotenv.Load(); err != nil {
          log.Print("No .env file found")
      }
      return
  }
  
  func main() {
      // Store the PATH environment variable in a variable
      sess, err := session.NewSession(&amp;aws.Config{
          Region: aws.String("us-east-1")},
      )
      if err != nil {
          panic(err)
      }
  
      s3Client := s3.New(sess)
      bucket := "ian-test-bucket-go-python"
      key := "StockInfo.json"
  
      requestInput := &amp;s3.GetObjectInput{
          Bucket: aws.String(bucket),
          Key:    aws.String(key),
      }
      result, err := s3Client.GetObject(requestInput)
          if err != nil {
               fmt.Println(err)
          }
      fmt.Println(result)
  </code></pre>
  
  <p>which returns to me the body/object buffer, but im not sure how to read that into a string so I can marshal it into my struct. I found this code in a similar question:</p>
  
  <pre><code>    requestInput := &amp;s3.GetObjectInput{
          Bucket: aws.String(bucket),
          Key:    aws.String(key),
      }
  
      buf := new(aws.WriteAtBuffer)
      numBytes, _ := *s3manager.Downloader.Download(buf, requestInput)
      tr := tar.NewReader(bytes.NewReader(buf.Bytes()))
  </code></pre>
  
  <p>but I get the following errors:</p>
  
  <pre><code>not enough arguments in call to method expression s3manager.Downloader.Download
      have (*aws.WriteAtBuffer, *s3.GetObjectInput)
      want (s3manager.Downloader, io.WriterAt, *s3.GetObjectInput, ...func(*s3manager.Downloader))
  
  multiple-value s3manager.Downloader.Download() in single-value context
  </code></pre>
  
  <p>Can anyone point me in the right direction? kinda frustrating how hard it seems to do this compared to python.</p>