Tutorial Autocomplete Dengan Select2 dan Laravel – Kasus User Role

Pada tutorial berikut ini saya ingin membahas sederhana cara membuat autocomplete dengan Select2 pada Laravel. Pada tutorial ini diharapkan kawan-kawan bisa mengintegrasikan autocomplete ini pada project atau aplikasi Laravel kawan-kawan.

Asumsi disini adalah saya memiliki data user yang cukup banyak, jadi tidak mungkin kita tampilkan semua karena pasti akan membuat aplikasi Laravel kita jadi lambat.

Setiap user memiliki 1 role. Role ini seperti jabatan dan pada kasus autocomplete ini, data role tidak dibuat autocomplete karena data role tidak begitu banyak di aplikasi. Jika nanti kedepan banyak, mungkin saatnya kita buatkan autocomplete pada data role juga. Continue reading Tutorial Autocomplete Dengan Select2 dan Laravel – Kasus User Role

Tutorial Cara Preview Gambar Sebelum Diupload

Kadang ada user yang ingin mengupload gambar namun sebelum diproses atau disimpan pada database atau storage server ingin di preview terlebih dahulu. Hal ini mungkin akan sangat bermanfaat jika gambar yang diupload banyak sehingga perlu preview terlebih dahulu.

Di jQuery ada cara yang sangat mudah. Berikut adalah cara melakukannya.

Pertama siapkan file HTML lalu buat seperti ini.

<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</head>
<body>
<input type="file" multiple id="uploadImage">
<div class="div_image"></div>
</body>
</html>

Lalu kita tambahkan javascript seperti kode berikut.

$(function() {
    // Multiple images preview in browser
    var imagesPreview = function(input, placeToInsertImagePreview) {

        if (input.files) {
            var filesAmount = input.files.length;

            for (i = 0; i < filesAmount; i++) {
                var reader = new FileReader();

                reader.onload = function(event) {
                    $($.parseHTML('<img>')).attr('src',event.target.result).appendTo(placeToInsertImagePreview);
                }

                reader.readAsDataURL(input.files[i]);
            }
        }

    };

    $('input#uploadImage').on('change', function() {
        imagesPreview(this, '.div_image');
    });
});

Dan hasilnya bisa temen-temen coba di sini: https://jsfiddle.net/adiputra/4nmLqfxk/2/

Pilih beberapa gambar lalu temen-temen akan melihat gambar langsung di preview.

Menarik ya.

Selamat mencoba Tutorial Cara Preview Gambar Sebelum Diupload πŸ™‚

Cara Setting Sederhana Laravel dan Docker

Berawal dari satu project yang memiliki environtment development yang berbeda. Saya mencoba membiasakan setup project entah dengan bahasa apapun dengan docker. Lalu apa sebenarnya docker itu? dan masalah seperti apa yang menyebabkan kita menggunakan docker?

Jawabannya itu sederhana, misalnya di local laptop kita terinstall MySQL versi 5.7. Sedangkan project hanya berjalan lancar di versi 5.6.

Apa yang harus kita lakukan? Jawaban-nya itu biasanya kita downgrade mysql menjadi versi 5.6. Tapi project lainnya yang ada di local laptop dan menggunakan MySQL versi 5.7 kita bagaimana? Dilema πŸ˜€

Saat inilah kita harus mencoba docker. Continue reading Cara Setting Sederhana Laravel dan Docker

Queue Proses dengan Celery

Proses antrian/queue pada artikel sebelumnya saya tulis dengan Laravel sudah dijelaskan bagaimana antrian bisa menghandle proses-proses yang memakan waktu lama, istilahnya kita jalankan di background system. Penasaran saya coba bagaimana Python melakukan hal yang sama. Setelah searching, ketemu Celery. Salah satu yang banyak digunakan oleh developer Python untuk membuat queue job pada aplikasi mereka. Pengguna salah satu ternama adalah Instagram, waw πŸ™‚

Pada laravel, broker atau pengantar job/message bisa menggunakan Redis, RabitMQ, Database, ataupun SQS nya Amazon. Di Celery pun hampir semua bisa digunakan dan satu lagi kita bisa menyimpan hasil dari queue ke database atau nosql database, istilahnya backend result.

Penasaran, saya mau coba sederhana membuat task queue Celery dengan Python. Dan saya menemukan artikel yang mudah dan enak sekali dibaca.

https://www.agiliq.com/blog/2015/07/getting-started-with-celery-and-redis/

Sayangnya, artikel sudah 2015 ditulis, jadi mungkin ada perubahan. Btw, artikel ini enak banget dibaca dan mari kita coba implementasi sederhana.

Awalnya saya buat virtualenv dengan python 3 di folder project kita.

virtualenv venv -p python3

Lalu saya activekan virtual env dengan perintah

source venv/bin/activate

Setelah aktif, saya install Celery dan Requests karena pada artikel tersebut mencoba menjelaskan bagaimana mengakses (curl di php) website dengan python.

Install Celery

pip install -U "[celery-redis]"

Karena saya ingin menggunakan broker redis, maka install celery seperti diatas :), jika ingin menggunakan RabitMQ, installnya beda ya, coba cek documentasinya.

Setelah itu saya install requests

pip install requests

Seperti biasa, saya biasa membuat folder src lalu didalamnya berisi file app.py. Kode dari file tersebut adalah sebagai berikut:

from celery import Celery
import requests

app = Celery('app', broker='redis://localhost:6379/0')

@app.task
def fetch_url(url):
    resp = requests.get(url)
    print(resp.status_code)

def func(urls):
    for url in urls:
        fetch_url.delay(url)

if __name__ == "__main__":
    func(["http://google.com", "https://amazon.com", "https://facebook.com", "https://twitter.com", "https://alexa.com"])

Pada kode tersebut saya import celery lalu requests. Lalu saya buat object celery dengan nama app. Lalu terlihat ada broker url (redis) yang saya gunakan. Dari sini saja kita harus mengaktifkan redis-server pada linux kita. Jika ada yang belum ada redis, jangan lupa install dulu ya.


[crp]


Sampai disitu, saya masukan decorator celery @app.task, dimana decorator tersebut memberikan flag/tanda bahwa fungsi tertentu (dalam hal ini fetch_url()) adalah fungsi yang bisa dijalankan dengan queue celery.

Dalam blok fungsi fetch_url() sederhana saja mengakses website lalu jika berhasil print kode hasil request.

Setelah itu, main fungsi adalah memanggil fungsi def func(urls), yang berisi list url website yang ingin diakses. Nah pada fungsi tersebut kita loop, lalu kita panggil fungsi decorator celery yaitu fetch_url() dengan penambahan fungsi .delay().

def func(urls):
    for url in urls:
        fetch_url.delay(url)

Jika anda tidak menggunakan celery atau queue system, proses ini masti berjalan menunggu hasil dari tiap-tiap website. Namun jika kita menggunakan queue, proses ini dijalankan di background sehingga proses menjadi lebih cepat.

Setelah itu, untuk mencobanya, mari kita coba jalankan perintah untuk mengaktifkan app.py tersebut sebagai celery queue.

celery -A app worker --loglevel=info

Dimana, anda mesti satu level folder dengan app.py. Sehingga akan menampilkan seperti gambar dibawah ini jika berhasil.

Pada gambar diatas, menandakan bahwa Celery anda siap untuk dijalankan. Mari kita coba panggil proses di app.py agar dijalankan oleh Celery sebagai queue.

python src/app.py

Jika dijalankan, proses pasti tidak menunggu lama ya. Dan jika dilihat ke terminal celery akan muncul seperti gambar ini:

Terlihat bahwa proses sudah dijalankan oleh Celery “succeeded”.

Beberapa fitur lain bisa dibaca di documentasi. Penjelasan lebih lengkap juga bisa dilihat di link diatas. Selamat mencoba πŸ™‚

Kirim data dari server ke klien atau sebaliknya dengan SocketIO dan Flask

Artikel ini berisi cara implementasi mengirim data dari server ke klien dengan SocketIO dan Flask. Dalam hal ini “server” adalah bahasa yang digunakan untuk mengakses data server seperti PHP, Python, Java, dan lainnya. Lalu “klien” adalah lingkungan yang biasa dilihat oleh user seperti browser, aplikasi mobile android / ios. Jika berbicara browser pasti tidak lepas dari HTML dan Javascript πŸ™‚

Artikel ini juga membahas socket.io sebagai media untuk membantu menghubungkan proses tersebut. Dalam website socket.io tertulis

“Socket.IO enables real-time bidirectional event-based communication.
It works on every platform, browser or device, focusing equally on reliability and speed.”

Socket.io membantu proses realtime komunikasi berdasarkan event secara bidireksional. Dapat digunakan di setiap platform, browser atau device dengan memfokuskan kecepatan dan reliabiliti.

Saya penasaran apakah Flask Python bisa menghandle proses ini seperti Laravel pun sudah bisa. Dan ternyata sudah ada yaitu Flask-SocketOi, https://flask-socketio.readthedocs.io/en/latest/.

Mari kita coba bermain dengan library python ini.

Langkah #1

Awalnya, buat folder dengan sembarang nama, misalnya saya ini “flask-socketio-test”.

Langkah #2

Masuk ke dalam folder “flask-socketoi-test” lalu kita buat virtualenv dengan perintah.

virtualenv venv -p python3

“venv” sebagai nama folder untuk virtual environtment python.

Langkah #3

Aktifkan virtualenv dengan perintah.

source venv/bin/activate

*perintah ini hanya dijalankan di lingkungan linux. Untuk windows, silahkan cari tahu ya di google.

Langkah #4

Instlal flask-socketio dengan perintah.

pip install flask-socketio

Setelah itu kita buat folder src lalu buat file app.py didalamnya. Lalu buat pula folder templates yang didalamnya berisi file index.html. Kosongkan saja dulu.

Setelah berhasil membuat folder dan file. Mari kita lanjutkan di proses selanjutnya.

Langkah #5

Buka file app.py, lalu code seperti dibawah ini.

from flask import Flask, render_template, request
from flask_socketio import SocketIO

app = Flask(__name__)
app.config['SECRET_KEY'] = 'THIS IS SECRETKEY 1231412'
socketio = SocketIO(app)

@app.route('/')
def index():
	return render_template('index.html')

@app.route('/kirim')
def kirim_data():
	socketio.emit('my_response', {'data': 'data 1'}, namespace='/app1')
	return ('', 204)

@socketio.on('data_dari_browser', namespace='/app1')
def menerima_data(json):
    print('menerima data json: ' + str(json))

if __name__ == '__main__':
	socketio.run(app)

Jika dilihat terdapat route “/” yang mengarah ke file index.html. Isi dari file index.html adalah sebagai berikut.

<!DOCTYPE HTML>
<html>

<head>
    <title>Flask-SocketIO Test</title>
    <script type="text/javascript" src="//code.jquery.com/jquery-1.4.2.min.js"></script>
    <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.5/socket.io.min.js"></script>
    <script type="text/javascript" charset="utf-8">
        $(document).ready(function () {
            namespace = '/app1';
            
            // initial socket object
            var socket = io.connect(location.protocol + '//' + document.domain + ':' + location.port + namespace);

            // sending data through socketio
            socket.on('connect', function () {

                // kirim data dari klien
                // dari klien ini bisa dari browser, atau dari mobile apps
                // biasa nya berupa form input
                socket.emit('data_dari_browser', { data: 'saya dari klien' });
            });

            socket.on('my_response', function (msg) {
                $('#log').append('<br>' + $('<div/>').text('Menerima data #' + msg.data).html());
            });
        });
    </script>
</head>

<body>
    <h1>Flask-SocketIO Test</h1>
    <div id="log"></div>
</body>

</html>

Baik, saya jelaskan per proses ya.

Mengirim data dari klien (browser) ke server

Untuk mengirim data dari klien ke server ini seperti proses ajax pada umumnya. Bedanya adalah kita tanpa jquery atau vanilla js. Kita pakai socket.io untuk mengirim data dari browser ke server.


[crp]


Pengirim dari browser itu terlihat di baris kode ini.

socket.emit('data_dari_browser', { data: 'saya dari klien' });

Pastikan sudah pasang object socket dulu diatas sebelumnya. Lalu perhatikan terdapat namespace yang mengarahkan data ini akan diterima oleh server. Jika namespace ini berbeda dengan server, maka data tidak akan diterima.

Penerimaan data di sisi server bisa dilihat di app.py di fungsi berikut.

@socketio.on('data_dari_browser', namespace='/app1')
def menerima_data(json):
    print('menerima data json: ' + str(json))

Kita coba jalankan dengan perintah

python src/app.py

Lalu server berjalan ke port 5000, *default port flask dalam membuat server. Dan kita coba akses ke port tersebut dengan Firefox maka pada terminal python kita akan terlihat bahwa data telah diterima seperti gambar dibawah ini.

menerima data socket.io flask

Sesuai ya. Dari data tersebut bisa digunakan untuk akses database atau kebutuhan lainnya.

Mengirim data dari server ke klien (browser)

Mengirim data dari klien ke server sepertinya mudah dan sudah biasa dilakukan ya oleh teman-teman. Nah sekarang bagaimana mengirim data dari server ke klien tanpa refresh/reload page? Kodenya udah ada kok di atas. Mari kita coba liat ya.

Kode dari server untuk mengirim ke klien itu kita lihat dulu kode di sisi server yaitu di file app.py. Kode pengirimannya tepat di kode ini.

@app.route('/kirim')
def kirim_data():
	socketio.emit('my_response', {'data': 'data 1'}, namespace='/app1')
	return ('', 204)

Pada kode ini saya buat route dengan “/kirim” lalu tiap ada browser yang memanggil url tersebut maka akan menjalankan kode untuk mengirim data dari server ke klien dengan perintah emit tersebut.

Pastikan flag “my_response” dan namespace itu sama dengan yang di klien (kode index.html). Karena jika tidak sama maka tidak akan diterima lho πŸ™‚

Lalu bagaimana klien / browser menerima data dari server? mari kita lihat index.html dan terlihat kode untuk menerimanya seperti berikut.

socket.on('my_response', function (msg) {
  $('#log').append('<br>'+$('<div/>').text('Menerima data #'+msg.data).html());
});

Terima data dengan variable msg, lalu tempel ke html. Sederhana juga ya πŸ˜€

mengirim data flask-socketio

Dari sini kita sudah dapat mengirim data dari server ke klien dengan bantuan socket.io bersama flask. Kebutuhan untuk proses ini banyak sekali, salah satunya ada konsep chatting yang membutuhkan proses secara bidireksional event.

Apa saja aplikasi yang bisa memanfaatkan proses ini? coba kamu bayangkan mengirim data dari server ke klien tanpa refresh/reload dengan resources minim.

Karena kalau pakai method long polling ajax itu bikin server ngap-ngapan lho. πŸ™‚

Ada beberapa fitur lain seperti membuat group, membuat broadcast dan lainnya, silahkan lihat referensi dibawah artikel ini.

Selamat mencoba πŸ™‚

Referensi:

Belajar Python: Membuat blog di terminal dengan mongodb

Inget dulu waktu kuliah membuat menu sederhana untuk menampilkan data dalam array di terminal dengan bahasa C. Dari situ saya bisa tahu apa itu fungsi, bagaimana cara memanggil fungsi lalu menampilkannya dalam screen terminal. Waktu itu kisaran tahun 2009-2010. Week lama juga ya..

Lanjut ke HTML, Javascript, PHP mulai diajarkan apa itu web dan cara membuat form lalu data masuk ke MySQL. Dari step-by-step tersebut saya yakin bahwa proses belajar itu mesti terstruktur dan berlanjut. Tidak ada proses belajar yang kilat. Saya pun gak seneng itu pesantren kilat #alah

Ingin nge-dalemin bahasa Python, step-nya pun saya pikir mesti begitu. Perlu kesabaran dan kini mesti di target sampai bisa buat ini mesti berapa hari dan setelah itu coba belajar yang lain kembali. Ada kawan yang mungkin umur sudah 40an tahun bergulat di dunia pemrograman. Dia sangat menikmati passion dan visioner tentang apa yang dia lakukan kedepan. Melihat pasar Indonesia yang katanya begitu ancur soal rates seorang programmer, dia cari kerjaan di Upwork dan akhirnya mendapatkan kesempatan bekerja di perusahaan luar dengan gaji dollar tapi biaya hidup pedesaan Indonesia..#manisbgt

Satu hal yang saya ambil dari dirinya itu adalah pengalaman tidak bisa dibeli. Orang lain punya skill yang banyak tapi pengalaman bekerja remote/freelance seperti negosiasi, cara komunikasi dengan sesama remote worker itu tidak bisa dibeli di Udemy ataupun kursus di Indonesia πŸ˜€

Weeh jadi ngelantur, intinya semangat belajar skill terbaru yang ingin kamu pelajari ya. Nikmati beberapa proses yang sedang kita jalani.

Saya baru aja mulai kembali untuk belajar Python nih di Udemy [https://www.udemy.com/the-complete-python-web-course-learn-by-building-8-apps/], beberapa kode saya masukan di github. Ini salah satunya: https://github.com/adiputra22/blog-python-terminal

Membuat Queue sederhana dengan Database pada Laravel

Queue adalah salah satu teknik agar proses pada aplikasi kita dapat berjalan secara mengantri. Kenapa dibuat mengantri? kadang beberapa proses dilakukan sesuai dengan antrian sehingga berjalan sesuai flow yang direncanakan.

Pada laravel, proses queue sudah sangat mudah dilakukan. Pada artikel ini saya coba jelaskan contoh simple membuat queue pada proses tertentu. Diharapkan dengan membaca artikel ini, pembaca mengetahui proses kerja queue dengan database pada Laravel. Untuk production, saya sarankan untuk menggunakan redis atau amazon sqs atau driver lainnya yang lebih baik dari database.

# Langkah 1
Membuat proyek laravel, saat artikel ini dibuat, saya menggunakan Laravel 5.5 LTS. Jika dikemudian hari laravel sudah berubah, mohon disesuaikan dengan dokumentasi. Saya membuat folder laravel-jobtable

# Langkah 2
Setelah kita menginstall laravel 5.5, kita buat database pada mysql local kita. Pada artikel ini saya buat “laravel-jobtable”.

# Langkah 3
Setelah membuat database tersebut, kita sesuaikan di konfigurasi laravel dengan mysql database di file .env


[crp]


# Langkah 4
Setelah langkah ketiga telah dilakukan, mari kita coba jalankan proses migration untuk menyimpan queue laravel pada database dengan cara mengetikan pada terminal seperti pada gambar dibawah ini.

php artisan queue:job
php artisan queue:job

Setelah berhasil lanjutkan dengan php artisan migrate.

migrate job success
migrate job success

Setelah berhasil, cek database kita. Apa benar database sudah terinstall table-table yang telah berhasil di migrate.

tables current
tables current

Lalu kita lihat ada table jobs, data masih kosong dan struktur seperti gambar dibawah ini.

empty jobs
empty jobs

Nanti table jobs inilah yang berisi queue/atrian yang akan kita jalankan pada proyek laravel kita. Lanjut ke langkah berikutnya ya.

# Langkah 5
Pada langkah ini, mari kita coba membuat dua proses untuk melakukan atrian. Proses ini saya sebut juga job. Pada laravel, kita dapat mudah mengetikan perintah “php artisan make:job “. Pada artikel ini saya buat JobPertama dan JobKedua sebagai percobaan.

laravel job pertama dan kedua
laravel job pertama dan kedua

Baik, mari kita edit kedua job tersebut. File kedua job tersebut berada pada folder /app/Jobs/.

Lalu saya coba menuliskan job untuk write log untuk melihat apakah benar job tersebut berjalan sesuai yang diharapkan atau tidak.

File /app/Jobs/JobPertama.php

<?php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;

use Log;

class JobPertama implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    private $data;
    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct($data)
    {
        $this->data = $data;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        Log::info('Ini log dari JobPertama dengan data ' . $this->data);
    }
}

 

File /app/Jobs/JobKedua.php

<?php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;

use Log;

class JobKedua implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    private $data;
    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct($data)
    {
        $this->data = $data;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        Log::info('Ini log dari JobKedua dengan data ' . $this->data);
    }
}

Pada kedua job tersebut, saya menambakan Log untuk menuliskan log dari job yang telah kita buat. Ada flag darimana log tersebut dibuat sehingga kita bisa mengetahui apa benar proses sesuai dengan yang kita harapkan?

# Langkah 6

Setelah kita buat job, saatnya kita panggil job tersebut. Job akan berjalan sesuai dengan antrian/queue yang telah kita buat. Cara panggilnya mudah, kita buka controller atau lokasi yang ingin menggunakan job pertama dan job kedua ini lalu sisipkan kode seperti pada contoh ini.

Sebelumnya kita buat dulu controller dengan nama misalnya HomeController. Karana default laravel 5.5 belum ada controllernya.

Berikut kode dari HomeController.

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Jobs\JobPertama;
use App\Jobs\JobKedua;

class HomeController extends Controller
{
    public function index() {

        JobPertama::dispatch('belajar queue dengan');
        JobKedua::dispatch('laravel');

        return "berhasil";

    }
}

Pada HomeController itu kita include JobPertama dan JobKedua, lalu kita panggil dengan <namajob>::dispatch(<data yang ingin dilempar ke job>).

Data yang ingin dilempar ke job itu nanti di handle di construct method job tersebut. Dan prosesnya ada di method handle πŸ™‚

Setelah itu mari kita panggil HomeController tersebut dengan menyetting route web ‘/’ mengarah ke HomeController method index.

Langkah 7:

Setelah itu, jangan lupa file .env terdapat konfigurasi untuk menyetting driver queue yang ingin kita gunakan. Defaultnya laravel menggunakan sync. GantiΒ QUEUE_DRIVER=sync menjadiΒ QUEUE_DRIVER=database.

Langkah 8:

Jalankan artisan serve πŸ™‚ lalu lihat pada /storage/logs/laravel.log.

Jika selesai halaman akan memunculkan “berhasil”. Apakah ada data yang tersimpan pada log? Dan saat itu juga, mari kita lihat database table jobs. Apakah ada perubahan atau tidak ya?

Yap ada data ya

job menunggu perintah
job menunggu perintah

Pada gambar diatas terlihat ada 2 job yang tersimpan. Pada table tersebut adalah list dari job yang akan dijalankan oleh laravel. Karena kita belum memanggil satu fungsi untuk menjalankan job tersebut. Maka job tersebut akan terlist pada table tersebut.

Mari kita coba jalankan perintah untuk memanggil job dengan perintah “php artisan queue:work”.

Lalu sekarang cek kembali table jobs tersebut. Sudah hilang ya data-datanya. Itu karena data jobs telah terpanggil untuk dijalankan. Sekarang coba lihat file /storage/logs/laravel.log.

hasil log queue

Yap, sekarang sudah ada log nya yaa..

Begitulah kira-kira cara kerja job queue.

  • Kita buat job
  • Dijalankan HomeController
  • Proses di HomeController hanya untuk menuliskan job ke table jobs
  • Setelah HomeController berhasil menuliskan job tersebut. Proses HomeController selesai.
  • JobPertama dan JobKedua dijalankan oleh laravel queue:work dengan membaca table jobs tersebut di background proses.
  • Jadi ada 2 proses, proses di HomeController dan proses di background

Coba kita bayangkan ada proses pengiriman email pada HomeController. Dimana pengiriman email tersebut belum menggunakan job.

  • Jalankan HomeController
  • Jalankan proses yang ada HomeController salah satunya adalah pengiriman email.
  • Waktu pengiriman email kisaran 3-5 detik tergantung dengan koneksi
  • Sampai pengiriman email berhasil, HomeController berhasil dipanggil
  • Jadi ada proses dan waktu menunggu pengiriman email dari proses HomeController tersebut.

Jika kita buat job dalam pengiriman email akan lebih simpel karena proses di HomeController hanya menyimpan job pengiriman email ke table jobs. Sedangkan proses pengiriman email dilakukan di background (secara terpisah). Sehingga tidak memakan waktu yang lama.

Pada proses ini tidak terlihat, silahkan coba buat job untuk pengiriman email ke mailtrap.io untuk mencoba.

Copy-Paste Token dengan Postman Jadi Lebih Mudah

Restful pasti beberapa menggunakan sistem auth token dimana token menjadi key untuk bisa masuk mengakses data resource tertentu yang sifatnya tidak public. Misalnya, jika ingin mengakses data order dari satu customer tertentu, maka untuk mengaksesnya kita membutuhkan identitas order milik siapa ini? Nah biasanya kan kita pakai session, di Restful tidak mengenal session jadi perlu token untuk mengetahui id atau kepemilikan order tersebut.

Token ini bersifat sementara, jika temen-temen menggunakan tokopedia/bukalapak apps android. Kadang mereka meminta untuk login ulang. Kenapa login ulang? karena token sudah expired jadi kita perlu mendapatkan token lagi dengan cara login kembali ke sistem mereka.

Pada real kenyataannya adalah orang testing atau programmer pasti melakukan test untuk akses data order dengan token. Nah karena token ini berubah-ubah, jika di Postman saya biasanya akses kembali auth/login. Lalu setelah dapet token, token itu saya copy lalu saya paste pada resources order di headernya. Jadi repot mesti copy-paste bolak-balik jika token berubah.


[crp]


Untungnya, Postman lagi-lagi memudahkan kita dalam melakukan development/testing dengan linkungan postman. Di Postman ada istilah “Test”, dalam artian linkungan untuk melakukan testing. Ada banyak langkah-langkahnya sebenernya, temen-temen bisa lihat di link ini untuk dokumentasi lebih lengkap. https://www.getpostman.com/docs/postman/scripts/test_scripts

Balik ke kasus kita tadi, kita ingin ketika kita mendapatkan token baru, resource seperti order atau resource lain seperti data profile, data history wallet atau data lainnya yang terikat dengan token itu otomatis ter-set/tersimpan dengan token yang baru. Bagaimana caranya set di Postman?

Pada endpoint login/auth temen-temen, tinggal ditambahkan kode untuk test di Postman seperti endpoint saya ini.

Postman Test 1
Postman Test 1

Pada gambar saya arahkan ke tab “Tests”, lalu saya isi seperti diatas:
var jsonData = JSON.parse(responseBody);. Kita buat variable dengan nama jsonData dimana isinya itu adalah result dari endpoint /auth ini. Terlihat JSON.parse(responseBody) melakukan parse dari responseBody si Postman.
tests[“Access Token is not empty”] = jsonData.access_token !== undefined;. Kode ini adalah memberikan flag/tanda suatu test atau memberikan nama suatu flag/tanda test. Pada kode itu saya kasih nama test “Access token is not empty”, nanti valuenya itu berupa boolean (false or true) sesuai dengan kondisi dari pembanding setelahnya yaitu kode “jsonData.access_token !== undefined”. Kode tersebut untuk mengecek bahwa responseBody itu yang kita simpan di variable jsonData itu pasti memiliki data access_token.
postman.setEnvironmentVariable(“jwt_token”, jsonData.access_token);. Pada kode ini saya set variable/label Postman yaitu ‘jwt_token’ dengan isi dari jsonData.access_token. Nah variable/label Postman ini yang kita set pada resource yang membutuhkan token. Contoh kasus adalah misalnya berikut ini.

Postman Test 2
Postman Test 2

Format ini adalah format Flask-JWT. Jadi Authorization di isi value cukup dengan JWT {{ jwt_token }}. Nah jwt_token ini didapat dari tab “Tests” di endpoint /auth barusan.

Jadi dengan cara ini kita tidak perlu copy-paste token berulang kali pada Postman.

Keren ya si Postman πŸ™‚

Belajar membuat Restful sederhana dengan Flask-Restful dan Flask-JWT

Kini banyak website yang menggunakan Restful untuk konektifitas dengan database. Selain lebih cepat karena data tidak dipanggil secara langsung ketika website itu muncul, dengan restful pun kita mudah untuk melebarkan performance website yang mungkin beberapa dikenal dengan microservices arsitektur. Selain itu API Restful bisa digunakan untuk Android/IOS developer untuk merangkai kode-kode indahnya. Apapun itu sebenernya adalah kemajuan yang harus programmer pelajari untuk bisa survive. Ya survive!

Enaknya, bagian Backend developer itu tidak dipusingkan dengan aturan main dari CSS atau layout. Hanya menunggu permintaan dari Frontend developer. Frontend developer biasanya menggunakan javascript framework seperti Angular, VueJS ataupun React. Ketiga pemain ini sudah begitu besar dan kencang sekali di dunia pemrograman. Luarbiasa Javascript!

Pernah menggunakan Laravel sebagai API Restful, saya penasaran dengan beberapa teknologi dari nyoba-nyoba Spring Boot, lalu sampai ke Flask Restful. Entah kenapa belum kepingin nyobain NodeJs. Lalu kenapa Flask? Ini mudah banget bikin dan implementasinya. Selain itu memang saya ada plan juga untuk putus sama PHP karena value yang makin kesini makin turun saja. (updated belum bisa move on dari PHP karena kerjaan dan butuh harian keluarga :D)

Beberapa saya coba untuk membuat Flask Restfull sederhana dengan menyimpan data pada variable python dictionary. Berikut adalah URL Githubnya: https://github.com/adiputra22/flask-rest-beginner

Setelah itu mencoba untuk menyimpan data dengan SQLite. Karena SQLite sudah bawaan Flask, jadi tinggal pakai saja. Berikut adalah URL Githubnya: https://github.com/adiputra22/flask-rest-beginner-with-sqlite

Berhasil bermain SQLite, saya coba untuk integrasi ke MySQL. Dengan MySQL ini perlu tambahan lagi yaitu PyMySQL. Berikut adalah Githubnya: https://github.com/adiputra22/flask-rest-beginner-with-mysql

Ke MySQL berhasil, lalu saya nyobain ORM yang biasa digunakan python, yap SQLAlchemy. Belajar buat model lalu cara mengakses model pada Python sampai mencoba untuk setting ke Heroku. Hasil saya simpan di github: https://github.com/adiputra22/flask-rest-sqlite-sqlalchemy. Disini juga nyobain fitur keren si heroku auto deploy dari github ke live server https://flask-rest-sqlalchemy.herokuapp.com/

Kalau udah bisa konek dan manipulasi di database. Tinggal coba-coba yang lain seperti:
– mengatur gemana restful yang baik di flask (struktur folder, file) agar manage-nya gampang jika sudah besar
– mengatur performance dari restful flask. Dihitung dari sisi flask itu sendiri ya. Belum masuk ke settingan lainnya seperti best performance untuk MySQL/Postgresql. Belum lagi kita perlu setting best performance untuk server kita, dll, dll.

Diakhir mungkin ada yang bertanya kenapa Flask/Python?
– Pertama yang saya katakan diawal adalah kode-nya simple dan gampang baca-nya.
– Performa Python itu udah terkenal handal, ada youtube, bitbucket, udemy, instagram API dan lainnya
– Project diluar negeri banyak yang nyari Python, Rails dan lainnya. PHP banyak juga tapi nilai kecil dan yang main banyak juga jadi persaingan ketat banget πŸ˜€

Mengatur Environment Pada Postman

Yang baru menggunakan Postman pasti bingung ketika mencoba testing Restful di localhost dengan testing Restful di live server. Dulu saya copy paste url untuk mencoba url localhost dengan url live server. Ini agak merepotkan kita lho, untungnya Postman baik hati. Pada Postman kita diberikan akses kemudahan untuk mengatur lingkungan/environment dalam melakukan testing terhadap Restfull API yang telah kita buat.

Ketika pertama mungkin kita menuliskan URL Resfull seperti ini ya.

Restfull Postman 1
Restfull Postman 1

Kita Post URL tersebut untuk mengetahui jalan gak nih restful yang kita buat. Nah jika live server mungkin diganti dengan url “https://api.xxxx.id” ya..hehe

Ini merepotkan, baiknya buat environment dalam Postman, caranya adalah

Langkah pertama, Pojok kanan atas Postman ada icon pengaturan, tekan lalu pilih yang “Manage Environments

Postman Environment 1
Postman Environment 1

Baik, setelah itu akan muncul gambar seperti dibawah ini jika Manage Environments dipilih.

Postman Environment 2
Postman Environment 2

Pada gambar diatas, saya ada 1 environment yaitu section 6. Nah mari kita coba buat 1 lagi environment. Caranya adalah pilih “Add” sehingga muncul gambar seperti ini.

Postman Environment 3
Postman Environment 3

Pada kolom “Environment Name”, ketik sembarang sesuai keinginanmu. Misalnya saya ketik “LiveServer”.

Lalu pada kolom key, saya isi misalnya label “URL” dengan value misalnya “https://api.liveserver.id”


[crp]


Jika sudah, jangan lupa tekan tombol “Add” kembali untuk menyimpan perubahan yang telah kita lakukan bro.

Postman Environment 4
Postman Environment 4

Terlihat pada gambar, terdapat environment “LiveServer”, jika dipilih akan muncul label “URL” yang telah kita set sebelumnya. Setelah itu close aja.

Bisa di update dan ditambah gak ya? Bisa doong πŸ™‚ Sesuai kebutuhan aja..

Baik, setelah kita sudah set environment postman lalu mengisi label/variable pada postman tersebut. Mari kita pakai tuh variable “URL” di restful kita. Caranya adalah, pilih URL endpoint tertentu, misalnya saya disini endpoint get token /auth. Lalu ganti “http://localhost/” menjadi “{{URL}}” sehingga seperti gambar dibawah ini nih bro.

Postman Environment 5
Postman Environment 5

Bisa dilihat ya:

  1. Β URL nya kita set seperti itu yaa..jangan lupa terdapat “slash” karena diawal kita set URL variable postman itu tanpa slash.
  2. Di pojok kanan atas ada bacaan “No Environment”. Nah itu kita ganti dengan cara memilih environment yang barusan kita buat yaitu “LiveServer”.

Mantap, sekarang mau gonta ganti URL localhost atau liveserver itu jadi mudah. Tinggal ganti aja environment tersebut tanpa harus ganti-ganti lagi URL Restful kita. Mudah ya..

Nice Postman!

 

Cara Membuat JWT token dengan Flask

Lama tidak bermain dengan Flask mungkin kisaran 1 tahun lalu. Library python ini memang keren banget untuk belajar web dengan Python sebelum masuk ke Django. JWT sendiri biasa digunakan untuk Auth atau pembatasan penggunaan dari sisi API. Ngomong soal API, pasti ga jauh dengan development Android/IOS walaupun sekarang juga ada yang seneng buat aplikasi web dengan SPA (Single Page Application) yang membutuhkan API tentunya πŸ™‚

Flask sendiri ada library untuk handel JWT. Ada di link ini [https://pythonhosted.org/Flask-JWT/]. Penasaran mari kita coba yuk dengan bantuan Postman untuk mengetest-nya.

Seperti biasa kita buat folder dulu, lalu pastikan kita sudah menginstall Flask dan Flask-JWT.

pip install Flask-JWT

Setelah berhasil, masuk ke folder misalnya saya buat flask-jwt, lalu buat file app.py yang isinya seperti kode dibawah ini.

from flask import Flask
from flask_jwt import JWT, jwt_required, current_identity #1
from werkzeug.security import safe_str_cmp #2

class User(object): #3
  def __init__(self, id, username, password):
    self.id = id
    self.username = username
    self.password = password

  def __str__(self):
    return "User ID: " + str(self.id) + "<br />Username: " + self.username

#4
users = [
    User(1, 'joe', 'pass'),
    User(2, 'adiputra', 'yay')
]

username_table = {u.username: u for u in users} #5
userid_table = {u.id: u for u in users} #6

#7
def authenticate(username, password):
    user = username_table.get(username, None)
    if user and safe_str_cmp(user.password.encode('utf-8'), password.encode('utf-8')):
        return user

#8
def identity(payload):
    user_id = payload['identity']
    return userid_table.get(user_id, None)

app = Flask(__name__)
app.debug = True
app.config['SECRET_KEY'] = 'xxxadiputra-flask-jwt' #9

#10
jwt = JWT(app, authenticate, identity)

@app.route('/protected')
@jwt_required() #11
def protected():
    return '%s' % current_identity #12

if __name__ == '__main__':
    app.run()

Kode ini sebenernya saya ambil dari link diatas. Ada sedikit perubahan di data saja. Penjelasan per kode:

#1: Import Flask JWT dan kawan-kawannya.
#2: safe_str_cmp itu untuk security dan membandingkan 2 variable yang akan kita gunakan saat melakukan request/login guna mendapatkan token. Penjelasan lebih lengkap ada di sini (http://werkzeug.pocoo.org/docs/0.14/utils/)
#3: Membuat class dan object User. Karena ini percobaan saja jadi mungkin buat simplenya seperti ini. Kedepan mungkin mesti dihubungkan dengan database
#4: Mengisi object dari class User. Hanya sample user saja untuk kebutuhan login nanti
#5: Dictionary user untuk mendapatkan username saat login
#6: Dictionary user untuk mendapatkan spesifik user
#7: Fungsi login untuk mendapatkan token
#8: Fungsi untuk mengetest apakah token bisa digunakan untuk mendapatkan resource/data yang diinginkan berdasarkan token tersebut.
#9: Secret Key, ini untuk mendefinisikan secretkey aplikasi kita. JWT perlu setting secretkey ini
#10: Membuat object JWT dengan fungsi callback yang sudah kita setting sebelumnya. Callback fungsi ini ada banyak tidak hanya 2, bisa dibaca di link Flask-JWTnya ya.
#11: Decorator untuk membatasi fungsi tidak bisa diakses kecuali dengan token yang valid
#12: Mereturnkan String dari Object User yang telah kita set di __str__

Penjelasannya gitu aja ya, sekarang kita coba jalankan dengan memanggil app.py tersebut di terminal kita.

python app.py

Yap, setelah itu kita coba buka Postman lalu saya akses token terlebih dahulu seperti gambar dibawah ini.

Request Token Flask-JWT
Request Token Flask-JWT

Setelah saya “Send” akan muncul “access_token”: “xxxsdsdf”. Nah token ini yang kita pakai untuk mengetest apakah token ini bisa digunakan untuk mengakses fungsi protected. Berikut saya coba dan terlihat di gambar ini.

Test Token - Flask-JWT
Test Token – Flask-JWT

Terlihat pada gambar tersebut saya sisipkan Header dengan Authorization dengan pattern: “JWT” spasi Token yang didapat.

Alhasil, token bisa digunakan dan data user bisa didapat.

Sederhana ya, mungkin dilanjut ke bagian yang lebih tapi intinya sih flask-jwt ini bisa dipakai ya πŸ™‚

Selamat mencoba..