Advertisement
  1. Code
  2. Ruby on Rails

Mengunggah File Dengan Rails dan Dragonfly

Scroll to top
Read Time: 14 min

() translation by (you can also view the original English article)

Beberapa waktu lalu saya menuliskan sebuah artikiel Mengunggah File Dengan Rails dan Shrine yang menjelaskan bagaimana memperkenalkan sebuah fitur pengunggah file ke dalam aplikasi Rails dengan bantuan Shrine gem. Bagaimana pun juga, ada beberapa solusi serupa yang tersedia, dan salah satu favorit saya adalah Dragonfly—sebuah solusi pengunggah yang mudah digunakan untuk Rails dan Rack yang dibuat oleh Mark Evans.

Kami membahas libary ini lebih awal pada tahun lalu namun, seperti dengan kebanyakan software, itu membantu melihat sebuah library dari waktu ke waktu untuk melihat apa yang telah berubah dan bagaimana kita dapat menerapkannya dalam aplikasi kita.

Di dalam artikel ini saya akan membimbingmu melalui pengaturan Dragonfly dan menjelaskan bagaimana memanfaatkan fitur utamanya. Kamu akan belajar bagaimana:

  • Memadukan Dragonfly ke dalam aplikasimu
  • Mengkonfigurasi model untuk dikerjakan dengan Dragonfly
  • Memperkenalkan mekanisme pengunggah dasar
  • Memperkenalkan validasi
  • Membuat thumbnail gambar
  • Melakukan pemrosesan file
  • Menyimpan metadata untuk file yang diunggah
  • Menyiapkan sebuah aplikasi untuk penyebaran

Untuk membuatnya lebih menarik, kita akan membuat aplikasi kecil musik. Itu akan menyajikan album dan lagu terkait yang dapat dikelola dan dimainkan pada website.

Kode sumber untuk artikel ini tersedia di GitHub. Kamu juga dapat memeriksa demo aplikasi tersebut.

Membuat Daftar dan Mengelola Album

Untuk memulai, buat sebuah aplikasi Rails baru tanpa paket pengujian default:

1
rails new UploadingWithDragonfly -T

Untuk artikel ini saya akan menggunakan Rails 5, namun kebanyakan konsep yang dijelaskan berlaku juga untuk versi yang lebih lama.

Membuat Model, Controller, dan Routes

Situs musikal kecil kita akan berisi dua model: Album dan Song. Untuk sekarang, mari kita buat yang pertama dengan isian berikut:

  • title (string)—berisi judul album
  • singer (string)—pelaku album
  • image_uid (string)—sebuah isian spesial untuk menyimpan gambar pratinjau album. Isian ini dapat dinamai apapun yang kamu suka, namun itu harus berisi akhiran _uid seperti yang diinstruksikan dalam dokumentasi Dragonfly.

Buat dan terapkan masing-masing migrasi:

1
rails g model Album title:string singer:string image_uid:string
2
rails db:migrate

Sekarang mari kita buat controller yang sangat umum untuk mengelola album dengan semua tindakan default:

albums_controller.rb

1
class AlbumsController < ApplicationController
2
  def index
3
    @albums = Album.all
4
  end
5
6
  def show
7
    @album = Album.find(params[:id])
8
  end
9
10
  def new
11
    @album = Album.new
12
  end
13
14
  def create
15
    @album = Album.new(album_params)
16
    if @album.save
17
      flash[:success] = 'Album added!'
18
      redirect_to albums_path
19
    else
20
      render :new
21
    end
22
  end
23
24
  def edit
25
    @album = Album.find(params[:id])
26
  end
27
28
  def update
29
    @album = Album.find(params[:id])
30
    if @album.update_attributes(album_params)
31
      flash[:success] = 'Album updated!'
32
      redirect_to albums_path
33
    else
34
      render :edit
35
    end
36
  end
37
38
  def destroy
39
    @album = Album.find(params[:id])
40
    @album.destroy
41
    flash[:success] = 'Album removed!'
42
    redirect_to albums_path
43
  end
44
45
  private
46
47
  def album_params
48
    params.require(:album).permit(:title, :singer)
49
  end
50
end

Terakhir, tambahkan route:

config/routes.rb

1
resources :albums

Memadukan Dragonfly

Waktunya bagi Dragonfly untuk melangkah ke dalam pusat perhatian. Pertama, tambahkan gem ke dalam Gemfile:

Gemfile

1
gem 'dragonfly'

Jalankan:

1
bundle install

2
rails generate dragonfly

Perintah terakhir akan membuat initializer bernama dragonfly.rb dengan konfigurasi default. Kita akan mengesampingkan itu dulu untuk saat ini, namun kamu dapat membaca tentang berbagai pilihan di website resmi Dragonfly.

Hal penting berikutnya untuk dilakukan adalah melengkapi model kita dengan metode Dragonfly. Ini dapat dilakukan dengan menggunakan dragonfly_accessor:

models/album.rb

1
dragonfly_accessor :image

Perhatikan bahwa di sini saya mengatakan :image—itu secara langsung terkait pada kolom image_uid yang kita buat di dalam bagian sebelumnya. Jika kamu, sebagai contoh, menamai kolommu photo_uid, maka metode dragonfly_accessor akan perlu menerima :photo sebagai sebuah argument.

Jika kamu menggunakan Rails 4 atau 5, langkah penting lainnya adalah menandai isian :image (bukan :image_uid!) sebagai yang diizinkan di dalam controller:

albums_controller.rb

1
params.require(:album).permit(:title, :singer, :image)

Ini sudah cukup—kita siap membuat view dan mulai mengunggah file kita!

Membuat Views

Mulai dengan index view:

views/albums/index.html.erb

1
<h1>Albums</h1>
2
3
<%= link_to 'Add', new_album_path %>
4
5
<ul>
6
  <%= render @albums %>
7
</ul>

Sekarang bagian parsial:

views/albums/_album.html.erb

1
<li>
2
  <%= image_tag(album.image.url, alt: album.title) if album.image_stored? %>
3
  <%= link_to album.title, album_path(album) %> by
4
  <%= album.singer %>
5
  | <%= link_to 'Edit', edit_album_path(album) %>
6
  | <%= link_to 'Remove', album_path(album), method: :delete, data: {confirm: 'Are you sure?'} %>
7
</li>

Ada dua metode Dragonfly untuk dicatat di sini:

  • album.image.url mengembalikan jalur ke gambar.
  • album.image_stored? mengatakan apakah rekaman telah mengunggah file pada tempatnya.

Sekarang tambahkan halaman baru dan edit halaman:

views/albums/new.html.erb

1
<h1>Add album</h1>
2
3
<%= render 'form' %>

views/albums/edit.html.erb

1
<h1>Edit <%= @album.title %></h1>
2
3
<%= render 'form' %>

views/albums/_form.html.erb

1
<%= form_for @album do |f| %>
2
  <div>
3
    <%= f.label :title %>
4
    <%= f.text_field :title %>
5
  </div>
6
7
  <div>
8
    <%= f.label :singer %>
9
    <%= f.text_field :singer %>
10
  </div>
11
12
  <div>
13
    <%= f.label :image %>
14
    <%= f.file_field :image %>
15
  </div>
16
17
  <%= f.submit %>
18
<% end %>

Form ini tidak ada yang menarik, namun sekali lagi perhatikan bahwa kami mengatakan :image, bukan :image_uid, ketika menerjemahkan input file.

Sekarang kamu dapat melakukan boot pada server dan menguji fitur pengunggahan!

Menghapus Gambar

Sehingga pengguna dapat membuat dan mengedit album, namun ada sebuah masalah: mereka tidak memiliki cara untuk menghapus gambar, hanya menggantinya dengan yang lainnya. Untungnya, ini sangat mudah diperbaiki dengan memperkenalkan kotak centang "remove image":

views/albums/_form.html.erb

1
<% if @album.image_thumb_stored? %>
2
    <%= image_tag(@album.image.url, alt: @album.title)  %>
3
    <%= f.label :remove_image %>
4
    <%= f.check_box :remove_image %>
5
<% end %>

Jika album memiliki gambar terkait, kita menampilkannya dan menerjemahkan sebuah kotak centang. Jika kotak centang ini diatur, gambar akan dihapus. Perhatikan bahwa isianmu bernama photo_uid, kemudian metode terkait untuk menghapus lampiran akan berupa remove_photo. Sederhana, bukan?

Satu-satunya hal lainnya untuk dilakukan adalah mengijinkan atribut remove_image di dalam controller:

albums_controller.rb

1
params.require(:album).permit(:title, :singer, :image, :remove_image)

Menambahkan Validasi

Pada tahapan ini, semuanya berkerja dengan baik, namun kita tidak memeriksa input pengguna sama sekali, yang tidak terlalu bagus. Karena itu, mari tambahkan validasi untuk model Album:

models/album.rb

1
validates :title, presence: true
2
validates :singer, presence: true
3
validates :image, presence: true
4
validates_property :width, of: :image, in: (0..900)

validates_property adalah metode Dragonfly yang memeriksa berbagai aspek lampiranmu: kamu mungkin memvalidasi sebuah ekstensi, jenis MIME, ukuran file, dll.

Sekarang mari kita buat parsial umum untuk menerjemahkan error yang kita temukan:

views/shared/_errors.html.erb

1
<% if object.errors.any? %>
2
  <div>
3
    <h4>The following errors were found:</h4>
4
5
    <ul>
6
      <% object.errors.full_messages.each do |msg| %>
7
        <li><%= msg %></li>
8
      <% end %>
9
    </ul>
10
  </div>
11
<% end %>

Masukkan parsial ini di dalam form:

views/albums/_form.html.erb

1
<%= form_for @album do |f| %>
2
    <%= render 'shared/errors', object: @album %>
3
    <%# ... %>
4
<% end %>

Terapkan style isian dengan error sedikit untuk menggambarkannya secara visual:

stylesheets/application.scss

1
.field_with_errors {
2
  display: inline;
3
  label {
4
    color: red;
5
  }
6
  input {
7
    background-color: lightpink;
8
  }
9
}

Mempertahankan Gambar Di Antara Permintaan

Dengan memperkenalkan validasi, kita memasuki permasalahan lainnya (skenario yang cukup umum, eh?): jika pengguna telah membuat kesalahan sementara mengisi form, dia akan perlu memilih file lagi setelah mengklik tombol Submit.

Dragonfly dapat membantumu memecahkan masalah ini dengan menggunakan isian retained_* yang tersembunyi:

views/albums/_form.html.erb

1
<%= f.hidden_field :retained_image %>

Jangan lupa untuk memberikan izin pada isian ini:

albums_controller.rb

1
params.require(:album).permit(:title, :singer, :image, :remove_image, :retained_image)

Sekarang gambar akan dipertahankan di antara permintaan! Namun satu-satunya masalah kecil adalah bahwa input unggah file akan tetap menampilkan pesan "choose a file", namun ini dapat diperbaiki dengan beberapa styling dan sebuah JavaScript.

Memproses Gambar

Membuat Thumbnail

Gambar yang diunggah oleh pengguna dapat memiliki dimensi yang berbeda, yang dapat (dan mungkin akan) menyebabkan dampak negatif pada desain website. Kamu mungkin ingin mengecilkan skala gambar pada dimensi tetap, dan tentu saja ini mungkin dengan memanfaatkan style width dan height. Ini bagaimana pun juga, bukan sebuah pendekatan optimal: browser akan tetap perlu mengunduh gambar ukuran penuh dan kemudian menyusutkannya.

Pilihan lainnya (yang biasanya jauh lebih baik) adalah menghasilkan thumbnail gambar dengan beberapa dimensi yang telah ditentukan pada server. Ini sangat sederhana untuk dicapai dengan Dragonfly:

views/albums/_album.html.erb

1
<li>
2
  <%= image_tag(album.image.thumb('250x250#').url, alt: album.title) if album.image_stored? %>
3
  <%# ... %>
4
</li>

250x250 tentu saja, adalah dimensi, dimana # adalah geometri yang berarti "ubah ukuran dan crop jika perlu untuk mempertahankan aspect ratio terhadap titik pusat". Kamu dapat menemukan informasi tentang geometri lainnya pada website Dragonfly.

Metode thumb diperkuat oleh ImageMagick—sebuah solusi bagus untuk membuat dan memanipulasi gambar. Karena itu, untuk melihat demo secara lokal, kamu perlu menginstal ImageMagick (didukung semua plaftorm besar).

Dukungan untuk ImageMagick diaktifkan secara default di dalam initializer Dragonfly:

config/initializers/dragonfly.rb

1
plugin :imagemagick

Sekarang thumbnail dibuat, namun mereka tidak disimpan dimana pun. Ini berarti tiap kali pengguna mengunjungi halaman album, thumbnail akan dibuat. Ada dua cara untuk mengatasi masalah ini: dengan membuatnya setelah rekaman disimpan atau dengan melakukan pembuatan sambil berlalu.

Pilihan pertama melibatkan pengenalan sebuah kolom baru untuk menyimpan thumbnail dan menyesuaikan metode dragonfly_accessor. Buat dan terapkan migrasi baru:

1
rails g migration add_image_thumb_uid_to_albums image_thumb_uid:string
2
rails db:migrate

Sekarang modifikasi modelnya:

models/album.rb

1
dragonfly_accessor :image do
2
    copy_to(:image_thumb){|a| a.thumb('250x250#') }
3
end
4
5
dragonfly_accessor :image_thumb

Perhatikan bahwa yang panggilan pertama ke dragonfly_accessor mengirimkan sebuah blok yang sebenarnya membuat thumbnail bagi kita dan menyalin itu ke dalam image_thumb. Sekarang cukup gunakan metode image_thumb di dalam tampilanmu:

views/albums/_album.html.erb

1
<%= image_tag(album.image_thumb.url, alt: album.title) if album.image_thumb_stored? %>

Solusi ini yang paling sederhana, namun tidak direkomendasikan oleh dokumentasi resmi dan, yang lebih buruk lagi, pada waktu penulisan artikel ini itu tidak berkerja dengan isian retained_*.

Karena itu, biarkan saya menunjukkanmu pilihan lainnya: menghasilkan thumbnail sambil berlalu. Itu melibatkan pembuatan model baru dan menyesuaikan file config Dragonfly. Pertama, modelnya:

1
rails g model Thumb uid:string job:string
2
rake db:migrate

Tabel thumbs akan menjadi induk thumbnail, namun mereka akan dibuat pada saat permintaan. Untuk membuat ini terjadi, kita perlu menentukan ulang metode url di dalam initializer Dragonfly:

config/initializers/dragonfly.rb

1
Dragonfly.app.configure do
2
    define_url do |app, job, opts|
3
        thumb = Thumb.find_by_job(job.signature)
4
        if thumb
5
          app.datastore.url_for(thumb.uid, :scheme => 'https')
6
        else
7
          app.server.url_for(job)
8
        end
9
    end
10
    
11
    before_serve do |job, env|
12
        uid = job.store
13
        
14
        Thumb.create!(
15
            :uid => uid,
16
            :job => job.signature
17
        )
18
    end
19
    # ...
20
end

Sekarang tambahkan album baru dan kunjungi halaman root. Pertama kalinya kamu melakukan itu, output berikut akan dicetak ke dalam log:

1
DRAGONFLY: shell command: "convert" "some_path/public/system/dragonfly/development/2017/02/08/3z5p5nvbmx_Folder.jpg" "-resize" "250x250^^" "-gravity" "Center" "-crop" "250x250+0+0" "+repage" "some_path/20170208-1692-1xrqzc9.jpg"

Ini secara efektif berarti bahwa thumbnail dibuat untuk kita oleh ImageMagick. Jika kamu memuat ulang halaman, baris ini tidak akan muncul lagi, yang berarti bahwa thumbnail mengalami cached! Kamu dapat membaca sedikit lebih lanjut tentang fitur ini di website Dragonfly.

Pemrosesan Lainnya

Kamu dapat melakukan manipulasi apapun secara virtual pada gambarmu setelah mereka diunggah. Ini dapat dilakukan di dalam callback after_assign. Sebagai contoh, mari kita konversi semua gambar kita ke dalam format JPEG dengan kualitas 90%:

1
dragonfly_accessor :image do
2
    after_assign {|a| a.encode!('jpg', '-quality 90') }
3
end

Ada lebih banyak tindakan yang dapat kamu lakukan: memutar dan crop gambar, melakukan encode dengan format yang berbeda, menuliskan teks padanya, mencampurkan dengan gambar lainnya (sebagai contoh, untuk menempatkan watermark), dll. Untuk melihat beberapa contoh lainnya, acukan ke bagian ImageMagick pada website Dragonfly.

Mengunggah dan Mengelola Lagu

Tentu saja, bagian utama situs musikal kita adalah lagu, jadi mari tambahkan itu sekarang. Tiap lagu memiliki sebuah judul dan file musikal, dan itu menjadi milik sebuah album:

1
rails g model Song album:belongs_to title:string track_uid:string
2
rails db:migrate

Gunakan metode Dragonfly, seperti yang kita lakukan untuk model Album:

models/song.rb

1
dragonfly_accessor :track

Jangan lupa untuk menetapkan relasi has_many:

models/album.rb

1
has_many :songs, dependent: :destroy

Tambahkan route baru. Sebuah lagu selalu ada di dalam lingkup album, jadi saya akan route ini disarangkan:

config/routes.rb

1
resources :albums do
2
    resources :songs, only: [:new, :create]
3
end

Buat sebuah controller yang sangat sederhana (sekali lagi, jangan lupa memberikan ijin pada isian track):

songs_controller.rb

1
class SongsController < ApplicationController
2
  def new
3
    @album = Album.find(params[:album_id])
4
    @song = @album.songs.build
5
  end
6
7
  def create
8
    @album = Album.find(params[:album_id])
9
    @song = @album.songs.build(song_params)
10
    if @song.save
11
      flash[:success] = "Song added!"
12
      redirect_to album_path(@album)
13
    else
14
      render :new
15
    end
16
  end
17
18
  private
19
20
  def song_params
21
    params.require(:song).permit(:title, :track)
22
  end
23
end

Tampilkan lagu dan tautan untuk menambahkan yang baru:

views/albums/show.html.erb

1
<h1><%= @album.title %></h1>
2
<h2>by <%= @album.singer %></h2>
3
4
<%= link_to 'Add song', new_album_song_path(@album) %>
5
6
<ol>
7
  <%= render @album.songs %>
8
</ol>

Buat code form tersebut:

views/songs/new.html.erb

1
<h1>Add song to <%= @album.title %></h1>
2
3
<%= form_for [@album, @song] do |f| %>
4
  <div>
5
    <%= f.label :title %>
6
    <%= f.text_field :title %>
7
  </div>
8
9
  <div>
10
    <%= f.label :track %>
11
    <%= f.file_field :track %>
12
  </div>
13
14
  <%= f.submit %>
15
<% end %>

Terakhir, tambahkan parsial  _song:

views/songs/_song.html.erb

1
<li>
2
  <%= audio_tag song.track.url, controls: true %>
3
  <%= song.title %>
4
</li>

Di sini saya menggunakan tag audio HTML5, yang tidak akan berkerja untuk browser yang lebih tua. Jadi, jika kamu bertujuan mendukung browser itu, gunakan polyfill.

Seperti yang kamu lihat, keseluruhan proses sangat langsung pada tujuan. Dragonfly tidak benar-benar peduli jenis file apa yang kamu ingin unggah; yang perlu kamu lakukan adalah menyediakan metode dragonfly_accessor, menambahkan isian yang sesuai, memberinya ijin, dan menerjemahkan tag input file.

Menyimpan Metadata

Ketika saya membuka saya playlist, saya mengharapkan melihat beberapa informasi tambahan tentang tiap lagu, seperti durasi atau bitrate. Tentu saja, secara default info ini tidak disimpan dimana pun, namun kita dapat memperbaikinya dengan cukup mudah. Dragonfly memungkinkan kita untuk menyediakan data tambahan tentang tiap file yang diunggah dan menarik itu nantinya dengan menggunakan metode meta.

Namun itu menjadi lebih kompleks ketika kita berkerja dengan audio atau video, karena untuk menarik metadata, diperlukan sebuah gem khusus steamio-ffmpeg. Gem ini, sebagai gantinya, bergantung pada FFmpeg, sehingga untuk melanjutkan kamu akan perlu menginstalnya pada PC.

Tambahkan streamio-ffmpeg ke dalam Gemfile:

Gemfile

1
gem 'streamio-ffmpeg'

Install itu:

1
bundle install

Sekarang kita dapat menerapkan callback after_assign yang sama dengan yang telah dilihat di bagian sebelumnya:

models/song.rb

1
dragonfly_accessor :track do
2
    after_assign do |a|
3
      song = FFMPEG::Movie.new(a.path)
4
      mm, ss = song.duration.divmod(60).map {|n| n.to_i.to_s.rjust(2, '0')}
5
      a.meta['duration'] = "#{mm}:#{ss}"
6
      a.meta['bitrate'] = song.bitrate ? song.bitrate / 1000 : 0
7
    end
8
end

Perhatikan bahwa di sini saya menggunakan metode path, bukan url, karena pada titik ini kita berkerja dengan sebuah tempfile. Berikutnya kita hanya mengekstrak durasi lagu (mengkonversinya ke menit dan detik dengan pemandu angka nol) dan bitrate (mengkonversinya ke kilobytes per detik).

Terakhir, tampilkan metadata di dalam tampilan:

views/songs/_song.html.erb

1
<li>
2
  <%= audio_tag song.track.url, controls: true %>
3
  <%= song.title %> (<%= song.track.meta['duration'] %>, <%= song.track.meta['bitrate'] %>Kb/s)
4
</li>

Jika kamu memeriksa konten pada folder public/system/dragonfly (lokasi default untuk menjadi induk unggahan), kamu akan memperhatikan beberapa file .yml—mereka menyimpan semua informasi meta di dalam format YAML.

Menyebarkan ke Heroku

Topik terakhir yang akan kita bahas hari ini adalah bagaimana menyiapkan aplikasimu sebelum menyebarkan ke platform cloud Heroku. Permasalahan utamanya adalah bahwa Heroku tidak mengijinkanmu untuk menyimpan file custom (seperti ungaahan), sehingga kita harus bergantung pada layanan penyimpanan cloud seperti Amazon S3. Untungnya, Dragonfly dapat dipadukan dengan itu secara mudah.

Yang perlu kamu lakukan adalah mendaftarkan akun baru di AWS (jika kamu belum memilikinya), buat sebuah user dengan ijin untuk mengakses S3 bucket, dan tuliskan pemasangan kunci pengguna di dalam lokasi yang aman. Kamu mungkin menggunakan pemasangan kunci root, namun ini sangat tidak direkomendasikan. Terakhir, buat sebuah S3 bucket.

Kembali ke aplikasi Rails, jatuhkan sebuah gem baru:

Gemfile

1
group :production do
2
  gem 'dragonfly-s3_data_store'
3
end

Install itu:

1
bundle install

Kemudian sesuaikan konfigurasi Dragonfly untuk menggunakan S3 di dalam lingkungan produksi:

config/initializers/dragonfly.rb

1
if Rails.env.production?
2
    datastore :s3,
3
              bucket_name: ENV['S3_BUCKET'],
4
              access_key_id: ENV['S3_KEY'],
5
              secret_access_key: ENV['S3_SECRET'],
6
              region: ENV['S3_REGION'],
7
              url_scheme: 'https'
8
else
9
    datastore :file,
10
        root_path: Rails.root.join('public/system/dragonfly', Rails.env),
11
        server_root: Rails.root.join('public')
12
end

Untuk menyediakan variabel ENV pada Heroku, gunakan perintah ini:

1
heroku config:add SOME_KEY=SOME_VALUE

Jika kamu ingin menguji integrasi dengan S3 secara lokal, kamu mungkin menggunakan gem seperti dotenv-rails untuk mengelola variabel lingkungan. Namun ingatlah, bahwa pemasangan kunci AWS tidak boleh diekspos secara publik!

Permasalahan kecil lainnya yang saya alami ketika menyebarkan ke Heroku adalah tidak adanya FFmpeg. Masalahnya adalah ketika sebuah aplikasi baru Heroku dibuat, itu memiliki serangkaian layanan yang umumnya digunakan (sebagai contoh, ImageMagick tersedia secara default). Layanan lainnya dapat diinstal sebagai Heroke addon atau di dalam bentuk buildpacks. Untuk menambahkan FFmpeg buildpack, jalankan perintah berikut:

1
heroku buildpacks:add https://github.com/HYPERHYPER/heroku-buildpack-ffmpeg.git

Sekarang semuanya telah siap, dan kamu dapat membagikan aplikasi musikalmu dengan dunia!

Kesimpulan

Ini perjalanan yang panjang, bukan? Hari ini kita telah mendiskusikan Dragonfly—sebuah solusi untuk mengunggah file di dalam Rails. Kita telah melihat pengaturan dasarnya, beberapa pilihan konfigurasi, pembuatan thumbnail, pemrosesan, dan penyimpanan metadata. Juga, kita telah memadukan Dragonfly dengan layanan Amazon S3 dan mempersiapkan aplikasi kita untuk penyebaran pada produksi.

Tentu saja, kita belum mendiskusikan semua aspek Dragonfly di dalam artikel ini, jadi pastikan untuk menjelajah website resminya untuk menemukan dokumentasi lanjutan dan contoh-contoh yang berguna. Jika kamu memiliki pertanyaan lainnya atau tersendat dengan beberapa contoh code, jangan ragu untuk menghubungi saya.

Terima kasih telah bersama saya, dan sampai jumpa lagi!

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.