Menu Navigasi

Tutorial Tutorial Pemrograman Part 54: PHP Microservices Architecture – Konsep, Implementasi, dan Scaling

AI Generated
29 Desember 2025
22 views
Tutorial Tutorial Pemrograman Part 54: PHP Microservices Architecture – Konsep, Implementasi, dan Scaling

Pendahuluan

Selamat datang di part 54 seri tutorial pemrograman PHP! Di part ini, kita akan menyelami dunia microservices architecture. Microservices adalah pendekatan arsitektur di mana aplikasi dibangun sebagai kumpulan layanan kecil yang independen, dikomunikasikan melalui API. Ini adalah topik advanced, tetapi pemahaman tentang ini sangat penting untuk membangun aplikasi yang scalable, maintainable, dan resilient. Sebagai prasyarat, Anda diharapkan sudah familiar dengan konsep dasar PHP, REST APIs, dan idealnya sudah memahami konsep Message Broker seperti RabbitMQ (seperti yang dibahas di Tutorial Pemrograman Part sebelumnya). Jika belum, sangat disarankan untuk membacanya terlebih dahulu.

Konsep Dasar Microservices

Bayangkan Anda memiliki toko serba ada yang besar. Pendekatan monolithic (semua dalam satu) adalah seperti semua karyawan toko melakukan semua pekerjaan – mulai dari memesan barang, melayani pelanggan, membersihkan toko, hingga menghitung keuangan. Jika satu orang sakit atau satu sistem rusak, seluruh toko terpengaruh.

Microservices adalah seperti membagi toko menjadi departemen-departemen kecil yang independen: departemen makanan, departemen pakaian, departemen elektronik. Setiap departemen memiliki karyawan sendiri, beroperasi secara independen, dan berkomunikasi dengan departemen lain jika diperlukan (misalnya, departemen makanan perlu tahu apakah inventarisnya mencukupi dari sistem inventaris terpusat). Jika departemen pakaian mengalami masalah, departemen makanan tetap bisa beroperasi. Inilah esensi dari resilience dan scalability.

Keuntungan Microservices

  • Scalability: Setiap service dapat di-scale secara independen, memungkinkan alokasi sumber daya yang efisien.
  • Independensi: Setiap service dapat dikembangkan, di-deploy, dan di-update secara independen, mempercepat siklus pengembangan.
  • Resilience: Kegagalan satu service tidak akan mempengaruhi service lain.
  • Fleksibilitas Teknologi: Setiap service dapat menggunakan teknologi yang paling cocok untuk tugasnya.

Hands-on Coding: Implementasi Sederhana dengan PHP

Mari kita buat contoh sederhana dengan dua microservices: UserService dan ProductService. UserService akan mengelola data pengguna, dan ProductService akan mengelola data produk. Keduanya akan berkomunikasi melalui REST API.

UserService

Buat folder user-service dan file index.php:


<?php
require_once 'vendor/autoload.php'; // Jika menggunakan Composer

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\Matcher\UrlMatcher;
use Symfony\Component\Routing\RequestContext;
use Symfony\Component\HttpKernel\Controller\ArgumentResolver;
use Symfony\Component\HttpKernel\Controller\ControllerResolver;

// Inisialisasi Router
$routes = new RouteCollection();
$routes->add('user_get', new Route('/users/{id}', ['_controller' => 'UserService::getUser']));

class UserService {
    public function getUser(Request $request) {
        $userId = $request->attributes->get('id');
        // Simulasi data pengguna
        $users = [
            1 => ['id' => 1, 'name' => 'John Doe', 'email' => 'john.doe@example.com'],
            2 => ['id' => 2, 'name' => 'Jane Doe', 'email' => 'jane.doe@example.com'],
        ];

        if (isset($users[$userId])) {
            $user = $users[$userId];
            $response = new Response(json_encode($user), 200, ['Content-Type' => 'application/json']);
        } else {
            $response = new Response(json_encode(['message' => 'User not found']), 404, ['Content-Type' => 'application/json']);
        }
        return $response;
    }
}

$request = Request::createFromGlobals();

$context = new RequestContext();
$context->fromRequest($request);
$matcher = new UrlMatcher($routes, $context);

$controllerResolver = new ControllerResolver();
$argumentResolver = new ArgumentResolver();

try {
    $parameters = $matcher->match($request->getPathInfo());
    $request->attributes->add($parameters);

    $controller = $controllerResolver->getController($request);
    $arguments = $argumentResolver->getArguments($request, $controller);

    $response = call_user_func_array($controller, $arguments);
} catch (Symfony\Component\Routing\Exception\ResourceNotFoundException $exception) {
    $response = new Response('Not Found', 404);
} catch (Exception $exception) {
    $response = new Response('An error occurred', 500);
}

$response->send();

ProductService

Buat folder product-service dan file index.php:


<?php
require_once 'vendor/autoload.php'; // Jika menggunakan Composer

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\Matcher\UrlMatcher;
use Symfony\Component\Routing\RequestContext;
use Symfony\Component\HttpKernel\Controller\ArgumentResolver;
use Symfony\Component\HttpKernel\Controller\ControllerResolver;

// Inisialisasi Router
$routes = new RouteCollection();
$routes->add('product_get', new Route('/products/{id}', ['_controller' => 'ProductService::getProduct']));

class ProductService {
    public function getProduct(Request $request) {
        $productId = $request->attributes->get('id');
        // Simulasi data produk
        $products = [
            1 => ['id' => 1, 'name' => 'Laptop', 'price' => 1200],
            2 => ['id' => 2, 'name' => 'Smartphone', 'price' => 800],
        ];

        if (isset($products[$productId])) {
            $product = $products[$productId];
            $response = new Response(json_encode($product), 200, ['Content-Type' => 'application/json']);
        } else {
            $response = new Response(json_encode(['message' => 'Product not found']), 404, ['Content-Type' => 'application/json']);
        }
        return $response;
    }
}

$request = Request::createFromGlobals();

$context = new RequestContext();
$context->fromRequest($request);
$matcher = new UrlMatcher($routes, $context);

$controllerResolver = new ControllerResolver();
$argumentResolver = new ArgumentResolver();

try {
    $parameters = $matcher->match($request->getPathInfo());
    $request->attributes->add($parameters);

    $controller = $controllerResolver->getController($request);
    $arguments = $argumentResolver->getArguments($request, $controller);

    $response = call_user_func_array($controller, $arguments);
} catch (Symfony\Component\Routing\Exception\ResourceNotFoundException $exception) {
    $response = new Response('Not Found', 404);
} catch (Exception $exception) {
    $response = new Response('An error occurred', 500);
}

$response->send();

Penjelasan Kode:

  • Kami menggunakan Symfony's Routing Component untuk membuat REST endpoint sederhana.
  • Setiap service memiliki endpoint /users/{id} atau /products/{id} untuk mengambil data berdasarkan ID.
  • Data pengguna dan produk disimulasikan dalam array.
  • Response dikembalikan dalam format JSON.

Cara Menjalankan:

  1. Pastikan PHP dan web server (misalnya, Apache atau Nginx) terinstall.
  2. Install dependencies dengan Composer: composer require symfony/routing symfony/http-foundation symfony/http-kernel di masing-masing direktori user-service dan product-service.
  3. Jalankan masing-masing service di port yang berbeda (misalnya, php -S localhost:8000 untuk UserService dan php -S localhost:8001 untuk ProductService).
  4. Akses http://localhost:8000/users/1 atau http://localhost:8001/products/2 untuk melihat data.

Common Pitfalls

  • Kompleksitas: Microservices menambah kompleksitas dalam deployment, monitoring, dan manajemen.
  • Network Latency: Komunikasi antar service melalui jaringan dapat menimbulkan latency.
  • Data Consistency: Memastikan konsistensi data di beberapa service bisa menjadi tantangan (gunakan pola seperti Saga atau Eventual Consistency).
  • Distributed Debugging: Debugging masalah yang melibatkan beberapa service bisa sulit.

Challenge

Coba tambahkan endpoint baru ke ProductService untuk membuat produk baru (POST /products). Gunakan file_put_contents untuk menyimpan data produk ke dalam file JSON (jangan gunakan database sungguhan untuk challenge ini).

Sumber Referensi

Bagikan: