Firkin.Backend behaviour (firkin v0.2.0)

Copy Markdown View Source

Behaviour for S3 storage backends.

Implement this behaviour to provide actual storage operations behind the S3-compatible HTTP interface. All callbacks receive an auth context map containing the authenticated identity from lookup_credential/1.

Multipart upload callbacks are optional — the server returns 501 Not Implemented for multipart operations if they are not defined.

Summary

Types

auth_context()

@type auth_context() :: %{access_key_id: String.t(), identity: term()}

bucket()

@type bucket() :: String.t()

key()

@type key() :: String.t()

s3_error()

@type s3_error() :: Firkin.Error.t()

Callbacks

abort_multipart_upload(auth_context, bucket, key, upload_id)

(optional)
@callback abort_multipart_upload(auth_context(), bucket(), key(), upload_id :: String.t()) ::
  :ok | {:error, s3_error()}

complete_multipart_upload(auth_context, bucket, key, upload_id, parts)

(optional)
@callback complete_multipart_upload(
  auth_context(),
  bucket(),
  key(),
  upload_id :: String.t(),
  parts :: [{pos_integer(), String.t()}]
) :: {:ok, Firkin.CompleteResult.t()} | {:error, s3_error()}

copy_object(auth_context, bucket, key, source_bucket, source_key)

@callback copy_object(
  auth_context(),
  bucket(),
  key(),
  source_bucket :: bucket(),
  source_key :: key()
) :: {:ok, Firkin.CopyResult.t()} | {:error, s3_error()}

create_bucket(auth_context, bucket)

@callback create_bucket(auth_context(), bucket()) :: :ok | {:error, s3_error()}

create_multipart_upload(auth_context, bucket, key, opts)

(optional)
@callback create_multipart_upload(auth_context(), bucket(), key(), opts :: map()) ::
  {:ok, upload_id :: String.t()} | {:error, s3_error()}

delete_bucket(auth_context, bucket)

@callback delete_bucket(auth_context(), bucket()) :: :ok | {:error, s3_error()}

delete_object(auth_context, bucket, key)

@callback delete_object(auth_context(), bucket(), key()) :: :ok | {:error, s3_error()}

delete_objects(auth_context, bucket, list)

@callback delete_objects(auth_context(), bucket(), [key()]) ::
  {:ok, Firkin.DeleteResult.t()} | {:error, s3_error()}

get_bucket_location(auth_context, bucket)

@callback get_bucket_location(auth_context(), bucket()) ::
  {:ok, String.t()} | {:error, s3_error()}

get_object(auth_context, bucket, key, t)

@callback get_object(auth_context(), bucket(), key(), Firkin.GetOpts.t()) ::
  {:ok, Firkin.Object.t()} | {:error, s3_error()}

head_bucket(auth_context, bucket)

@callback head_bucket(auth_context(), bucket()) :: :ok | {:error, s3_error()}

head_object(auth_context, bucket, key)

@callback head_object(auth_context(), bucket(), key()) ::
  {:ok, Firkin.ObjectMeta.t()} | {:error, s3_error()}

list_buckets(auth_context)

@callback list_buckets(auth_context()) ::
  {:ok, [Firkin.Bucket.t()]} | {:error, s3_error()}

list_multipart_uploads(auth_context, bucket, opts)

(optional)
@callback list_multipart_uploads(auth_context(), bucket(), opts :: map()) ::
  {:ok, Firkin.MultipartList.t()} | {:error, s3_error()}

list_objects_v2(auth_context, bucket, t)

@callback list_objects_v2(auth_context(), bucket(), Firkin.ListOpts.t()) ::
  {:ok, Firkin.ListResult.t()} | {:error, s3_error()}

list_parts(auth_context, bucket, key, upload_id, opts)

(optional)
@callback list_parts(
  auth_context(),
  bucket(),
  key(),
  upload_id :: String.t(),
  opts :: map()
) ::
  {:ok, Firkin.PartList.t()} | {:error, s3_error()}

lookup_credential(access_key_id)

@callback lookup_credential(access_key_id :: String.t()) ::
  {:ok, Firkin.Credential.t()} | {:error, :not_found}

put_object(auth_context, bucket, key, body, t)

@callback put_object(
  auth_context(),
  bucket(),
  key(),
  body :: iodata(),
  Firkin.PutOpts.t()
) ::
  {:ok, etag :: String.t()} | {:error, s3_error()}

put_object_stream(auth_context, bucket, key, body, t)

(optional)
@callback put_object_stream(
  auth_context(),
  bucket(),
  key(),
  body :: Enumerable.t(),
  Firkin.PutOpts.t()
) :: {:ok, etag :: String.t()} | {:error, s3_error()}

upload_part(auth_context, bucket, key, upload_id, part_number, body)

(optional)
@callback upload_part(
  auth_context(),
  bucket(),
  key(),
  upload_id :: String.t(),
  part_number :: pos_integer(),
  body :: iodata()
) :: {:ok, etag :: String.t()} | {:error, s3_error()}

upload_part_stream(auth_context, bucket, key, upload_id, part_number, body)

(optional)
@callback upload_part_stream(
  auth_context(),
  bucket(),
  key(),
  upload_id :: String.t(),
  part_number :: pos_integer(),
  body :: Enumerable.t()
) :: {:ok, etag :: String.t()} | {:error, s3_error()}