Bahasa Indonesia

Eksplorasi mendalam tentang Tornado, kerangka kerja web Python dan pustaka jaringan asinkron. Pelajari cara membangun aplikasi yang skalabel dan berkinerja tinggi dengan penjelasan, contoh, dan praktik terbaik yang terperinci.

Dokumentasi Tornado: Panduan Komprehensif untuk Pengembang di Seluruh Dunia

Tornado adalah kerangka kerja web Python dan pustaka jaringan asinkron, yang awalnya dikembangkan di FriendFeed. Ini sangat cocok untuk polling-panjang, WebSocket, dan aplikasi lain yang memerlukan koneksi berdurasi panjang ke setiap pengguna. I/O jaringannya yang non-blocking membuatnya sangat skalabel dan menjadi pilihan yang kuat untuk membangun aplikasi web berkinerja tinggi. Panduan komprehensif ini akan memandu Anda melalui konsep inti Tornado dan memberikan contoh praktis untuk memulai.

Apa itu Tornado?

Pada intinya, Tornado adalah kerangka kerja web dan pustaka jaringan asinkron. Berbeda dengan kerangka kerja web sinkron tradisional, Tornado menggunakan arsitektur berbasis event-loop tunggal. Ini berarti Tornado dapat menangani banyak koneksi bersamaan tanpa memerlukan satu thread per koneksi, membuatnya lebih efisien dan skalabel.

Fitur Utama Tornado:

Menyiapkan Lingkungan Tornado Anda

Sebelum terjun ke pengembangan Tornado, Anda perlu menyiapkan lingkungan Anda. Berikut adalah panduan langkah demi langkah:

  1. Instal Python: Pastikan Anda telah menginstal Python 3.6 atau lebih tinggi. Anda dapat mengunduhnya dari situs web resmi Python (python.org).
  2. Buat Lingkungan Virtual (Disarankan): Gunakan venv atau virtualenv untuk membuat lingkungan terisolasi untuk proyek Anda:
    python3 -m venv myenv
    source myenv/bin/activate  # Di Linux/macOS
    myenv\Scripts\activate  # Di Windows
  3. Instal Tornado: Instal Tornado menggunakan pip:
    pip install tornado

Aplikasi Tornado Pertama Anda

Mari kita buat aplikasi "Hello, World!" sederhana dengan Tornado. Buat file bernama app.py dan tambahkan kode berikut:

import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
 def get(self):
  self.write("Hello, World!")

def make_app():
 return tornado.web.Application([
  (r"/", MainHandler),
 ])

if __name__ == "__main__":
 app = make_app()
 app.listen(8888)
 tornado.ioloop.IOLoop.current().start()

Sekarang, jalankan aplikasi dari terminal Anda:

python app.py

Buka browser web Anda dan navigasikan ke http://localhost:8888. Anda akan melihat pesan "Hello, World!".

Penjelasan:

Request Handler dan Routing

Request handler adalah fondasi dari aplikasi web Tornado. Mereka mendefinisikan cara menangani permintaan HTTP yang masuk berdasarkan URL. Routing memetakan URL ke request handler tertentu.

Mendefinisikan Request Handler:

Untuk membuat request handler, buat subkelas dari tornado.web.RequestHandler dan implementasikan metode HTTP yang sesuai (get, post, put, delete, dll.).

class MyHandler(tornado.web.RequestHandler):
 def get(self):
  self.write("Ini adalah permintaan GET.")

 def post(self):
  data = self.request.body.decode('utf-8')
  self.write(f"Menerima data POST: {data}")

Routing:

Routing dikonfigurasi saat membuat tornado.web.Application. Anda menyediakan daftar tuple, di mana setiap tuple berisi pola URL dan request handler yang sesuai.

app = tornado.web.Application([
 (r"/", MainHandler),
 (r"/myhandler", MyHandler),
])

Pola URL:

Pola URL adalah ekspresi reguler. Anda dapat menggunakan grup ekspresi reguler untuk menangkap bagian dari URL dan meneruskannya sebagai argumen ke metode request handler.

class UserHandler(tornado.web.RequestHandler):
 def get(self, user_id):
  self.write(f"ID Pengguna: {user_id}")

app = tornado.web.Application([
 (r"/user/([0-9]+)", UserHandler),
])

Dalam contoh ini, /user/([0-9]+) cocok dengan URL seperti /user/123. Bagian ([0-9]+) menangkap satu atau lebih digit dan meneruskannya sebagai argumen user_id ke metode get dari UserHandler.

Templating

Tornado menyertakan mesin templating yang sederhana dan efisien. Template digunakan untuk menghasilkan HTML secara dinamis, memisahkan logika presentasi dari logika aplikasi.

Membuat Template:

Template biasanya disimpan dalam file terpisah (misalnya, index.html). Berikut adalah contoh sederhana:

<!DOCTYPE html>
<html>
<head>
 <title>Situs Web Saya</title>
</head>
<body>
 <h1>Selamat datang, {{ name }}!</h1>
 <p>Hari ini adalah {{ today }}.</p>
</body>
</html>

{{ name }} dan {{ today }} adalah placeholder yang akan diganti dengan nilai aktual saat template dirender.

Merender Template:

Untuk merender template, gunakan metode render() di request handler Anda:

class TemplateHandler(tornado.web.RequestHandler):
 def get(self):
  name = "John Doe"
  today = "2023-10-27"
  self.render("index.html", name=name, today=today)

Pastikan pengaturan template_path dikonfigurasi dengan benar dalam pengaturan aplikasi Anda. Secara default, Tornado mencari template di direktori bernama templates di direktori yang sama dengan file aplikasi Anda.

app = tornado.web.Application([
 (r"/template", TemplateHandler),
], template_path="templates")

Sintaks Template:

Template Tornado mendukung berbagai fitur, termasuk:

Operasi Asinkron

Kekuatan Tornado terletak pada kemampuan asinkronnya. Operasi asinkron memungkinkan aplikasi Anda untuk melakukan I/O non-blocking, meningkatkan kinerja dan skalabilitas. Ini sangat berguna untuk tugas-tugas yang melibatkan menunggu sumber daya eksternal, seperti kueri database atau permintaan jaringan.

@tornado.gen.coroutine:

Dekorator @tornado.gen.coroutine memungkinkan Anda menulis kode asinkron menggunakan kata kunci yield. Ini membuat kode asinkron terlihat dan berperilaku lebih seperti kode sinkron, meningkatkan keterbacaan dan pemeliharaan.

import tornado.gen
import tornado.httpclient

class AsyncHandler(tornado.web.RequestHandler):
 @tornado.gen.coroutine
 def get(self):
  http_client = tornado.httpclient.AsyncHTTPClient()
  response = yield http_client.fetch("http://example.com")
  self.write(response.body.decode('utf-8'))

Dalam contoh ini, http_client.fetch() adalah operasi asinkron yang mengembalikan Future. Kata kunci yield menangguhkan eksekusi coroutine hingga Future diselesaikan. Setelah Future diselesaikan, coroutine dilanjutkan dan badan respons ditulis ke klien.

tornado.concurrent.Future:

Sebuah Future merepresentasikan hasil dari operasi asinkron yang mungkin belum tersedia. Anda dapat menggunakan objek Future untuk merangkai operasi asinkron bersama-sama dan menangani kesalahan.

tornado.ioloop.IOLoop:

IOLoop adalah jantung dari mesin asinkron Tornado. Ia memonitor deskriptor file dan soket untuk event dan mengirimkannya ke handler yang sesuai. Anda biasanya tidak perlu berinteraksi langsung dengan IOLoop, tetapi penting untuk memahami perannya dalam menangani operasi asinkron.

WebSocket

Tornado memberikan dukungan yang sangat baik untuk WebSocket, memungkinkan komunikasi real-time antara server dan klien. WebSocket ideal untuk aplikasi yang memerlukan komunikasi dua arah dengan latensi rendah, seperti aplikasi obrolan, game online, dan dasbor real-time.

Membuat Handler WebSocket:

Untuk membuat handler WebSocket, buat subkelas dari tornado.websocket.WebSocketHandler dan implementasikan metode berikut:

import tornado.websocket

class WebSocketHandler(tornado.websocket.WebSocketHandler):
 def open(self):
  print("WebSocket dibuka")

 def on_message(self, message):
  self.write_message(f"Anda mengirim: {message}")

 def on_close(self):
  print("WebSocket ditutup")

 def check_origin(self, origin):
  return True # Mengizinkan koneksi WebSocket lintas-asal

Mengintegrasikan WebSocket ke dalam Aplikasi Anda:

Tambahkan handler WebSocket ke konfigurasi routing aplikasi Anda:

app = tornado.web.Application([
 (r"/ws", WebSocketHandler),
])

Implementasi Sisi Klien:

Di sisi klien, Anda dapat menggunakan JavaScript untuk membuat koneksi WebSocket dan mengirim/menerima pesan:

const websocket = new WebSocket("ws://localhost:8888/ws");

websocket.onopen = () => {
 console.log("Koneksi WebSocket dibuat");
 websocket.send("Halo dari klien!");
};

websocket.onmessage = (event) => {
 console.log("Pesan diterima:", event.data);
};

websocket.onclose = () => {
 console.log("Koneksi WebSocket ditutup");
};

Autentikasi dan Keamanan

Keamanan adalah aspek penting dari pengembangan aplikasi web. Tornado menyediakan beberapa fitur untuk membantu Anda mengamankan aplikasi Anda, termasuk autentikasi, otorisasi, dan perlindungan terhadap kerentanan web umum.

Autentikasi:

Autentikasi adalah proses verifikasi identitas pengguna. Tornado menyediakan dukungan bawaan untuk berbagai skema autentikasi, termasuk:

Otorisasi:

Otorisasi adalah proses menentukan apakah pengguna memiliki izin untuk mengakses sumber daya tertentu. Anda dapat mengimplementasikan logika otorisasi di request handler Anda untuk membatasi akses berdasarkan peran atau izin pengguna.

Praktik Terbaik Keamanan:

Deployment

Mendeploy aplikasi Tornado melibatkan beberapa langkah, termasuk mengkonfigurasi server web, menyiapkan manajer proses, dan mengoptimalkan kinerja.

Server Web:

Anda dapat mendeploy Tornado di belakang server web seperti Nginx atau Apache. Server web bertindak sebagai reverse proxy, meneruskan permintaan masuk ke aplikasi Tornado.

Manajer Proses:

Manajer proses seperti Supervisor atau systemd dapat digunakan untuk mengelola proses Tornado, memastikan bahwa proses tersebut secara otomatis dimulai ulang jika mogok.

Optimisasi Kinerja:

Internasionalisasi (i18n) dan Lokalisasi (l10n)

Saat membangun aplikasi untuk audiens global, penting untuk mempertimbangkan internasionalisasi (i18n) dan lokalisasi (l10n). i18n adalah proses merancang aplikasi agar dapat diadaptasi ke berbagai bahasa dan wilayah tanpa perubahan rekayasa. l10n adalah proses mengadaptasi aplikasi yang telah diinternasionalisasi untuk bahasa atau wilayah tertentu dengan menambahkan komponen spesifik lokal dan menerjemahkan teks.

Tornado dan i18n/l10n

Tornado sendiri tidak memiliki pustaka i18n/l10n bawaan. Namun, Anda dapat dengan mudah mengintegrasikan pustaka Python standar seperti `gettext` atau kerangka kerja yang lebih canggih seperti Babel untuk menangani i18n/l10n dalam aplikasi Tornado Anda.

Contoh menggunakan `gettext`:

1. **Siapkan lokal Anda:** Buat direktori untuk setiap bahasa yang ingin Anda dukung, berisi katalog pesan (biasanya file `.mo`).

locales/
 en/LC_MESSAGES/messages.mo
 fr/LC_MESSAGES/messages.mo
 de/LC_MESSAGES/messages.mo

2. **Ekstrak string yang dapat diterjemahkan:** Gunakan alat seperti `xgettext` untuk mengekstrak string yang dapat diterjemahkan dari kode Python Anda ke dalam file `.po` (Portable Object). File ini akan berisi string asli dan placeholder untuk terjemahan.

xgettext -d messages -o locales/messages.po your_tornado_app.py

3. **Terjemahkan string:** Terjemahkan string dalam file `.po` untuk setiap bahasa.

4. **Kompilasi terjemahan:** Kompilasi file `.po` menjadi file `.mo` (Machine Object) yang digunakan oleh `gettext` saat runtime.

msgfmt locales/fr/LC_MESSAGES/messages.po -o locales/fr/LC_MESSAGES/messages.mo

5. **Integrasikan ke dalam aplikasi Tornado Anda:**

import gettext
import locale
import os
import tornado.web

class BaseHandler(tornado.web.RequestHandler):
 def initialize(self):
  try:
  locale.setlocale(locale.LC_ALL, self.get_user_locale().code)
  except locale.Error:
  # Tangani kasus di mana lokal tidak didukung oleh sistem
  print(f"Lokal {self.get_user_locale().code} tidak didukung")

  translation = gettext.translation('messages', 'locales', languages=[self.get_user_locale().code])
  translation.install()
  self._ = translation.gettext

 def get_current_user_locale(self):
  # Logika untuk menentukan lokal pengguna (misalnya, dari header Accept-Language, pengaturan pengguna, dll.)
  # Ini adalah contoh yang disederhanakan - Anda akan memerlukan solusi yang lebih kuat
  accept_language = self.request.headers.get('Accept-Language', 'en')
  return tornado.locale.get(accept_language.split(',')[0].split(';')[0])

class MainHandler(BaseHandler):
 def get(self):
  self.render("index.html", _=self._)

settings = {
 "template_path": os.path.join(os.path.dirname(__file__), "templates"),
}

app = tornado.web.Application([
 (r"/", MainHandler),
], **settings)

6. **Ubah template Anda:** Gunakan fungsi `_()` (terikat pada `gettext.gettext`) untuk menandai string untuk terjemahan di template Anda.

<h1>{{ _("Selamat datang di situs web kami!") }}</h1>
<p>{{ _("Ini adalah paragraf yang diterjemahkan.") }}</p>

Pertimbangan Penting untuk Audiens Global:

Topik Lanjutan

Halaman Kesalahan Kustom:

Anda dapat menyesuaikan halaman kesalahan yang ditampilkan Tornado saat terjadi kesalahan. Ini memungkinkan Anda memberikan pengalaman yang lebih ramah pengguna dan menyertakan informasi debug.

Pengaturan Kustom:

Anda dapat mendefinisikan pengaturan kustom dalam konfigurasi aplikasi Anda dan mengaksesnya di request handler Anda. Ini berguna untuk menyimpan parameter spesifik aplikasi, seperti string koneksi database atau kunci API.

Pengujian:

Uji aplikasi Tornado Anda secara menyeluruh untuk memastikan aplikasi berfungsi dengan benar dan aman. Gunakan pengujian unit, pengujian integrasi, dan pengujian end-to-end untuk mencakup semua aspek aplikasi Anda.

Kesimpulan

Tornado adalah kerangka kerja web yang kuat dan serbaguna yang sangat cocok untuk membangun aplikasi web yang skalabel dan berkinerja tinggi. Arsitektur asinkronnya, dukungan WebSocket, dan API yang mudah digunakan menjadikannya pilihan populer bagi pengembang di seluruh dunia. Dengan mengikuti panduan dan contoh dalam panduan komprehensif ini, Anda dapat mulai membangun aplikasi Tornado Anda sendiri dan memanfaatkan banyak fiturnya.

Ingatlah untuk merujuk ke dokumentasi resmi Tornado untuk informasi terbaru dan praktik terbaik. Selamat membuat kode!