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.
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:
# 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.
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,
];
}
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');
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',
],
];
}
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',
]);
}
}
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');
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
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.
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.