Skip to content

RFC: Storage providers #866

@Daniel15

Description

@Daniel15

This is something I'd like to implement in Bigcapital, but I'd like to get feedback on the API design first.

Problem

Bigcapital requires the use of S3. However, when self-hosting, it's beneficial to be able to just store the files locally. In my case, Bigcapital will be running on a VPS with 150GB disk space, so it makes sense to just store the files locally rather than paying for an S3-compatible service like S3, Backblaze B2, Cloudflare R2, etc.

The requirement to use S3 can also cause confusion during setup (e.g. #846 and #785, plus I've seen it discussed on Discord).

Solution

Remove the tight coupling with S3 and abstract the handling of files out into interfaces:

interface StorageProvider {
  /**
   * Validate that the storage provider is configured correctly.
   */
  async validateConfig(): Promise<void>;

  /**
   * Store a file. Returns an object representing the uploaded file.
   */
  async upload(file): Promise<File>;

  /**
   * Gets a `File` instance given a fileKey from the database.
   */
  getFileFromKey(fileKey: string): File;
}

interface File {
  /**
  * File path, relative to the root of the storage provider.
  */
  path: string;

  /**
   * Builds a URL to this file.
   */
  buildURL(): string;

  /**
   * Gets the contents of this file.
   */
  async getContents(): Promise<string>;
}

Initially, implement S3StorageProvider and LocalStorageProvider.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions