loading...

How to upload JSON data to AWS S3 with NodeJS AWS SDK and Typescript

paulchiu profile image paulchiu ・2 min read

After much Googling and finding Upload to S3 with Node - The Right Way via How to upload files to AWS S3 with NodeJS SDK, then adapting it for my Typescript project, here is another contribution to the topic.

Code Test With

  • Node.js v10.16.3
  • Typescript 3.6.3
  • AWS SDK 2.525.0

Assumptions

The code snippet assumes that:

  • You are familiar with AWS S3, how it works, how to confirm your uploaded file exists.
  • You are able to inject your AWS credentials via environment variables.
  • You are okay with an object-oriented solution; although it shouldn't be too hard to convert it to a simple function.

The Code

The solution is split into two parts, a general client abstraction class to put our convenience methods, and a usage example.

S3Client

Below is a sample S3Client class that I would usually put in a project's lib/ folder.

There are three main parts:

  1. The constructor, which accepts your AWS credentials.
  2. The put method is a wrapper that makes AWS' putObject callback function that is also await ready.
  3. The createPutPublicJsonRequest is a convenience function with sane defaults that relevant for my project, but should probably be changed for your own.

aws-s3-client.ts

import AWS from 'aws-sdk'

export class S3Client {
  protected client: AWS.S3

  constructor(
    accessKeyId: string,
    secretAccessKey: string
  ) {
    this.client = new AWS.S3({
      accessKeyId,
      secretAccessKey
    })
  }

  public async put(
    request: AWS.S3.Types.PutObjectRequest
  ): Promise<AWS.S3.Types.PutObjectOutput> {
    return new Promise((resolve, reject) => {
      this.client.putObject(request, (error, data) => {
        if (error) {
          return reject(error)
        }

        return resolve(data)
      })
    })
  }

  public createPutPublicJsonRequest(
    location: string,
    filename: string,
    contents: string
  ) {
    const request: AWS.S3.Types.PutObjectRequest = {
      Bucket: location,
      Key: filename,
      Body: contents,
      ContentType: 'application/json; charset=utf-8',
      ACL: 'public-read',
      CacheControl: 'max-age=60'
    }

    return request;
  }
}

Sample Code

To use the class, see below. The returned s3Response object will contain an Etag that allows you to get more details about it.

index.ts

import { S3Client } from './lib/aws-s3-client.ts'

const s3Client = new S3Client(
  process.env.ACCESS_KEY_ID,
  process.env.SECRET_ACCESS_KEY
)

const s3PutRequest = s3Client.createPutPublicJsonRequest(
  'mybucket/bucketpath',
  'filename.json',
  JSON.stringify({ hello: 'world' })
)

const s3Response = await s3Client.put(s3PutRequest)

Additional Information

Hopefully the above is a simple starting point for uploading JSON data for public consumption. For more information, check the official AWS S3 JS SDK API.

Discussion

pic
Editor guide