paint-brush
Cloudinary Upload API Introduction: Hassle Free Alternative to AWS S3by@gerald-goh
1,161 reads
1,161 reads

Cloudinary Upload API Introduction: Hassle Free Alternative to AWS S3

by Gerald GohJanuary 2nd, 2020
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

Image uploads in a local development environment are currently defaulted to local psql. In production environment (Heroku), a cloud storage service stores images. Heroku does not host pictures, Heroku's addon cloud service Cloudinary does. It offers a solution to web application’s entire image management pipeline. On the back-end, images uploads to or deleted from Cloudinary. Your rails app displays images hosted on Cloudinary via API exchange. The best part is that Cloudinary will not ask for your credit card to sign up for 10GB free storage.

Companies Mentioned

Mention Thumbnail
Mention Thumbnail
featured image - Cloudinary Upload API Introduction: Hassle Free Alternative to AWS S3
Gerald Goh HackerNoon profile picture

So you've developed an impressive rails APP that showcases a gallery of images. Its time to unveil it on the worldwide web via Heroku. Image uploads in a local development environment are currently defaulted to local psql. In production environment (Heroku), a cloud storage service stores images.

By popular choice, AWS S3 cloud service would be suitable to host your images. They offer a free plan, but to sign up it requires a credit/debit card. In my experience setting AWS up for image-handling was challenge. If one does not exercise extreme caution; API key and secret will get exposed on Github.

Unscrupulous bots are on the prowl for these credentials to exploit compute resources. Hence raking up a hefty bill.

Since Heroku does not host pictures, Heroku's addon cloud service Cloudinary does. It offers a solution to web application’s entire image management pipeline. Cloudinary offers comprehensive APIs and administration capabilities. It is easy to integrate with any web application, existing or new on Heroku. Cloudinary provides URL and HTTP based APIs. Which helps integrates with any Web development framework.

As opposed to setting up a separate Cloudinary account. By the end of this article, users will upload pictures over your rails app on Heroku. On the back-end, images uploads to or deleted from Cloudinary. Your rails app displays images hosted on Cloudinary via API exchange. The best part is that Cloudinary will not ask for your credit card to sign up for 10GB free storage.

Author’s Assumptions

The following assumptions are being made:

  • You are using Heroku to host your rails app .
  • Heroku CLI is installed on your machine .
  • Your rails app have been pushed to Heroku.

Cloudinary local and cloud setup

Edit your Gemfile, add the following line.

# ./gemfile

gem ‘carrierwave’
gem ‘cloudinary’

Run "run bundle install" to install inserted gems.

Login Herokuapp page and click on the app as illustrated below;

Navigate to "Resources".

Find & select Cloudinary in the search box as illustrated below;

Select "Start Plan" for free usage and click provision.

You are now redirected to the Cloudinary admin page. Notice generated credentials. Copy cloud name, API key, API secret & Environment Variable.

To hide API key and secret, while the resides in Github, we use config variables. First, navigate to settings and click on config vars. Input credentials (CL_ID, CL_key, Cloudinary_URL) as illustrated below;

Create a cloudinary.yml file in your ‘config’ folder. Copy and paste the template into new file. Substitute Cloud_name for actual cloud name found in Cloudinary admin dashboard. This configuration specifies credentials as well as other attributes.

# config/cloudinary.yml

---
development:
  cloud_name: cloud_name
  api_key: <%= ENV["CL_ID"] %>
  api_secret: <%= ENV["CL_KEY"] %>
  enhance_image_tag: true
  static_file_support: false
production:
  cloud_name: cloud_name
  api_key: <%= ENV["CL_ID"] %>
  api_secret: <%= ENV["CL_KEY"] %>
  enhance_image_tag: true
  static_file_support: true
test:
  cloud_name: cloud_name
  api_key: <%= ENV["CL_ID"] %>
  api_secret: <%= ENV["CL_KEY"] %>
  enhance_image_tag: true
  static_file_support: false

Create an initializer cloudinary.rb as below. When rails server starts up, configuration below will take affect.

Cloudinary.config do |config|
  config.cloud_name = 'cloud_name'
  config.api_key = ENV["CL_ID"]
  config.api_secret = ENV["CL_KEY"]
  config.secure = true
  config.cdn_subdomain = true
end

Assuming you have built the image upload feature (as shown in learn enough tutorial). Setup uploader for Cloudinary as below;

# app/uploader/picture.rb

class PictureUploader < CarrierWave::Uploader::Base
  include CarrierWave::MiniMagick
  include Cloudinary::CarrierWave
  
  # Specify dimensions for images to resize to for appropriate display fit
  version :standard do
    process :resize_to_fill => [400, 400, :north]          
  end

  # Cloudinary will be utilized in production (Heroku) while local psql stored us utilized in development and testing environment.
  if Rails.env.production?
    include Cloudinary::CarrierWave
    CarrierWave.configure do |config|
      config.cache_storage = :file
    end
  else
    storage :file
  end

  # Cloudinary public file path to upload and display pictures
  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end
  
  # Only files with extension jpg jpeg, gif and png will be uploaded
  def extension_whitelist
    %w[jpg jpeg gif png]
  end
end

For image upload forms, emulate the following erb form on front-end view;

# app/views/micropost/_form.html.erb

<%= form_with(model: @post, local: true) do |form| %>
.
.
<span class="picture">
  <%= form.file_field :picture, accept: 'image/jpeg,image/gif,image/png' %>
</span>
.
.
<% end %>

For image display, emulate the following erb tag on front-end view;

# app/views/micropost/_feed.html.erb

<% @feeds.each do |p| %>
.
.
<%= image_tag p.picture.url if p.picture? %>
.
.
<% end %>

Now that you are done, push rails app to Heroku and test it.

Check out my Gitbub Repo, to see how it was done.