Skip to content

ndianabasi/adonis-drive-r2

Repository files navigation


AdonisJS Driver for Cloudflare R2

Enjoy the freedom of Cloudflare R2 from your Adonisjs Application.


gh-workflow-image npm-image license-image synk-image

Built with ❤︎ by Ndianabasi Udonkang

Background

The Cloudflare R2 API implements the S3 API in order to enable users have a seamless migration/transition from Amazon S3 to Cloudflare R2. Because of this, this driver utilises the Amazon S3 Rest API by working within the Cloudflare S3 API compatibility instructions, which ensures S3 APIs not supported are not included in this driver.

This driver works by pointing the endpoint property required in the S3 API config to Cloudflare's R2 endpoint. See here. The Cloudflare R2 endpoint is generated within the driver by injecting the required R2 Account ID and the name of the bucket for the active driver instance.

A major difference between this R2 driver and S3 driver is that this driver only supports bucket-level visibility. This is because Cloudflare R2 only provides bucket-level ACL and Cloudflare R2 does not support for the S3 GetObjectAcl command.

Installation

yarn add adonis-drive-r2
node ace invoke adonis-drive-r2

Validating Environment Variables

The configuration for R2 driver relies on certain environment variables and it is usually a good practice to validate the presence of those environment variables.

Open env.ts file and paste the following code inside it.

R2_ACCESS_KEY_ID: Env.schema.string(),
R2_SECRET_ACCESS_KEY: Env.schema.string(),
R2_BUCKET: Env.schema.string(),
R2_ACCOUNT_ID: Env.schema.string(),
R2_PUBLIC_URL: Env.schema.string.optional(),

Update DRIVE_DISK

- DRIVE_DISK: Env.schema.enum(['local', 's3'] as const),
+ DRIVE_DISK: Env.schema.enum(['local', 's3', 'r2'] as const),

Define a New Disk for R2 Driver

Open the config/drive.ts and paste the following code snippet inside it.

{
  disks: {
    // ... other disk

    r2: {
      driver: 'r2',
      visibility: 'private',
      key: Env.get('R2_ACCESS_KEY_ID'),
      secret: Env.get('R2_SECRET_ACCESS_KEY'),
      bucket: Env.get('R2_BUCKET'),
      accountId: Env.get('R2_ACCOUNT_ID'),
      cdnUrl: Env.get('R2_PUBLIC_URL')
    }
  }
}

Note that the cdnUrl property of this R2 config (which maps to the public URl of your bucket) is required when the visibility of the disk is public.

Improve your Drive Contract

Open the contracts/drive.ts file. Add the name of the new disk to the DisksList interface

declare module '@ioc:Adonis/Core/Drive' {
  interface DisksList {
    // ... other disks
    r2: {
      config: R2DriverConfig // <-- Make sure to use the `R2DriverConfig` interface
      implementation: R2DriverContract // <-- Make sure to use the `R2DriverContract` interface
    }
  }
}

How to Obtain Public URL for Cloudflare R2 Bucket

  1. Login to your Cloudflare Dashboard.
  2. Click R2 on the sidebar and open a bucket (or create one and open it).
  3. Switch to the Settings tab.
  4. Under Bucket Access, click View Public Bucket URL and copy the URL.

Making your R2 Bucket Public

By default, Cloudflare's bucket-level ACL, only provides read access to individual files via the public URL. The public won't be able to list your bucket items via the public URL.

To make your bucket public, click on Allow Access within the Bucket Access section of the Settings tab of your bucket.

Public URLs are only useful when your bucket is public. The driver can generate signed URLs for private buckets.

Credits

A big thank you to Harminder Virk for his work of love on the AdonisJS framework and for the amazing S3 Driver for Adonisjs Drive which inspired this Driver for Cloudflare R2.