PHP

Cara Membuat RESTful API dengan CodeIgniter 4 Lengkap

CodeIgniter 4 itu framework PHP favorit saya — ringan, cepat, dan dokumentasinya jelas. Bikin RESTful API pakai CI4 itu gampang banget. Di tutorial ini saya share step-by-step dari nol sampai API-nya siap dipakai.

Apa itu RESTful API?

REST (Representational State Transfer) adalah arsitektur untuk membuat web service yang menggunakan HTTP request untuk mengakses dan memanipulasi data. RESTful API memungkinkan aplikasi berkomunikasi satu sama lain melalui endpoint HTTP dengan metode:

  • GET — Mengambil data (read)
  • POST — Membuat data baru (create)
  • PUT/PATCH — Mengupdate data (update)
  • DELETE — Menghapus data (delete)

Prasyarat

  • PHP 8.0 atau lebih baru
  • Composer terinstall
  • MySQL/MariaDB database
  • Text editor (VS Code recommended)

Step 1: Install CodeIgniter 4

# Install CI4 via Composer
composer create-project codeigniter4/appstarter ci4-api

# Masuk ke folder project
cd ci4-api

# Test server
php spark serve

Buka http://localhost:8080 di browser. Jika muncul welcome page, instalasi berhasil.

Step 2: Konfigurasi Database

Edit file app/Config/Database.php:

<?php
namespace Config;

class Database extends \CodeIgniter\Database\Config
{
    public $default = [
        'DSN'      => '',
        'hostname' => 'localhost',
        'username' => 'root',
        'password' => '',
        'database' => 'ci4_api',
        'DBDriver' => 'MySQLi',
        'DBPrefix' => '',
        'pConnect' => false,
        'DBDebug'  => true,
        'charset'  => 'utf8',
        'DBCollat' => 'utf8_general_ci',
        'swapPre'  => '',
        'encrypt'  => false,
        'compress' => false,
        'strictOn' => false,
        'failover' =>: [],
        'port'     => 3306,
    ];
}

Step 3: Buat Tabel Database

CREATE DATABASE ci4_api;
USE ci4_api;

CREATE TABLE products (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    description TEXT,
    price DECIMAL(10,2) NOT NULL,
    stock INT DEFAULT 0,
    category VARCHAR(100),
    image VARCHAR(255) DEFAULT NULL,
    is_active TINYINT(1) DEFAULT 1,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB;

-- Insert sample data
INSERT INTO products (name, description, price, stock, category) VALUES
('Laptop ASUS', 'Laptop untuk programmer, RAM 16GB', 12500000, 10, 'Elektronik'),
('Keyboard Mechanical', 'Keyboard RGB switch biru', 450000, 50, 'Aksesoris'),
('Mouse Logitech', 'Mouse wireless ergonomic', 250000, 30, 'Aksesoris');

Step 4: Buat Model

Buat file app/Models/ProductModel.php:

<?php
namespace App\Models;

use CodeIgniter\Model;

class ProductModel extends Model
{
    protected $table = 'products';
    protected $primaryKey = 'id';
    protected $useAutoIncrement = true;
    protected $returnType = 'array';
    protected $useSoftDeletes = false;
    protected $useTimestamps = true;
    protected $createdField = 'created_at';
    protected $updatedField = 'updated_at';

    protected $allowedFields = [
        'name', 'description', 'price', 
        'stock', 'category', 'image', 'is_active'
    ];

    // Validation rules
    protected $validationRules = [
        'name'  => 'required|min_length[3]|max_length[255]',
        'price' => 'required|numeric|greater_than[0]',
        'stock' => 'permit_empty|integer',
    ];

    protected $validationMessages = [
        'name' => [
            'required' => 'Nama produk wajib diisi',
            'min_length' => 'Nama produk minimal 3 karakter',
        ],
        'price' => [
            'required' => 'Harga wajib diisi',
            'numeric' => 'Harga harus berupa angka',
            'greater_than' => 'Harga harus lebih dari 0',
        ],
    ];
}

Step 5: Buat Controller

Buat file app/Controllers/Api/ProductController.php:

<?php
namespace App\Controllers\Api;

use CodeIgniter\RESTful\ResourceController;
use App\Models\ProductModel;

class ProductController extends ResourceController
{
    protected $model;
    protected $format = 'json';

    public function __construct()
    {
        $this->model = new ProductModel();
    }

    // GET /api/products
    public function index()
    {
        $page = $this->request->getGet('page') ?: 1;
        $limit = $this->request->getGet('limit') ?: 10;
        $search = $this->request->getGet('search');

        $builder = $this->model;

        if ($search) {
            $builder = $builder->like('name', $search)
                               ->orLike('description', $search);
        }

        $products = $builder->paginate($limit, 'default', $page);

        return $this->respond([
            'status' => 'success',
            'data' => $products,
            'pager' => $this->model->pager->getDetails(),
        ]);
    }

    // GET /api/products/{id}
    public function show($id = null)
    {
        $product = $this->model->find($id);

        if (!$product) {
            return $this->failNotFound('Produk tidak ditemukan');
        }

        return $this->respond([
            'status' => 'success',
            'data' => $product,
        ]);
    }

    // POST /api/products
    public function create()
    {
        $data = $this->request->getJSON(true);

        if (!$this->model->insert($data)) {
            return $this->failValidationErrors(
                $this->model->errors()
            );
        }

        return $this->respondCreated([
            'status' => 'success',
            'message' => 'Produk berhasil ditambahkan',
            'data' => $this->model->find(
                $this->model->getInsertID()
            ),
        ]);
    }

    // PUT /api/products/{id}
    public function update($id = null)
    {
        $product = $this->model->find($id);

        if (!$product) {
            return $this->failNotFound('Produk tidak ditemukan');
        }

        $data = $this->request->getJSON(true);

        if (!$this->model->update($id, $data)) {
            return $this->failValidationErrors(
                $this->model->errors()
            );
        }

        return $this->respond([
            'status' => 'success',
            'message' => 'Produk berhasil diupdate',
            'data' => $this->model->find($id),
        ]);
    }

    // DELETE /api/products/{id}
    public function delete($id = null)
    {
        $product = $this->model->find($id);

        if (!$product) {
            return $this->failNotFound('Produk tidak ditemukan');
        }

        $this->model->delete($id);

        return $this->respondDeleted([
            'status' => 'success',
            'message' => 'Produk berhasil dihapus',
        ]);
    }
}

Step 6: Buat Routes

Edit file app/Config/Routes.php:

<?php
use CodeIgniter\Router\RouteCollection;

/**
 * @var RouteCollection $routes
 */

// API Routes
$routes->group('api', function($routes) {
    $routes->resource('products', [
        'controller' => 'Api\ProductController',
        'except' => ['new', 'edit'],
        'placeholder' => '(:num)',
        'filter' => 'auth', // opsional: tambahkan filter auth
    ]);
});

// Custom routes (alternatif)
// $routes->get('api/products', 'Api\ProductController::index');
// $routes->get('api/products/(:num)', 'Api\ProductController::show/$1');
// $routes->post('api/products', 'Api\ProductController::create');
// $routes->put('api/products/(:num)', 'Api\ProductController::update/$1');
// $routes->delete('api/products/(:num)', 'Api\ProductController::delete/$1');

Step 7: Testing API

Jalankan server dan test dengan curl atau Postman:

# Jalankan server
php spark serve

# GET semua produk
curl http://localhost:8080/api/products

# GET produk dengan ID 1
curl http://localhost:8080/api/products/1

# GET dengan search
curl "http://localhost:8080/api/products?search=laptop&limit=5"

# POST produk baru
curl -X POST http://localhost:8080/api/products \
  -H "Content-Type: application/json" \
  -d '{"name":"Monitor Samsung","description":"Monitor 24 inch","price":2500000,"stock":15}'

# PUT update produk
curl -X PUT http://localhost:8080/api/products/4 \
  -H "Content-Type: application/json" \
  -d '{"price":2300000,"stock":20}'

# DELETE produk
curl -X DELETE http://localhost:8080/api/products/4

Step 8: Tambahkan CORS Filter

Agar API bisa diakses dari frontend yang berbeda domain, tambahkan CORS filter. Buat app/Filters/CorsFilter.php:

<?php
namespace App\Filters;

use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use CodeIgniter\Filters\FilterInterface;

class CorsFilter implements FilterInterface
{
    public function before(RequestInterface $request, $arguments = null)
    {
        $response = service('response');
        $response->setHeader('Access-Control-Allow-Origin', '*');
        $response->setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE, OPTIONS');
        $response->setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Requested-With');
        $response->setHeader('Access-Control-Max-Age', '86400');

        if ($request->getMethod() === 'options') {
            $response->setStatusCode(200);
            return $response;
        }
    }

    public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)
    {
        // Nothing needed here
    }
}

Register filter di app/Config/Filters.php dan tambahkan ke routes.

Kesimpulan

Membuat RESTful API dengan CodeIgniter 4 sangat mudah dan cepat. Dengan mengikuti langkah-langkah di atas, kamu sudah memiliki API lengkap dengan CRUD operations, validasi, pagination, dan search. CI4 menyediakan semua tools yang dibutuhkan: ResourceController, Model, Validation, dan Routing. Untuk production, jangan lupa tambahkan autentikasi (JWT atau API Key), rate limiting, dan HTTPS.


You may also like


0 Comments


Leave a Reply

Comments with links or spam keywords will be rejected.
Scroll to Top