Direct upload with Elixir / Phoenix
If available in Hex, the package can be installed
by adding cloud_storage to your list of dependencies in mix.exs:
def deps do
  [
    {:cloud_storage, "~> 0.1.0"}
  ]
endDocumentation can be generated with ExDoc and published on HexDocs. Once published, the docs can be found at https://hexdocs.pm/cloud_storage.
CloudStorage is a direct upload backend and it's compatible with multiple storage. The front end request a presigned url to a configured endpoint, upload the file directly to the storage and let the backend know that the file is correclty uploaded.
Example of presigned url request payload:
{
  "url": "...presigned_url",
  "key": "object_key",
  "reference": "unique reference for the upload"
}The key is the value that we want to save into our model to reference the upload
What is an orphan upload?
Orphan upload is a remote file not used anymore in any of your upload field.
How CloudStorage handle them?
Uploads are tracked using Postgresql trigger function. Each time there is a change on an upload field (ex: avatar), cloud_storage will take care of referencing/dereferencing the corresponding upload. Orphan uploads not updated in the last month are automatically deleted;
- Configurate cloud_storage
 
# config.exs
config :cloud_storage, :repo, MyApp.Repo
config :cloud_storage, :default_asset_host, "https://cdn.com"
config :cloud_storage, :default_bucket, "mybucket"
config :cloud_storage, :default_storage_dir, "uploads/direct"- Generate migration
 
mix cloud_storage.install
mix ecto.migrate- Create an uploader
 
# my_app/uploaders/default_uploader.ex
defmodule MyApp.Uploaders.DefaultUploader do
  use CloudStorage.Uploader
end- Add routes
 
# my_app_web/router.ex
defmodule MyAppWeb.Router do
  #...
  import CloudStorage.Router
  scope "/api" do
    cloud_storage_routes "/uploads", MyApp.Uploaders.DefaultUploader.Controller
  end
  #...
end- Generate field
 
mix cloud_storage.gen.upload users avatar# my_app/users/user.ex
defmodule CloudStorage.User do
  use Ecto.Schema
  schema "users" do
    #...
    field :avatar, MyApp.Uploaders.DefaultUploader.Type
    timestamps()
  end
endmix ecto.migrate