4. Docker dan RESTful API - Algoritma-dan-Pemrograman-ITS/camin-2023 GitHub Wiki
Docker dan API
Docker
Bayangkan ketika kita ingin memelihara 2 jenis ikan, yang satu adalah ikan air tawar, dan yang satu adalah ikan air asin, sementara kita hanya punya satu akuarium. Salah satu solusi yang terpikirkan adalah dengan memasang penyekat kedap air pada akuairum sehingga yang satu dapat diisi dengan air tawar dan yang satunya lagi dapat diisi dengan air asin. Kurang lebih seperti itulah docker bekerja.
Pada ilustrasi diatas, Docker membuat sebuah kontainer untuk masing-masing aplikasi dengan environment yang berbeda-beda, yang masing-masing kontainer memiliki environment yang mendukung aplikasi di dalamnya.
Sebelum kita mendalami penggunaan Docker pada Laravel, alangkah baiknya untuk melakukan instalasi Docker terlebih dahulu.
Pada Ubuntu
Pada Windows
Lakukan instalasi WSL (Windows Subsystem for Linux) terlebih dahulu di sini, barulah kemudian instal docker di sini.
Disclaimer: jika ukuran RAM kalian dibawah 8 GB (disarankan setidaknya memiliki RAM 12 GB atau lebih), disarankan untuk menginstall docker pada linux (bisa menggunakan virtual box atau dual boot)
Docker pada Laravel
Salah satu ciri-ciri adanya aplikasi yang menggunakan Docker, maka terdapat file docker-compose.yml
.
Buatlah sebuah file dengan nama docker-compose.yml
dan isikan file tersebut dengan contoh di bawah.
services:
# Database
db:
platform: linux/x86_64
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
restart: always
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: yourdb
MYSQL_PASSWORD: password
networks:
- mysql-phpmyadmin
# phpmyadmin
phpmyadmin:
depends_on:
- db
image: phpmyadmin
restart: always
ports:
- "8090:80"
environment:
PMA_HOST: db
MYSQL_ROOT_PASSWORD: password
networks:
- mysql-phpmyadmin
networks:
mysql-phpmyadmin:
volumes:
db_data:
Pada file diatas, nantinya Docker akan membuat sebuah kontainer dengan 2 layanan, yaitu database mysql
dan phpmyadmin
menggunakan image yang sudah ada pada Docker Hub. Jalankan command berikut untuk membuat kontainer yang diinginkan.
docker compose up -d
konsep image dan kontainer di sini mirip seperti konsep class dan object. class adalah sesuatu yang ada pada source code kita, dan object adalah hasil instansiasi dari class tersebut.
Buka http://localhost:8090/
(phpmyadmin dapat diakses pada port 8090 sesuai dengan isi docker-compose.yml
).
Kredensial dari phpmyadmin
sudah ada pada docker-compose.yml
, yaitu root:password
.
Kini project kita sudah memiliki sebuah database mysql
yang dapat diakses melalui phpmyadmin
. Sebelum melakukan migrasi, pastikan pada file .env
, kredensial database sudah cocok dengan kredensial pada phpmyadmin
.
Kemudian lakukanlah migrasi seperti yang sudah diajarkan.
Jika migrasi sukses, maka project kita sudah terhubung pada database yang ada di dalam kontainer Docker. Repository selengkapnya ada di sini.
Catatan: penulis lupa melakukan screenshot saat pertama kali melakukan migrasi, sehingga menggunakan rollback untuk memperlihatkan proses migrasi.
API
API (Application Programming Interface) adalah sebuah cara agar beberapa program dapat berkomunikasi satu sama lain. Hal ini akan sangat berguna ketika proyek yang kita lakukan memiliki beberapa program yang terpisah (Contoh: Program untuk Back-end dan Front-end).
Source: https://www.erp-information.com/
Spesifikasi API
Terdapat berbagai spesifikasi API, yang ada untuk menyelaraskan set of rules dan syntax.
RESTful API
Disebut juga REST API, API ini merupakan API yang mengikuti arsitektur REST (representational state transfer)
Kriteria
- Arsitektur client-server dengan messaging HTTP
- Bersifat stateless, tidak ada informasi client di tiap request dan tiap request terpisah
- Support caching
- Antarmuka yang seragam dalam pertukaran informasi
- Layered system
API Endpoint
API Endpoint adalah titik spesifik dimana API suatu program dapat diakses oleh program lain. Konsepnya nyaris sama dengan konsep URL dan URI yang pernah dibahas sebelumnya.
Laravel Resources
Laravel memiliki sebuah class Resources
yang berguna untuk melakukan formatting data menjadi bentuk JSON. Pada contoh kali ini, penulis menggunakan class Resources
untuk formatting data sebelum data tersebut kita kirimkan. Command dibawah akan otomatis membuat sebuah file pada direktori app/Http/Resources/CaminResources.php
.
php artisan make:resource CaminResource
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class CaminResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
*/
public function toArray($request)
{
return [
'nama' => $this->nama,
'angkatan_id' => $this->angkatan_id,
'nrp' => $this->nrp,
'jurusan' => $this->jurusan,
];
}
}
Berikut adalah bentuk response ketika tidak menggunakan Resources
:
Dan berikut ketika menggunakan Resources
:
Laravel API
Spesifikasi API Endpoint ada pada routes/api.php
. Sama seperti pada routes/web.php
, penambahan URI pada routes/api.php
akan menciptakan sebuah API Endpoint baru.
Route::get('/ping', function(){
return response()->json('Pong', 200);
});
Route::controller(CaminAPIController::class)->group(function () {
Route::get('/camin', 'index');
Route::get('/camin/{camins_id}', 'show');
Route::post('/camin', 'store');
Route::post('/camins', 'store_multiple');
Route::put('/camin/{camins_id}', 'update');
Route::delete('/camin/{camins_id}', 'destroy');
});
Pada contoh diatas, salah satu API Endpoint yang terbentuk adalah dengan URI /api/ping
.
Karena penggunaan URI pada routes/web.php
dan routes/api.php
berbeda (yang satu mengembalikan view, yang satu mengembalikan JSON), ada baiknya untuk membuat controller sendiri yang didedikasikan untuk API endpoint tersebut.
// fungsi index yang digunakan pada web.php
public function index()
{
$camins = Camin::all();
return view('camin.index', compact('camins'));
}
// fungsi index yang digunakan pada api.php
public function index()
{
$camins = CaminResource::collection(Camin::all());
return response()->json([
'status' => true,
'camins' => $camins
]);
}
Repository: https://github.com/Kadigas/camin-2023/tree/docker
Testing API
Ada banyak cara untuk melakukan pengecekan apakah API sudah bekerja sebagaimana seharusnya atau belum. Cara paling primitif adalah menggunakan command curl pada terminal.
Kita juga dapat melakukan pencarian API Endpoint pada browser kita, dan browser kita akan menampilkan responsenya.
Terdapat juga beberapa aplikasi seperti Postman dan Insomnia yang didedikasikan untuk pengembangan API.
Request Header dan Body
Setiap kali kita melakukan pemanggilan API, Client (kita) mengirimkan sebuah HTTP Request pada alamat dari API tersebut. HTTP Request Header berisi informasi tambahan yang terkadang diperlukan oleh program tempat API berada seperti authorization.
Adapun HTTP Request Body berisi file yang diperlukan oleh API jika API tersebut membutuhkan sebuah file seperti pada method POST.
Ketika kita memanggil suatu API, sebuah HTTP Response akan dikirimkan kepada kita dengan Header dan Body yang memiliki penggunaan serupa dengan HTTP Request.
Berikut adalah contoh HTTP Response Header setelah pemanggilan method GET:
200 OK
Access-Control-Allow-Origin: *
Connection: Keep-Alive
Content-Encoding: gzip
Content-Type: text/html; charset=utf-8
Date: Mon, 18 Jul 2016 16:06:00 GMT
Etag: "c561c68d0ba92bbeb8b0f612a9199f722e3a621a"
Keep-Alive: timeout=5, max=997
Last-Modified: Mon, 18 Jul 2016 02:36:04 GMT
Server: Apache
Set-Cookie: mykey=myvalue; expires=Mon, 17-Jul-2017 16:06:00 GMT; Max-Age=31449600; Path=/; secure
Transfer-Encoding: chunked
Vary: Cookie, Accept-Encoding
X-Backend-Server: developer2.webapp.scl3.mozilla.com
X-Cache-Info: not cacheable; meta data too large
X-kuma-revision: 1085259
x-frame-options: DENY
Pemanggilan API
Pengecekan API pada materi sebelumnya sudah termasuk pemanggilan API, namun terdapat beberapa fungsi, library, package, atau sejenisnya yang didedikasikan untuk melakukan pemanggilan API.
LARAVEL | JavaScript (Node) |
---|---|
Guzzle HTTP client (Facades\Http) | fetch, axios |
CORS
CORS (Cross-Origin Resource Sharing) adalah sebuah protokol atau mekanisme untuk pengambilan data dengan sumber dan tujuan yang berbeda.
Pada umumnya, Browser menggunakan SOP (Same-Origin Policy) sehingga browser akan memblokir konten jika terdapat perbedaan sumber (domain, port, protokol).
Hal ini dapat menjadi masalah saat integrasi Front-end dengan Back-end yang dapat diatasi dengan beberapa hal.
Modul ini hanya mengenalkan CORS namun belum dapat menjelaskan dengan rinci sekaligus penyelesaiannya. Diperlukan sumber lain untuk hal tersebut
Selengkapnya: https://www.contentstack.com/docs/developers/how-to-guides/understanding-and-resolving-cors-error/
Dokumentasi
Dokumentasi API adalah hal yang penting terlebih ketika kita membuatkan sebuah API yang bersifat publik. Penulis tidak memiliki pengalaman dalam hal ini, namun sebuah dokumentasi harus (menurut penulis) setidaknya memiliki:
- API Endpoint (termasuk query pada URI jika ada)
- Request (Header dan Body, lengkap dengan format data pada body seperti parameter apa yang ada, baik wajib dan opsional)
- Response (Header dan Body, lengkap dengan kemungkinan response yang ada seperti: 200, 400, 404, dsb)