Logo Universitas

Universitas ASA Indonesia

Program Studi: Teknologi Informasi

Mata Kuliah: Pengembangan Aplikasi Web Lanjut

SKS: 3 (2 teori, 1 praktikum)

Dosen Pengampu: Istiqomah Sumadikarta, S.T., M.Kom.

Beranda Mundur Maju

Pertemuan 3: RESTful API - Admin

Apa itu API ?


img

API atau Application Programming Interface merupakan sebuah interface yang dapat menghubungkan antara satu aplikasi dengan aplikasi yang lain dengan lebih mudah. Dengan API kita dapat melakukan pertukaraan data dari aplikasi yang berbeda, baik dalam satu platform maupun berbeda platform. [1]

Apa itu RESTful API ?

RESTful API / REST API merupakan implementasi dari API (Application Programming Interface). REST (Representional State Transfer) adalah suatu arsitektur metode komunikasi yang menggunakan protokol HTTP untuk pertukaran data dan metode ini sering diterapkan dalam pengembangan aplikasi.

Dimana tujuannya adalah untuk menjadikan sistem yang memiliki performa yang baik, cepat dan mudah untuk di kembangkan (scale) terutama dalam pertukaran dan komunikasi data. [2]

Di dalam RESTful API terdapaat beberapa bagian yang harus dipenuhi. Diantaranya adalah :

  1. URL

    RESTful API diakses menggunakan protokol HTTP. Penamaan dan struktur URL yang konsisten akan menghasilkan API yang baik dan mudah untuk dimengerti developer. URL API biasa disebut endpoint dalam pemanggilannya.

  2. HTTP Verbs

    Setiap request yang dilakukan terdapat metode yang dipakai agar server mengerti apa yang sedang di request client

    • GET : adalah metode HTTP Request yang paling simpel, metode ini digunakan untuk membaca atau mendapatkan data dari sumber.
    • POST : adalah metode HTTP Request yang digunakan untuk membuat data baru dengan menyisipkan data dalam body saat request dilakukan.
    • PUT : adalah metode HTTP Request yang biasanya digunakan untuk melakukan update data resource.
    • DELETE : adalah metode HTTP Request yang digunakan untuk menghapus suatu data pada resource.
  3. HTTP Response Code HTTP response code adalah kode standarisasi dalam menginformasikan hasil request kepada client. Secara umum terdapat 3 kelompok yang biasa kita jumpai pada RESTful API yaitu :

    • 2XX : adalah response code yang menampilkan bahwa request berhasil.
    • 4XX : adalah response code yang menampilkan bahwa request mengalami kesalahan pada sisi client.
    • 5XX : adalah response code yang menampilkan bahwa request mengalami kesalahan pada sisi server.
  4. Format Response Setiap request yang dilakukan client akan menerima data response dari server, response tersebut biasanya berupa data XML ataupun JSON. Setelah mendapatkan data response tersebut barulah client bisa menggunakannya dengan cara memparsing data tersebut dan diolah sesuai kebutuhan.

Dalam buku ini kita akan belajar bagaimana cara bertukar data dari satu aplikasi (Laravel) ke aplikasi yang lain (Nuxt.js) dengan menggunakan API. Dan untuk pertukaran data tersebut kita akan menggunakan data berupa JSON.


[1] : https://www.niagahoster.co.id/blog/api-adalah/#Apa_itu_API

[2] : https://jogjaweb.co.id/blog/pengertian-restfull-api

Installasi dan Konfigurasi JWT (JSON Web Token)


Kali ini kita semua akan belajar bagaimana cara installasi dan konfigurasi JWT (JSON Web Token) dl dalam project yang sedang kita kembangkan. Disini kita akan menggunakan JWT untuk proses authentication user.

Langkah 1 - Installasi JWT (JSOn Web Token)

Silahkan jalankan perintah di bawah ini di terminal/CMD :

composer require tymon/jwt-auth:2.2.1

Silahkan tunggu proses installasi sampai selesai. Dan pastikan harus terhubung dengan internet, karena package ini akan di unduh secara online.

Langkah 2 - Publish Konfigurasi File

Setelah proses installasi selesai, sekarang silahkan lakukan publish file konfigurasi. Jalankan perintah berikut ini di dalam terminal/CMD :

php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"

Jika perintah di atas berhasil, maka kita akan mendapatkan 1 file di dalam folder config/jwt.php.

Langkah 3 - Generate Secreet Key

Silahkan jalankan perintah di bawah ini di terminal/CMD untuk membuat secreet key di JWT :

php artisan jwt:secret

Jika perintah di atas berhasil, maka kita akan mendapatkan variable yang isinya adalah secreet key dari JWT di dalam file .env.

JWT_SECRET=

Langkah 4 - Update Auth Config File

Sekarang kita akan lakukan beberapa konfigurasi karena kita akan mengatur JWT ini untuk model Customer.

Silahkan buka file config/auth.php, kemudian pada config guards kurang lebih seperti berikut ini :

'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],
],

Sekarang, silahkan ubah menjadi seperti berikut ini :

'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],

    'api' => [
        'driver' => 'jwt',			// <-- set ke jwt
        'provider' => 'users',
        'hash' => false,
    ],
],

Di atas kita fokus pada perubahan guard api, dimana kita rubah untuk driver yang digunakan adalah jwt dan provider yang digunakan adalah users.

Langkah 5 - Update Model User

Sekarang, kita lanjutkan untuk melakukan beberapa konfigurasi di dalam model User agar bisa menggunakan JWT untuk generate token.

Silahkan buka file app/Models/User.php kemudian ubah kode-nya menjadi seperti berikut ini :

<?php

namespace App\Models;

// use Illuminate\Contracts\Auth\MustVerifyEmail;
use Tymon\JWTAuth\Contracts\JWTSubject; // <-- import JWTSubject
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable implements JWTSubject
{
    /** @use HasFactory<\Database\Factories\UserFactory> */
    use HasFactory, Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var list<string>
     */
    protected $fillable = [
        'name',
        'email',
        'password',
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var list<string>
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];

    /**
     * Get the attributes that should be cast.
     *
     * @return array<string, string>
     */
    protected function casts(): array
    {
        return [
            'email_verified_at' => 'datetime',
            'password' => 'hashed',
        ];
    }

    /**
     * sliders
     *
     * @return void
     */
    public function sliders()
    {
        return $this->hasMany(Slider::class);
    }

    /**
     * categories
     *
     * @return void
     */
    public function categories()
    {
        return $this->hasMany(Category::class);
    }

    /**
     * places
     *
     * @return void
     */
    public function places()
    {
        return $this->hasMany(Place::class);
    }

    /**
     * getJWTIdentifier
     *
     * @return void
     */
    public function getJWTIdentifier()
    {
        return $this->getKey();
    }
        
    /**
     * getJWTCustomClaims
     *
     * @return void
     */
    public function getJWTCustomClaims()
    {
        return [];
    }
}

Di atas, pertama kita import JWTSubject di dalam model Customer.

use Tymon\JWTAuth\Contracts\JWTSubject; // <-- import JWTSubject

Setelah itu kita tambahkan implements JWTSubject di dalam class Customer.

class User extends Authenticatable implements JWTSubject // <-- tambahkan ini
{
	....

Kemudian, kita juga menambahkan 2 method yaitu : function getJWTIdentifier dan function getJWTCustomClaims.

Membuat RESTful API Login


Sekarang kita akan belajar membuat otentikasi menggunakan Laravel Passport untuk melakukan generate token. Disini kita akan mengimplementasikan Single Action Controller. Konsep ini digunakan jika kita ingin menjadikan sebuah class controller hanya menangani satu action saja. Biasanya karena kode di dalam controller tersebut hanya membutuhkan 1 aksi saja.

Langkah 1 - Membuat Controller Login

Silahkan jalankan perintah berikut ini di dalam terminal / CMD dan pastikan berada di dalam folder project Laravel.

php artisan make:controller Api/Admin/LoginController -i

Jika perintah di atas berhasil dijalankan, maka kita akan mendapatkan 1 file baru dengan nama LoginController.php di dalam folder app/Http/Controllers/Api/Admin. Dan kita tambahkan flag -i, artinya controller tersebut akan di set menjadi invoke atau single action.

Sekarang, silahkan buka file tersebut dan ubah semua kode-nya menjadi seperti berikut ini :

<?php

namespace App\Http\Controllers\Api\Admin;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Validator;

class LoginController extends Controller
{
    /**
     * Handle the incoming request.
     */
    public function __invoke(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'email'    => 'required|email',
            'password' => 'required',
        ]);

        if ($validator->fails()) {
            return response()->json($validator->errors(), 400);
        }

        $credentials = $request->only('email', 'password');

        if(!$token = auth()->guard('api')->attempt($credentials)) {
            return response()->json([
                'success' => false,
                'message' => 'Email or Password is incorrect'
            ], 401);
        }
        return response()->json([
            'success' => true,
            'message' => 'Login Successfully!',
            'user'    => auth()->guard('api')->user(),  
            'token'   => $token   
        ], 201);
    }
}

Dari perubahan kode di atas, pertama kita melakukan import Facades Validator dari Laravel, karena kita akan membuat sebuah validasi terhadap data yang dikirimkan oleh pengguna.

use Illuminate\Support\Facades\Validator;

Kemudian, di dalam method __invoke, pertama kita melakukan definisi validasi, kurang lebih seperti berikut ini :

//set validation
$validator = Validator::make($request->all(), [
    'email'     => 'required|email',
    'password'  => 'required'
]);

Dari validasi di atas, kurang lebih penjelasannya seperti berikut ini :

KEY VALIDATION DESCRIPTION
email required field wajib diisi
email field harus menggunakan format email
password required field wajib diisi

Jika data yang dikirimkan belum sesuai dengan validasi di atas, maka akan mengembalikan sebuah response dalam format JSON dengan informasi validasi error.

//if validation fail
if ($validator->fails()) {
   return response()->json($validator->errors(), 422);
}

kemudian kita membuat kondisi untuk proses login gagal. Dan kita akan membuat response dengan status code 401.

$credentials = $request->only('email', 'password');

if(!$token = auth()->guard('api')->attempt($credentials)) {
  return response()->json([
    'success' => false,
    'message' => 'Email or Password is incorrect'
  ], 401);
}

Jika proses login berhasil, kita akan membuat response success menjadi true dan menampilkan data customer beserta token yang di generate. Disini kita menggunakan status code 201.

return response()->json([
   'success' => true,
   'message' => 'Login Successfully!',
   'user'    => auth()->guard('api')->user(),  
   'token'   => $token   
], 201);

Langkah 2 - Membuat Route API Login

Setelah berhasil membuat controller untuk proses login, sekarang kita lanjutkan untuk membuat sebuah route, tujuannya agar controller yang sudah kita buat di atas dapat digunakan.

Silahkan teman-teman jalankan perintah berikut ini di dalam terminal/CMD dan pastikan sudah berada di dalam project-nya.

php artisan install:api

Silahkan tunggu proses installasinya sampai selesai, jika keluar pesan seperti ini, silahkan ketik yes dan ENTER.

One new database migration has been published. Would you like to run all pending database migrations? (yes/no)

Setelah itu buka file routes/api.php, kemudian ubah semua kode-nya menjadi seperti berikut ini :

<?php

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;

//group route with prefix "admin"
Route::prefix('admin')->group(function () {

    //route login
    Route::post('/login', App\Http\Controllers\Api\Admin\LoginController::class, ['as' => 'admin']);

    //group route with middleware "auth:api"
    Route::group(['middleware' => 'auth:api'], function() {

        //route user logged in
        Route::get('/user', function (Request $request) {
            return $request->user();
        })->name('user');

    });

});

Dari perubahan kode route di atas, pertama kita menambahkan sebuah route prefix yang bernama admin. Route prefix digunakan untuk mengelompokan sebuah route ke dalam suatu prefix, tujuannya agar mempermudah untuk membedakan jenis-jenis route yang akan dibuat.

Route Prefix diatas juga digunakan untuk menambahkan kata admin di awalan URL. Jadi jika kita atur sebuah route dengan /dashboard, maka kita akan otomatis mendapatkan hasilnya menjadi /admin/dashboard. Karena awalan URL akan di tambahkan kata admin.

//group route with prefix "admin"
Route::prefix('admin')->group(function () {

	//...

});

Setelah itu, di dalam prefix admin, pertam kita membuat sebuah route baru menggunakan method POST, dimana route ini akan digunakan untuk menangani proses login.

//route login
Route::post('/login', App\Http\Controllers\Api\Admin\LoginController::class, ['as' => 'admin']);

Dari route di atas, kita tambahkan as => 'admin', agar route tersebut ditambahkan sebuah name dengan awalan admin.

kemudian, kita membuat sebuah route group dengan middleware auth:api, artinya route yang di definisikan di dalam group ini harus melakukan proses login terlebih dahulu.

//group route with middleware "auth:api"
Route::group(['middleware' => 'auth:api'], function() {
    
    //...
    
});

Di dalam route group auth:api di atas, kita menambahkan 1 route baru yang digunakan untuk menampilkan data user yang sedang login.

//route user logged in
Route::get('/user', function (Request $request) {
  return $request->user();
})->name('user');

Langkah 3 - Uji Coba API Login

Setelah berhasil membuat controller dan menambahkan method di dalamnya, sekarang kita akan lanjutkan untuk proses uji coba atau tetsing dari Rest API yang sudah kita buat.

Uji Coba Proses Login

Sekarang kita akan lakukan uji coba proses login. Silahkan buka aplikasi Postman, kemudian masukkan URL berikut ini : http://localhost:8000/api/admin/login dan untuk method-nya silahkan pilih POST.

Jika sudah,silahkan klik Send, maka kita akan mendapatkan response berupa error validasi, karena kita belum mengirimkan data apapun ke dalam server.

Sekarang, silahkan klik tab Body dan pilih form-data, kemudian masukkan key dan value berikut ini :

KEY VALUE
email isi dengan email yang dibuat di database seeder / tinker.
password isi dengan password yang dibuat di database seeder / tinker.

Jika sudah, silahkan klik Send dan jika berhasil melakukan proses login, maka kita akan mendapatkan informasi data user, beserta token yang di generate oleh Laravel Passport.

INFORMASI : selanjutnya untuk mengakses route yang membutuhkan otentikasi, maka kita harus menyertakan token yang di dapatkan dari proses login seperti di atas.

Uji Coba Get User

Setelah berhasil melakukan proses login, sekarang kita lanjutkan untuk belajar melakukan get data user yang sedang login. Dimana kita membutuhkan token yang di dapatkan dari proses login seperti diatas.

Silahkan buka aplikasi Postman, kemudian masukkan URL berikut ini : http://localhost:8000/api/admin/user dan untuk method-nya silahkan pilih GET.

Setelah itu, silahkan klik tab Headers kemudian masukkan key dan value berikut ini di dalamnya.

KEY VALUE
Accept application/json
Content-Type application/json
Authorization Bearer <spasi> Token

CATATAN ! : untuk value dari Authorization adalah Bearer kemudian spasi Token, token tersebut silahkan diambil dari hasil response token di proses login.

Jika sudah, silahakn klik Send dan jika berhasil maka kita akan mendapatkan sebuah response yang berisi informasi tentang data user yang sedang login.

Membuat RESTful API Logout


Setelah berhasil membuat proses login dan menampilkan data user, sekarang kita akan lanjutkan belajar bagaiman cara membuat proses logout. Sama seperti sebelumnya, kita akan menggunakan Single Action Controller.

Langkah 1 - Membuat Controller Logout

Pertama, silahkan tambahkan kode berikut ini di dalam file .env.

JWT_SHOW_BLACKLIST_EXCEPTION=true

Selanjutnya, silahkan jalankan perintah di bawah ini di dalam terminal/CMD dan pastikan berada di dalam project Larvel-nya.

php artisan make:controller Api/Admin/LogoutController -i

Jika perintah di atas berhasil dijalankan, maka kita akan mendapatkan 1 file baru dengan nama LogoutController.php di dalam folder app/Http/Controllers/Api/Admin. Setelah itu, kita akan lakukan beberapa modifikasi di dalam file tersebut.

Silahkan buka file app/Http/Controllers/Api/Admin/LogoutController.php dan ubah semua kode-nya menjadi seperti berikut ini :

<?php

namespace App\Http\Controllers\Api\Admin;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Tymon\JWTAuth\Facades\JWTAuth;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
use Tymon\JWTAuth\Exceptions\TokenInvalidException;

class LogoutController extends Controller
{
    /**
     * Handle the incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function __invoke(Request $request)
    {        
        //remove token
        $removeToken = JWTAuth::invalidate(JWTAuth::getToken());

        if($removeToken) {
            //return response JSON
            return response()->json([
                'success' => true,
                'message' => 'Logout Successfully!',  
            ]);
        }
    }
}

Di atas, kita membuat kondisi di dalam method __invoke, dimana kita membuat sebuah variable dengan nama removeToken yang isinya adalah kita melakukan logout dari token yang active. Jika proses tersebut berhasil, maka akan mengembalikan sebuah response success true.

Langkah 2 - Membuat Route API Logout

Setelah berhasil membuat controller logout, sekarang kita lanjutkan untuk menambahkan route logout. Silahkan buka file routes/api.php, kemudian tambahkan route berikut ini di dalam prefix admin dan di dalam middleware auth:api, tepatnya di bawah route /user.

//route logout
Route::post('/logout', App\Http\Controllers\Api\Admin\LogoutController::class, ['as' => 'admin']);

Jika ditulis dengan lengkap kurang lebih seperti berikut ini :

<?php

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;

//group route with prefix "admin"
Route::prefix('admin')->group(function () {

    //route login
    Route::post('/login', App\Http\Controllers\Api\Admin\LoginController::class, ['as' => 'admin']);

    //group route with middleware "auth:api"
    Route::group(['middleware' => 'auth:api'], function() {

        //route user logged in
        Route::get('/user', function (Request $request) {
            return $request->user();
        })->name('user');

        //route logout
        Route::post('/logout', App\Http\Controllers\Api\Admin\LogoutController::class, ['as' => 'admin']);

    });

});

Langkah 3 - Uji Coba API Logout

Setelah berhasil membuat controller dan menambahkan method di dalamnya, sekarang kita akan lanjutkan untuk proses uji coba atau tetsing dari Rest API yang sudah kita buat.

Uji Coba Proses Logout

Sekarang kita akan lakukan uji coba proses logout. Silahkan buka aplikasi Postman, kemudian masukkan URL berikut ini : http://localhost:8000/api/admin/logout dan untuk method-nya silahkan pilih POST.

Setelah itu, silahkan klik tab Headers kemudian masukkan key dan value berikut ini di dalamnya.

KEY VALUE
Accept application/json
Content-Type application/json
Authorization Bearer <spasi> Token

Jika sudah,silahkan klik Send, maka kita akan mendapatkan response JSON dengan informasi success logout.

Membuat RESTful API Dashboard


Setelah berhasil membuat proses otentikasi menggunakan Laravel Passport, maka sekarang kita akan lanjutkan belajar membuat RESTful API untuk dashboard. Dimana di dalam endpoint ini kita akan belajar menampilkan statistik data dari masing-masing table.

Langkah 1 - Membuat Controller Dashboard

Karena hanya membutuhkan 1 action saja, maka kita tetap akan menggunakan Single Action Controller. Silahkan jalankan perintah berikut ini di dalam terminal/CMD dan pastikan berada di dalam project Laravel.

php artisan make:controller Api/Admin/DashboardController -i

Jika perintah di atas berhasil dijalankan, maka kita akan mendapatkan 1 file baru dengan nama DashboardController.php di dalam folder app/Http/Controller/Api/Admin. Silahkan buka file tersebut, kemudian ubah semua kode-nya menjadi seperti berikut ini :

<?php

namespace App\Http\Controllers\Api\Admin;

use App\Models\User;
use App\Models\Place;
use App\Models\Slider;
use App\Models\Category;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class DashboardController extends Controller
{
    /**
     * Handle the incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function __invoke(Request $request)
    {
        //count categories
        $categories = Category::count();

        //count places
        $places = Place::count();

        //count sliders
        $sliders = Slider::count();

        //count users
        $users = User::count();

        return response()->json([
            'success'   => true,
            'message'   => 'Statistik Data',
            'data'      => [
                'categories' => $categories,
                'places'     => $places,
                'sliders'   => $sliders,
                'users'  => $users
            ]
        ]);
    }
}

Dari perubahan di atas, kita melakukan import 4 Model, dimana model-model tersebut akan kita gunakan untuk mendapatkan jumlah data/record yang ada di dalam table.

use App\Models\User;
use App\Models\Place;
use App\Models\Slider;
use App\Models\Category;

Dan di dalam method __invoke, kita melakukan count ke dalam masing-masing model.

//count categories
$categories = Category::count();

//count places
$places = Place::count();

//count sliders
$sliders = Slider::count();

//count users
$users = User::count();

Setelah itu, kita return data di atas ke dalam format JSON, kurang lebih seperti berikut ini :

return response()->json([
   'success'   => true,
   'message'   => 'Statistik Data',
   'data'      => [
      'categories' => $categories,
      'places'     => $places,
      'sliders'   => $sliders,
      'users'  => $users
   ]
]);

Langkah 2 - Membuat Route API Dashboard

Setelah berhasil membuat controller, sekarang kita lanjutkan untuk membuat route-nya. Silahkan buka file routes/api.php, kemudian tambahkan route berikut ini di dalam prefix admin dan di dalam middleware auth:api, tepatnya di bawah route /logout.

//dashboard
Route::get('/dashboard', App\Http\Controllers\Api\Admin\DashboardController::class, ['as' => 'admin']);

Jika file routes/api.php ditulis secara lengkap, maka kurang lebih seperti berikut ini :

<?php

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;

//group route with prefix "admin"
Route::prefix('admin')->group(function () {

    //route login
    Route::post('/login', App\Http\Controllers\Api\Admin\LoginController::class, ['as' => 'admin']);

    //group route with middleware "auth:api"
    Route::group(['middleware' => 'auth:api'], function() {

        //route user logged in
        Route::get('/user', function (Request $request) {
            return $request->user();
        })->name('user');

        //route logout
        Route::post('/logout', App\Http\Controllers\Api\Admin\LogoutController::class, ['as' => 'admin']);

        //dashboard
        Route::get('/dashboard', App\Http\Controllers\Api\Admin\DashboardController::class, ['as' => 'admin']);

    });

});

Langkah 3 - Uji Coba API Dashboard

Setelah berhasil membuat controller dan menambahkan method di dalamnya, sekarang kita akan lanjutkan untuk proses uji coba atau tetsing dari Rest API yang sudah kita buat.

Silahkan buka aplikasi Postman, kemudian masukkan URL berikut ini : http://localhost:8000/api/admin/dashboard dan untuk method-nya silahkan pilih GET.

Setelah itu, silahkan klik tab Headers kemudian masukkan key dan value berikut ini di dalamnya.

KEY VALUE
Accept application/json
Content-Type application/json
Authorization Bearer <spasi> Token

Jika sudah,silahkan klik Send, maka kita akan mendapatkan response JSON dengan informasi statistik data. Kurang lebih seperti berikut ini :

Membuat RESTful API CRUD Categories


Pada materi kali ini kita akan belajar membuat RESTful API untuk CRUD data categories, dimana kita akan menggunakan fitur di dalam Laravel untuk membuat layer untuk mentransformasi data di dalam Model menjadi format JSON dengan lebih mudah dan cepat dan fitur tersebut bernama API Resource.

Kita juga akan belajar untuk melakukan kustomisasi di dalam API Resource, dengan tujuan agar response dari Rest API yang akan kita buat bisa sesuai dengan yang diinginkan.

Langakah 1 - Membuat Resource Category

Sebelum kita membuat controller, maka kita membuat resource-nya terlebih dahulu, dimana resource ini akan kita paanggil di dalam controller yang membutuhkan sebuah transformasi data ke dalam format JSON.

Silahkan jalankan perintah berikut ini di dalam terminal/CMD dan pastikan berada di dalam project Laravel-nya.

php artisan make:resource CategoryResource

Jika perintah di atas berhasil dijalankan, maka kita akan mendapatkan 1 file baru dengan nama CategoryResource.php di dalam folder app/Http/Resources.

Setelah itu, kita akan melakukan kustomisasi dari file tersebut agar sesuai dengan yang kita harapkan. Silahkan buka file tersebut dan ubah kode-nya menjadi seperti berikut ini :

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class CategoryResource extends JsonResource
{
    //public properti
    public $status;
    public $message;
    
    /**
     * __construct
     *
     * @param  mixed $status
     * @param  mixed $message
     * @param  mixed $resource
     * @return void
     */
    public function __construct($status, $message, $resource)
    {
        parent::__construct($resource);
        $this->status  = $status;
        $this->message = $message;
    }

    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return [
            'success'   => $this->status,
            'message'   => $this->message,
            'data'      => $this->resource
        ];
    }
}

Dari perubahan kode di atas, pertama kita membuat 2 public properti, properti tersebut nantinya akan diisi nilai yang dikirimkan oleh controller sebagai parameter.

//public properti
public $status;
public $message;

Setelah itu, kita menambahkan method __contruct. Method ini akan pertama kali dijalankan ketika class CategoryResource di panggil, dimana di dalam method ini kita definisikan 3 parameter, yaitu :

  1. $status : merupakan properti $status yang kita buat di atas, yang mana isinya nanti akan berupa nilai boolean, yaitu true atau false yang dikirimkan secara dinamis oleh controller.
  2. $message : merupakan properti $message yang kita buat di atas, yang mana isinya nanti akan berupa pesan/message tentang response dari Rest API yang dikirimkan oleh controller.
  3. $resource : merupakan data yang akan di transformasi menjadi Rest API, ini nanti akan berupa data Model yang dikirim dari controller.

Kemudian kita return ketiga variable di atas di dalam method toArray.

return [
   'success'   => $this->status,
   'message'   => $this->message,
   'data'      => $this->resource
];

Langkah 2 - Membuat Controller Category

Setelah berhasil membuat Resource, maka kita akan lanjutkan membuat controller untuk category. Silahkan jalankan perintah berikut ini di dalam terminal/CMD dan pastikan berada di dalam project Laravel.

php artisan make:controller Api/Admin/CategoryController

Jika perintah di atas berhasil dijalankan, maka kita akan mendapatkan 1 file baru dengan nama CategoryController.php yang berada di dalam folder app/Http/Controllers/Api/Admin.

Silahkan buka file tersebut, kemudian ubah semua kode yang ada dan ganti menjadi seperti berikut ini :

<?php

namespace App\Http\Controllers\Api\Admin;

use App\Models\Category;
use Illuminate\Support\Str;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Storage;
use App\Http\Resources\CategoryResource;
use Illuminate\Support\Facades\Validator;

class CategoryController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        //get categories
        $categories = Category::when(request()->q, function($categories) {
            $categories = $categories->where('name', 'like', '%'. request()->q . '%');
        })->latest()->paginate(5);
        
        //return with Api Resource
        return new CategoryResource(true, 'List Data Categories', $categories);
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'image'    => 'required|image|mimes:jpeg,jpg,png|max:2000',
            'name'     => 'required|unique:categories',
        ]);

        if ($validator->fails()) {
            return response()->json($validator->errors(), 422);
        }

        //upload image
        $image = $request->file('image');
        $image->storeAs('categories', $image->hashName(), 'public');

        //create category
        $category = Category::create([
            'image'=> $image->hashName(),
            'name' => $request->name,
            'slug' => Str::slug($request->name, '-'),
        ]);

        if($category) {
            //return success with Api Resource
            return new CategoryResource(true, 'Data Category Berhasil Disimpan!', $category);
        }

        //return failed with Api Resource
        return new CategoryResource(false, 'Data Category Gagal Disimpan!', null);
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        $category = Category::whereId($id)->first();
        
        if($category) {
            //return success with Api Resource
            return new CategoryResource(true, 'Detail Data Category!', $category);
        }

        //return failed with Api Resource
        return new CategoryResource(false, 'Detail Data Category Tidak Ditemukan!', null);
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, Category $category)
    {
        $validator = Validator::make($request->all(), [
            'name'     => 'required|unique:categories,name,'.$category->id,
        ]);

        if ($validator->fails()) {
            return response()->json($validator->errors(), 422);
        }

        //check image update
        if ($request->file('image')) {

            //remove old image
            Storage::disk('public')->delete('categories/'.basename($category->image));
        
            //upload new image
            $image = $request->file('image');
            $image->storeAs('categories', $image->hashName(), 'public');

            //update category with new image
            $category->update([
                'image'=> $image->hashName(),
                'name' => $request->name,
                'slug' => Str::slug($request->name, '-'),
            ]);

        }

        //update category without image
        $category->update([
            'name' => $request->name,
            'slug' => Str::slug($request->name, '-'),
        ]);

        if($category) {
            //return success with Api Resource
            return new CategoryResource(true, 'Data Category Berhasil Diupdate!', $category);
        }

        //return failed with Api Resource
        return new CategoryResource(false, 'Data Category Gagal Diupdate!', null);
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy(Category $category)
    {
        //remove image
        Storage::disk('public')->delete('categories/'.basename($category->image));

        if($category->delete()) {
            //return success with Api Resource
            return new CategoryResource(true, 'Data Category Berhasil Dihapus!', null);
        }

        //return failed with Api Resource
        return new CategoryResource(false, 'Data Category Gagal Dihapus!', null);
    }
}

Dari perubahan kode di atas, pertama kita melakukan import Mode Category terlebih dahulu.

use App\Models\Category;

Setelah itu, kita juga melakukan import helper dari Laravel untuk manipulasi string, yaitu Str, karena kita akan menggunakannya untuk membuat URL yang SEO friendly atau biasa disebut dengan SLUG.

use Illuminate\Support\Str;

Kemudian kita juga melakukan import HTTP Request dari Laravel, yang digunakan untuk menerima sebuah request yang dikirimkan oleh form, cookies, url dan lain-lain.

use Illuminate\Http\Request;

Dan kita juga import Facade Storage dari Laravel, dimana akan kita gunakan untuk melakukan proses upload file ke dalam project Laravel.

use Illuminate\Support\Facades\Storage;

Kita juga melakukan import CategoryResource yang sudah kita buat sebelumnya, dimana akan kita gunakan untuk mengubah data menjadi format JSON dengan sangat mudah dan cepat.

use App\Http\Resources\CategoryResource;

Karena akan melakukan insert dan update data, maka kita perlu membuat validasi di dalamnya. Dan tentu saja kita akan menggunakan Facades Validator dari Laravel, dimana akan mempermudah kita dalam membuat sebuah validasi.

use Illuminate\Support\Facades\Validator;

Jika kita perhatikan, di dalam class CategoryController kita menambahkan beberapa method, yaitu :

  1. function index - menampilkan list data categories.
  2. function store - melakukan proses insert data category.
  3. function show - menampilkan detail data category.
  4. function update - melakukan proses update data category.
  5. function destroy - mengahapus data category.

function index

Method ini akan kita gunakan untuk menampilkan list data cateogories dari database. Disini kita menggunakan Eloquent untuk mendapatkan data dari database melalui Model Category.

Di dalam Eloquent pertama kita tambahkan method when, method tersebut digunakan untuk membuat sebuah kondisi, sama seperti kita menggunakan if statment.

Jadi di dalam method when kita memeriksa apakah ada sebuah request yang bernama q, jika ada maka kita akan melakukan ekseskusi kode di dalam closoure function, yang isinya adalah sebuah pencarian data berdasarkan name category yang sesuai dengan isi dari request q tersebut.

//get categories
$categories = Category::when(request()->q, function($categories) {
    $categories = $categories->where('name', 'like', '%'. request()->q . '%');
})->latest()->paginate(5);

Kode di dalam closoure function di atas hanya akan di eksekusi jika ada sebuah request dengan nama q, kalau tidak ada, maka isi di dalam closoure function tersebut akan dilewati.

Setelah itu, kita urutkan data yang ditampilkan berdasarkan yang paling terbaru menggunakan method latest() dan kita batas data yang ditampilkan perhalaman menggunakan method paginate().

Jika data sudah berhasil di dapatkan, langkah selanjutnya adalah melakukan return ke dalam Resource, tujuanya agar data tersebut di transformasi menjadi format JSON.

//return with Api Resource
return new CategoryResource(true, 'List Data Categories', $categories);

Di atas, di dalam Resource kita menambahkan 3 parameter, yaitu :

  1. status - merupakan status dari response Rest API, yaitu bernilai tipe data boolean true.
  2. message - merupakan pesan dari Rest API, yaitu List Data Categories.
  3. resource - merupakan data yang di dapatkan dari Model dan akan di transformasi menjadi format JSON.

function store

Method ini akan kita gunakan untuk melakukan proses insert data category ke dalam database. Tapi sebelum itu kita akan membuat sebuah validasi terlebih dahulu untuk memastikan data yang akan di insert sudah sesuai dengan yang diharapkan.

$validator = Validator::make($request->all(), [
   'image'    => 'required|image|mimes:jpeg,jpg,png|max:2000',
   'name'     => 'required|unique:categories',
]);

Dari penambahan validasi di atas, kurang lebih seperti berikut ini penjelasannya.

KEY VALIDATION DESCRIPTION
image required field wajib diisi.
images field harus gambar.
mimes:jpeg,jpg,png field harus memiliki extensi .jpg, .jpeg dan .png.
max:2000 field maksimal memiliki ukuran 2 Mb.
name required field wajib diisi.
unique:categories field bersifat unik dan tidak boleh ada yang sama di dalam table categories.

Jika data yang dikirimkan belum sesuai dengan validasi di atas, maka kita akan melakukan return dengan format JSON yang berisi informasi error validasi.

if ($validator->fails()) {
  return response()->json($validator->errors(), 422);
}

Tapi, jika data yang dikirimkan sudah sesuai dengan validasi di atas, maka langkah pertama kita akan melakukan upload gambar terlebih dahulu ke dalam server.

//upload image
$image = $request->file('image');
$image->storeAs('categories', $image->hashName(), 'public');

Di atas, kita membuat variable dengan nama $image yang isinya adalah sebuah request dengan tipe file yang bernama image.

Setelah itu, kita pindahkan file tersebut menggunakan method storeAs ke dalam folder storage/app/public/categories dan untuk nama file-nya akan di ubah menjadi random menggunakan method hashName().

Jika gambar sudah berhasil di upload di dalam server, langkah selanjutnya adalah melakukan proses insert data category ke dalam database menggunakan Eloquent.

//create category
$category = Category::create([
   'image'=> $image->hashName(),
   'name' => $request->name,
   'slug' => Str::slug($request->name, '-'),
]);

Dari proses insert data di atas, kurang lebih penjelassannya seperti berikut ini :

ATTRIBUTE VALUE DESCRIPTION
image $image->hashName() mengambil nama gambar yang di upload.
name $request->name mengambil dari request yang bernama name.
slug Str::slug($request->name, '-') mengambil dari request yang bernama name, kemudian di letakkan di dalam Str::slug dengan tujuan menambahkan karakter - sebagai pengganti spasi antar kata.

Jika proses insert data di atas berhasil dilakukan, maka kita akan melakukan return menggunakan Resource dengan status success true, kurang lebih seperti berikut ini :

//return success with Api Resource
return new CategoryResource(true, 'Data Category Berhasil Disimpan!', $category);

Tapi, jika proses insert data gagal dilakukan, maka kia juga akan return menggunakan Resource dengan status success false.

//return failed with Api Resource
return new CategoryResource(false, 'Data Category Gagal Disimpan!', null);

function show

Method ini akan digunakan untuk mendapatkan detail data berdasarkan ID yang di dapatkan dari parameter URL.

$category = Category::whereId($id)->first();

Di atas, kita mencari data category berdasarkan ID, kemudian kita berikan method first() agar kita bisa mengakses object datanya.

Jika data ditemukan, maka kita akan return ke dalam Resource dengan status success true.

//return success with Api Resource
return new CategoryResource(true, 'Detail Data Category!', $category);

Tapi, jika data tidak ditemukan di dalam database, maka kita akan return menggunakan Resource dengan status success false.

//return failed with Api Resource
return new CategoryResource(false, 'Detail Data Category Tidak Ditemukan!', null);

function update

Method ini akan digunakan untuk melakukan proses update data ke dalam database. Sebelum itu, kita akan membuat validasi untuk memastikan data yang di kirim untuk di update sudah benar-benar sesuai dengan yang diharapkan.

$validator = Validator::make($request->all(), [
    'name'     => 'required|unique:categories,name,'.$category->id,
]);

Dari penambahan validasi di atas, kurang lebih penjelasannya seperti berikut ini :

KEY VALIDATION DESCRIPTION
name required field wajib diisi.
unique:categories,name,'.$category->id field bersifat unik dan tidak boleh ada yang sama di dalam table categories. Karena bersifat unik, maka untuk proses update kita tambahkan name,'.$category->id, yang artinya kusus ID category yang diupdate akan dikecualikan.

Jika daata yang akan diupdate belum sesuai dengan validasi di atas, maka kita akan melakukan return / mengembalikan sebuah format JSON dengan informasi error validasi.

if ($validator->fails()) {
  return response()->json($validator->errors(), 422);
}

Jika data yang dikirimkan sudah sesuai, selanjutnya kita akan membuat kondisi untuk memastikan apakah ada sebuah request dengan jenis file yang bernama image.

<//check image update
if ($request->file('image')) {

	//...
	
}

Jika ada, artinya kita akan melakukan update data beserta memperbarui file gambar. Pertama, kita akan lakukan hapus data gambar yang lama terlebih dahulu di dalam server.

//remove old image
Storage::disk('public')->delete('categories/'.basename($category->image));

Setelah gambar yang lama berhasil dihapus, sekarang kita lakukan upload gambar terbaru.

//upload new image
$image = $request->file('image');
$image->storeAs('categories', $image->hashName(), 'public');

Jika gambar sudah berhasil di upload di dalam server, selanjutnya kita lakukan proses update data category beserta gambar terbaru.

//update category with new image
$category->update([
    'image'=> $image->hashName(),
    'name' => $request->name,
    'slug' => Str::slug($request->name, '-'),
]);

Kemudian, jika tidak ada request file dengan nama image, maka kita cukup mengupdate semua attribute kecuali image.

//update category without image
$category->update([
    'name' => $request->name,
    'slug' => Str::slug($request->name, '-'),
]);

Dan kita buat sebuah kondisi, apakah proses update tersebut berhasil dilakukan. Jika IYA, maka akan melakukan return ke menggunakan Resource dengan status success true.

//return success with Api Resource
return new CategoryResource(true, 'Data Category Berhasil Diupdate!', $category);

Tapi, jika data gagal diupdate, maka kita akan melakukan return menggunakan Resource dengan status success false.

//return failed with Api Resource
return new CategoryResource(false, 'Data Category Gagal Diupdate!', null);

function destroy

Method ini akan digunakan untuk menghapus data dari database. Sebelum itu, kita akan menghapus gambar yang terkait dengan data category yang akan dihapus tersebut.

//remove image
Storage::disk('public')->delete('categories/'.basename($category->image));

Setelah gambar berhasil terhapus, selanjutnya kita akan menghapus data category-nya dari database.

$category->delete()

Jika dari kode di atas berhasil dilakukan, maka kita akan retuen menggunakan Resource dengan status success true.

//return success with Api Resource
return new CategoryResource(true, 'Data Category Berhasil Dihapus!', null);

Tapi, jika data gagal dihapus, maka akan melakukan return menggunakan Resource dengan status success false.

//return failed with Api Resource
return new CategoryResource(false, 'Data Category Gagal Dihapus!', null);

Langkah 3 - Membuat Route API Categories

Setelah berhasil membuat controller beserta method-method di dalamnya, maka sekarang kita akan lanjutkan membuat route agar controller kita dapat diakses melalui web browser.

Silahkan buka file routes/api.php, kemudian tambahkan route berikut ini di dalam prefix admin dan group middleware auth:api, tepatnya di bawah route /dashboard.

//categories resource
Route::apiResource('/categories', App\Http\Controllers\Api\Admin\CategoryController::class, ['except' => ['create', 'edit'], 'as' => 'admin']);

DI atas, kita menggunakan route dengan jenis apiResource. Dengan menggunakan tipe tersebut, maka kita akan dibuatkan route secara otomatis mulai dari index, create, store, edit, update dan destroy.

Tapi di dalam route di atas, kita juga menambahkan except, artinya akan mengecualikan sebuah route, yaitu create dan edit. Karena kita tidak membutuhkan route tersebut.

Jadi, untuk memastikan apakah route di atas berhasil ditambahkan, maka kita bisa menjalankan perintah berikut ini di dalam terminal / CMD :

php artisan route:list

Langkah 4 - Uji Coba API Categories

Setelah berhasil membuat controller dan menambahkan method di dalamnya, sekarang kita akan lanjutkan untuk proses uji coba atau tetsing dari Rest API yang sudah kita buat.

Uji Coba Method Index

Pertama kita akan lakukan uji coba untuk menampilkan list data category, silahkan buka aplikasi Postman dan masukkan URL berikut ini http://localhost:8000/api/admin/categories dan untuk method-nya silahkan pilih GET.

Selanjutnya silahkan klik tab Headers kemudian masukkan key dan value berikut ini :

KEY VALUE
Accept application/json
Content-Type application/json
Authorization Bearer <spasi> Token

Jika sudah silahkan klik Send dan jika berhasil maka kita akan mendapatkan response dalam format JSON yang berisi informasi list data categories.

Ujia Coba Method Store

Silahkan unduh file-file assets gambar category untuk bahan latihan.

DOWNLOAD : https://drive.google.com/file/d/1kpDrjUZYZERVi43IF2MYnMQQYk5melh3/view?usp=sharing

Selanjutnya kita akan lakukan uji coba untuk melakukan proses insert data category ke dalam database. Silahkan buka aplikasi Postman, kemudiaan masukkan URL berikut ini http://localhost:8000/api/admin/categories dan untuk method-nya silahkan pilih POST.

Selanjutnya silahkan klik tab Headers kemudian masukkan key dan value berikut ini :

KEY VALUE
Accept application/json
Content-Type application/json
Authorization Bearer <spasi> Token

Jika sudah, sekarang klik tab Body kemudian pilih form-data dan masukkan key dan value berikut ini :

KEY TYPE VALUE
image file Pilih gambar dari komputer.
name text Silahkan diisi dengan nama Category yang diinginkan.

Setelah semua input sudah diisi, sekarang silahkan klik Send dan jika berhasil maka kita akan mendapatkan sebuah response dalam format JSON yang berisi informasi data category yang baru saja di insert.

Uji Coba Method Show

Setelah berhasil melakukan proses insert data category ke dalam database, maka sekarang kita lanjutkan untuk menampilkan data tersebut. Silahkan buka aplikasi Postman kemudian masukkan URL berikut ini http://localhost:8000/api/admin/categories/1 dan untuk method-nya silahkan pilih GET.

CATATAN ! : di atas kita akan mencoba menampilkan data category yang memiliki ID 1.

Selanjutnya silahkan klik tab Headers kemudian masukkan key dan value berikut ini :

KEY VALUE
Accept application/json
Content-Type application/json
Authorization Bearer <spasi> Token

Jika sudah, sekarang silahkan klik Send dan jika berhasil maka kita akan mendapatkan sebuah response dengan format JSON yang berisi informasi tentang detail data category dengan ID 1.

Uji Coba Method Update

Selanjutnya kita akan lakukan uji coba untuk proses update, disini untuk attribute image sifatnya opsional, yaitu boleh di isi dan boleh dikosongkan.

Silahkan buka aplikasi Postman kemudian masukkan URL berikut ini http://localhost:8000/api/admin/categories/1 dan untuk method-nya silahkan pilih POST.

Selanjutnya silahkan klik tab Headers kemudian masukkan key dan value berikut ini :

KEY VALUE
Accept application/json
Content-Type application/json
Authorization Bearer <spasi> Token

Jika sudah, sekarang klik tab Body kemudian pilih form-data dan masukkan key dan value berikut ini :

KEY TYPE VALUE
image file Pilih gambar dari komputer (Tidak Wajib Diisi).
name text Silahkan diisi dengan nama Category yang diinginkan.
_method text PATCH

Setelah semua sudah diisi sekarang silahkan klik Send dan jika berhasil maka kita akan mendapatkan sebuah response dengan format JSON yang berisi informasi data category yang diupdate.

Uji Coba Method Destoy

Sekarang kita lanjutkan untuk proses uji coba hapus data dari database. Silahkan buka aplikasi Postman dan masukkan URL berikut ini http://localhost:8000/api/admin/categories/1 dan untuk method-nya silahkan pilih DELETE.

Selanjutnya silahkan klik tab Headers kemudian masukkan key dan value berikut ini :

KEY VALUE
Accept application/json
Content-Type application/json
Authorization Bearer <spasi> Token

Jika sudah, siljhkan klik Send dan jika berhasil maka kita akan mendapatkan sebuah response dengan format JSON yang berisi informasi data category yang sudah dihapus.

CATATAN ! : silahkan tambahkan data category yang banyak ke dalam database untuk digunakan pada materi CRUD Places nanti.

Membuat RESTful API CRUD Places


Sekarang kita akan belajar membuat CRUD RESTful API untuk data places. Dimana di dalam proses insert data place nanti kita akan melakukan multiple upload gambar menggunakan relasi yang sudah pernah kita buat. Artinya 1 data place bisa memiliki banyak gambar.

Langkah 1 - Membuat Resource Place

Pertama, kita akan belajar membuat sebuah resource terlebih dahulu, fungsinya adalah untuk melakukan transformasi data yang ada di dalam Model menjadi format JSON.

Silahkan jalankan perintah berikut ini di dalam terminal/CMD dan pastikan sudah berada di dalam project Laravel-nya.

php artisan make:resource PlaceResource

Jika perintah di atas berhasil dijalankan, maka kita akan mendapatkan 1 file baru dengan nama PlaceResource.php yang berada di dalam folder app/Http/Resource. Setelah itu, kita akan melakukan modifikasi di dalam file tersebut dengan tujuan agar format JSON yang di hasilkan bisa sesuai dengan keinginan kita.

Silahkan buka file tersebut, kemudian ubah semua kode-nya menjadi seperti berikut ini :

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class PlaceResource extends JsonResource
{
    //public properti
    public $status;
    public $message;
    
    /**
     * __construct
     *
     * @param  mixed $status
     * @param  mixed $message
     * @param  mixed $resource
     * @return void
     */
    public function __construct($status, $message, $resource)
    {
        parent::__construct($resource);
        $this->status  = $status;
        $this->message = $message;
    }

    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return [
            'success'   => $this->status,
            'message'   => $this->message,
            'data'      => $this->resource
        ];
    }
}

Dari perubahan kode di atas, pertama kita membuat 2 public properti, properti tersebut nantinya akan diisi nilai yang dikirimkan oleh controller sebagai parameter.

//public properti
public $status;
public $message;

Setelah itu, kita menambahkan method __contruct. Method ini akan pertama kali dijalankan ketika class PlaceResource di panggil, dimana di dalam method ini kita definisikan 3 parameter, yaitu :

  1. $status : merupakan properti $status yang kita buat di atas, yang mana isinya nanti akan berupa nilai boolean, yaitu true atau false yang dikirimkan secara dinamis oleh controller.
  2. $message : merupakan properti $message yang kita buat di atas, yang mana isinya nanti akan berupa pesan/message tentang response dari Rest API yang dikirimkan oleh controller.
  3. $resource : merupakan data yang akan di transformasi menjadi Rest API, ini nanti akan berupa data Model yang dikirim dari controller.

Kemudian kita return ketiga variable di atas di dalam method toArray.

return [
   'success'   => $this->status,
   'message'   => $this->message,
   'data'      => $this->resource
];

Langkah 2 - Membuat Controller Place

Sekarang kita akan lanjutkan untuk membuat sebuah controller untuk data place. Silahkan jalankan perintah berikut ini di dalam terminal/CMD dan pastikan berada di dalam project Laravel.

php artisan make:controller Api/Admin/PlaceController

Jika perintah di atas berhasil dijalankan, maka kita akan mendapatkan 1 file baru dengan nama PlaceController.php yang berada di dalam folder app/Http/Controllers/Api/Admin.

Setelah itu, silahkan buka file tersebut dan ubah semua kode-nya menjadi seperti berikut ini :

<?php

namespace App\Http\Controllers\Api\Admin;

use App\Models\Place;
use Illuminate\Support\Str;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Http\Resources\PlaceResource;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Validator;

class PlaceController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        //get places
        $places = Place::with('category')->when(request()->q, function($places) {
            $places = $places->where('title', 'like', '%'. request()->q . '%');
        })->latest()->paginate(5);
        
        //return with Api Resource
        return new PlaceResource(true, 'List Data Places', $places);
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'title'         => 'required|unique:places',
            'category_id'   => 'required',
            'description'   => 'required',
            'phone'         => 'required',
            'website'       => 'required',
            'office_hours'  => 'required',
            'address'       => 'required',
            'latitude'      => 'required',
            'longitude'     => 'required',
        ]);

        if ($validator->fails()) {
            return response()->json($validator->errors(), 422);
        }

        //create place
        $place = Place::create([
            'title'         => $request->title,
            'slug'          => Str::slug($request->title, '-'),
            'user_id'       => auth()->guard('api')->user()->id,
            'category_id'   => $request->category_id,
            'description'   => $request->description,
            'phone'         => $request->phone,
            'website'       => $request->website,
            'office_hours'  => $request->office_hours,
            'address'       => $request->address,
            'latitude'      => $request->latitude,
            'longitude'     => $request->longitude,
        ]);

        //check request file
        if($request->hasFile('image')) {
            
            //get request file image
            $images = $request->file('image');
            
            //loop file image
            foreach($images as $image) {
                
                //move to storage folder
                $image->storeAs('places', $image->hashName(), 'public');

                //insert database
                $place->images()->create([
                    'image'     => $image->hashName(),
                    'palce_id'  => $place->id
                ]);

            }
        }

        if($place) {
            //return success with Api Resource
            return new PlaceResource(true, 'Data Place Berhasil Disimpan!', $place);
        }

        //return failed with Api Resource
        return new PlaceResource(false, 'Data Place Gagal Disimpan!', null);
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        $place = Place::with('images')->whereId($id)->first();
        
        if($place) {
            //return success with Api Resource
            return new PlaceResource(true, 'Detail Data Place!', $place);
        }

        //return failed with Api Resource
        return new PlaceResource(false, 'Detail Data Place Tidak Ditemukan!', null);
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, Place $place)
    {
        $validator = Validator::make($request->all(), [
            'title'     => 'required|unique:places,title,'.$place->id,
            'category_id'   => 'required',
            'description'   => 'required',
            'phone'         => 'required',
            'website'       => 'required',
            'office_hours'  => 'required',
            'address'       => 'required',
            'latitude'      => 'required',
            'longitude'     => 'required',
        ]);

        if ($validator->fails()) {
            return response()->json($validator->errors(), 422);
        }

        //update place
        $place->update([
            'title'         => $request->title,
            'slug'          => Str::slug($request->title, '-'),
            'user_id'       => auth()->guard('api')->user()->id,
            'category_id'   => $request->category_id,
            'description'   => $request->description,
            'phone'         => $request->phone,
            'website'       => $request->website,
            'office_hours'  => $request->office_hours,
            'address'       => $request->address,
            'latitude'      => $request->latitude,
            'longitude'     => $request->longitude,
        ]);

        //check request file
        if($request->hasFile('image')) {
            
            //get request file image
            $images = $request->file('image');
            
            //loop file image
            foreach($images as $image) {
                
                //move to storage folder
                $image->storeAs('places', $image->hashName(), 'public');

                //insert database
                $place->images()->create([
                    'image'     => $image->hashName(),
                    'palce_id'  => $place->id
                ]);

            }
        }

        if($place) {
            //return success with Api Resource
            return new PlaceResource(true, 'Data Place Berhasil Diupdate!', $place);
        }

        //return failed with Api Resource
        return new PlaceResource(false, 'Data Place Gagal Diupdate!', null);
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        //find place by ID
        $place = Place::findOrFail($id);

        //loop image from relationship
        foreach($place->images()->get() as $image) {
            
            //remove image
            Storage::disk('public')->delete('places/'.basename($image->image));

            //remove child relation
            $image->delete();

        }

        if($place->delete()) {
            //return success with Api Resource
            return new PlaceResource(true, 'Data Place Berhasil Dihapus!', null);
        }

        //return failed with Api Resource
        return new PlaceResource(false, 'Data Place Gagal Dihapus!', null);
    }
}

Dari perubahan kode di atas, pertama kita melakukan import Model Place terlebih dahulu. Karena kita akan banyak menggunakan Model ini untuk mendapatkan data, insert dan lain-lain.

use App\Models\Place;

Setelah itu, kita juga melakukan import Helper string yaitu Str dari Laravel. Dimana akan kita gunakan untuk melakukan generate slug dari data place.

use Illuminate\Support\Str;

Kemudian kita juga melakukan import HTTP Request dari Laravel, yang digunakan untuk menerima sebuah request yang dikirimkan oleh form, cookies, url dan lain-lain.

use Illuminate\Http\Request;

Dan kita juga import PlaceResource yang sudah kita buat sebelumnya. Dimana akan kita gunakan untuk melakukan transformasi data di dalam Model menjadi format JSON.

use App\Http\Resources\PlaceResource;

Karena kita akan melakukan upload file ke dalam server, maka kita butuh bantuan Facades Storage dari Laravel.

use Illuminate\Support\Facades\Storage;

Dan karena kita akan melakukan proses insert data ke dalam database, maka kita butuh sebuah validasi untuk memastikan data yang akan disimpan sudah sesuai dengan yang diharapkan. Dan disini kita akan menggunakan Facades Validator dari Laravel.

use Illuminate\Support\Facades\Validator;

Dan jika kita perhatikan, di dalam class PlaceController kita menambahkan 5 method baru, yaitu :

  1. function index - menampilkan list data places.
  2. function store - melakukan proses insert data place.
  3. function show - menampilkan detail data place.
  4. function update - melakukan proses update data place.
  5. function destroy - mengahapus data place.

function index

Method ini akan kita gunakan untuk mendapatkan list data places dari database melalui Model Place. Dimana kita juga akan memanggil relasi category di dalam Model Place.

//get places
$places = Place::with('category')....

Di atas, kita memanggil relasi yang bernamaa category menggunakan method with atau biasa disebut dengan Eager Loading di dalam Laravel. Dimana relasi tersebut sudah kita buat sebelumnya di dalam Model.

Setelah itu, kita membuat sebuah kondisi menggunakan method when, method ini akan dijalankan ketika kondisi bernilai true.

->when(request()->q, function($places) {

	//...
	
})

Jadi di dalam method when kita membuat kondisi apabila ada sebuah request dengan nama q, maka kita akan melakukan proses pencarian ke dalam table places berdasarkan attribute title yang sesuai dengan isi yang ada di dalam request q tersebut.

$places = $places->where('title', 'like', '%'. request()->q . '%');

Tapi, jika request q tidak memiliki nilai / value, maka kita tidak akan menjalankan kode di atas. Yang artinya proses tersebut akan dilewati.

Setelah itu, kita akan urutkan datanya menggunakan method latest(), yang tujuannya agar menampilkan data yang paling terbaru. Dan setelah itu, kita batasi data yang akan ditampilkan dari setiap halaman menggunakan method paginate.

->latest()->paginate(5);

Jika data sudah ditemukan, maka kita akan lakukan return menggunakan PlaceResource agar data diubah menjadi format JSON.

//return with Api Resource
return new PlaceResource(true, 'List Data Places', $places);

function store

Method ini akan kita gunakan untuk melakukan proses insert data ke dalam database, dimana kita juga akan melakukan proses upload multiple gambar ke dalam server.

Sebelum itu, kita akan membuat sebuah validasi terlebih dahulu, tujuannya untuk memvalidasi data yang akan di simpan di dalam database apakah sudah sesuai dengan yang diharapkan.

$validator = Validator::make($request->all(), [
    'title'         => 'required|unique:places',
    'category_id'   => 'required',
    'description'   => 'required',
    'phone'         => 'required',
    'website'       => 'required',
    'office_hours'  => 'required',
    'address'       => 'required',
    'latitude'      => 'required',
    'longitude'     => 'required',
]);

Dari penambahan validasi di atas, kurang lebih penjelasannya seperti berikut ini :

KEY VALIDATION DESCRIPTION
title required field wajib diisi.
unique:places field bersifat unik dan tidak boleh ada yang sama di dalam table places.
category_id required field wajib diisi.
description required field wajib diisi.
phone required field wajib diisi.
website required field wajib diisi.
office_hours required field wajib diisi.
address required field wajib diisi.
latitude required field wajib diisi.
longitude required field wajib diisi.

Jika data yang dikirimkan belum sesuai dengan validasi di atas, maka kita akan melakukan return menggunakan format JSON dengan informasi error validasi.

if ($validator->fails()) {
   return response()->json($validator->errors(), 422);
}

Tapi jika data yang dikirimkan sudah sesuai, maka kita akan melakukan proses insert data ke dalam database.

//create place
$place = Place::create([
    'title'         => $request->title,
    'slug'          => Str::slug($request->title, '-'),
    'user_id'       => auth()->guard('api')->user()->id,
    'category_id'   => $request->category_id,
    'description'   => $request->description,
    'phone'         => $request->phone,
    'website'       => $request->website,
    'office_hours'  => $request->office_hours,
    'address'       => $request->address,
    'latitude'      => $request->latitude,
    'longitude'     => $request->longitude,
]);

Dari proses insert data di atas, kurang lebih seperti berikut ini penjelasannya.

ATTRIBUTE VALUE DESCRIPTION
title $request->title mengambil dari request yang bernama title.
slug Str::slug($request->title, '-') mengambil dari request yang bernama title, kemudian di letakkan di dalam Str::slug dengan tujuan menambahkan karakter - sebagai pengganti spasi antar kata.
user_id auth()->guard('api')->user()->id mengambil ID user yang sedang login.
category_id $request->category_id mengambil dari request yang bernama category_id.
description $request->description mengambil dari request yang bernama description.
phone $request->phone mengambil dari request yang bernama phone.
website $request->website mengambil dari request yang bernama website.
office_hours $request->office_hours mengambil dari request yang bernama office_hours.
address $request->address mengambil dari request yang bernama address.
latitude $request->latitude mengambil dari request yang bernama latitude.
longitude $request->longitude mengambil dari request yang bernama longitude.

Setelah data berhasil di insert ke dalam database, langkah selanjutnya kita akan melakukan proses upload multiple gambar.

Pertama, kita akan melakukan pengecekan terlebih dahulu, apakah ada sebuah request dengan tipe file yang bernama image.

//check request file
if($request->hasFile('image')) {

	//...

}

Jika ada, maka kita buat sebuah variable baru dengan nama $images isinya adalah request file yang bernama image, dimana valuenya nanti akan berupa beberapa gambar.

//get request file image
$images = $request->file('image');

Karena nilai dari variable $images lebih dari satu, maka kita perlu melakukan perulangan data.

//loop file image
foreach($images as $image) {

	//...

}

Di dalam perulangan data di atas, pertama kita akan melakukan upload gambar ke dalam server menggunakan method storeAs dan gambarnya akan disimpan di dalam folider storage/app/public/places dan untuk nama dari file tersebut akan di random menggunakan method hashName.

//move to storage folder
$image->storeAs('places', $image->hashName(), 'public');

Setelah gambar berhasil di upload di dalam server, maka selanjutnya kita akan melakukan proses insert data gambar di dalam relasi.

//insert database
$place->images()->create([
    'image'     => $image->hashName(),
    'palce_id'  => $place->id
]);

Di atas, kita menggunakan object $place untuk memanggil relasi images dan melakukan proses insert menggunakan method create. Dan data yang di insert adalah nama dari gambar yang telah di upload dan ID dari data place.

Jika dari proses insert data place di atas berhasil, maka kita akan melakukan return menggunakan PlaceResource dengan status success true.

//return success with Api Resource
return new PlaceResource(true, 'Data Place Berhasil Disimpan!', $place);

Tapi, jika proses insert data place gagal dilakukan, maka kita akan melakukan return menggunakan PlaceResource dengan status success false.

//return failed with Api Resource
return new PlaceResource(false, 'Data Place Gagal Disimpan!', null);

function show

Method ini akan digunakan untuk menampilkan detail data berdasarkan ID yang di dapat dari URL atau parameter. Disini kita menggunakan Eloquent untuk mencari data tersebut.

$place = Place::with('images')->whereId($id)->first();

Di atas kita mencari data place berdasarkan ID yang di dapatkan dari variable $id, variable tersebut akan berisi data yang diambil dari parameter URL. Dan di atas kita juga memanggil relasi image meggunakan method with atau biasa disebut dengan Eager Loading.

Jika data ditemukan, maka kita akan melakukan return menggunakan PlaceResource dengan status success true.

//return success with Api Resource
return new PlaceResource(true, 'Detail Data Place!', $place);

Dan jika data tidak ditemukan, maka akan melakukan return juga menggunakan PlaceeResource dengan status success false.

//return failed with Api Resource
return new PlaceResource(false, 'Detail Data Place Tidak Ditemukan!', null);

function update

Method ini akan digunakan untuk melakukan proses update data ke dalam database. Sebelum data tersebut di update, kita akan melakukan validasi terlebih dahulu, tujuannya agar memastikan data yang akan di update tersebut sudah sesuai dengan yang diharapkan.

$validator = Validator::make($request->all(), [
    'title'     => 'required|unique:places,title,'.$place->id,
    'category_id'   => 'required',
    'description'   => 'required',
    'phone'         => 'required',
    'website'       => 'required',
    'office_hours'  => 'required',
    'address'       => 'required',
    'latitude'      => 'required',
    'longitude'     => 'required',
]);

Dari penambahan kode validasi di atas, kurang lebih penjelasannya seperti berikut ini :

KEY VALIDATION DESCRIPTION
title required field wajib diisi.
unique:places,title,'.$place->id field bersifat unik dan tidak boleh ada yang sama di dalam table places. Karena bersifat unik, maka untuk proses update kita tambahkan title,'.$place->id, yang artinya kusus ID place yang diupdate akan dikecualikan.
category_id required field wajib diisi.
description required field wajib diisi.
phone required field wajib diisi.
website required field wajib diisi.
office_hours required field wajib diisi.
address required field wajib diisi.
latitude required field wajib diisi.
longitude required field wajib diisi.

Jadi, jika data yang dikirimkan belum sesuai dengan validasi di atas, maka akan melakukan return dengan format JSON dengan informasi error validasi.

if ($validator->fails()) {
  return response()->json($validator->errors(), 422);
}

Tapi, jika data yang dikirimkan sudah sesuai maka kita akan melakukan proses update data ke dalam database.

//update place
$place->update([
    'title'         => $request->title,
    'slug'          => Str::slug($request->title, '-'),
    'user_id'       => auth()->guard('api')->user()->id,
    'category_id'   => $request->category_id,
    'description'   => $request->description,
    'phone'         => $request->phone,
    'website'       => $request->website,
    'office_hours'  => $request->office_hours,
    'address'       => $request->address,
    'latitude'      => $request->latitude,
    'longitude'     => $request->longitude,
]);

Setelah itu sama seperti yang ada di dalam function store, kita akan melakukan pengecekan apakah ada sebuah request dengan jenis file yang bernama image,

//check request file
if($request->hasFile('image')) {

	//...
	
}

Jika ada, maka kita akan membuat variable baru dengan nama $images yang bertujuan untuk menyimpan data gambar yang dikirimkan.

//get request file image
$images = $request->file('image');

Karena data gambar tersebut bisa saja bernilai lebih dari 1, maka kita akan melakukan proses perulangan menggunakan foreach.

//loop file image
foreach($images as $image) {

	//...

}

Dimana di dalam perulangan tersebut, kita melakukan upload gambar ke dalam server menggunakan method storeAs dan melakukan rename untuk nama gambar tersebut dengan random menggunakan method hashName.

//move to storage folder
$image->storeAs('places', $image->hashName(), 'public');

Setelah itu, kita melakukan insert data gambar ke dalam relaasi images yang ada di Model Place.

//insert database
$place->images()->create([
    'image'     => $image->hashName(),
    'palce_id'  => $place->id
]);

Jika proses update data place berhasil dilakukan, maka kita akan melakukan return menggunakan PlaceResource dengan status success true.

//return success with Api Resource
return new PlaceResource(true, 'Data Place Berhasil Diupdate!', $place);

Tapi, jika proses update data gagal dilakukan, maka kita juga akan melakukan return menggunakan PlaceResource dengan status success false.

//return failed with Api Resource
return new PlaceResource(false, 'Data Place Gagal Diupdate!', null);

function destroy

Method ini akan digunakan untuk melakukan proses delete data di dalam database berdasarkan ID yang didapatkan dari paramter.

//find place by ID
$place = Place::findOrFail($id);

Setelah itu, kita akan melakukan perulangan untuk mendapatkan data gambar yang terkait data place yang akan dihapus.

//loop image from relationship
foreach($place->images()->get() as $image) {

	//...
	
}

Di dalam proses perulangan, kita akan melakuakan hapus gambar di dalam server.

//remove image
Storage::disk('public')->delete('places/'.basename($image->image));

Setelah gambar berhasil dihapus, selanjutnya kita akan mengahapus data relasinya di dalam table place_images.

//remove child relation
$image->delete();

Dan jika semua gambar dan data relasi yang terkait sudah berhasil dihapus, maka selanjutnya kita akan melakukan proses hapus data place-nya atau data induknya.

$place->delete()

Jika proses hapus data berhasil dilakukan, maka kita akan return menggunakan PlaceResource dengan status success true.

//return success with Api Resource
return new PlaceResource(true, 'Data Place Berhasil Dihapus!', null);

Tapi, jik proses hapus data gagal dilakukan maka akan melakukan return menggunakan PlaceResource dengan status success false.

//return failed with Api Resource
return new PlaceResource(false, 'Data Place Gagal Dihapus!', null);

Langkah 3 - Membuat Route API Places

Setelah berhasil membuat controller beserta method-method di dalamnya, maka sekarang kita akan lanjutkan membuat route agar controller kita dapat diakses melalui web browser.

Silahkan buka file routes/api.php, kemudian tambahkan route berikut ini di dalam prefix admin dan group middleware auth:api, tepatnya di bawah route /categories.

//places resource
Route::apiResource('/places', App\Http\Controllers\Api\Admin\PlaceController::class, ['except' => ['create', 'edit'], 'as' => 'admin']);

Untuk memastikan route berhasil di tambahkan, silahkan jalankan perintah berkut ini di dalam terminal/CMD dan pastikan berada di dalam project Laravel.

php artisan route:list

Langkah 4 - Uji Coba API Places

Setelah berhasil membuat controller, method dan route. Sekarang kita akan lanjutkan belajar melakukan API testing menggunakan aplikasi Postman.

Uji Coba Method Index

Pertama, kita akan melakukan uji coba API di method index. Silahkan buka aplikasi Postman kemudian masukkan URL berikut ini : http://localhost:8000/api/admin/places dan untuk method-nya silahkan pilih GET.

Selanjutnya silahkan klik tab Headers kemudian masukkan key dan value berikut ini :

KEY VALUE
Accept application/json
Content-Type application/json
Authorization Bearer <spasi> Token

Jika sudah silahkan klik Send dan jika berhasil maka kita akan mendapatkan response dalam format JSON yang berisi informasi list data places.

Uji Coba Method Store

Sekarang kita akan lanjutkan uji coba proses insert data ke dalam database, disini kita juga akan belajar melakukan upload multiple gambar di dalamnya.

Silahkan buka aplikasi Postman kemudian masukkan URL berikut ini : http://localhost:8000/api/admin/places dan untuk method-nya silahkan pilih POST.

Selanjutnya silahkan klik tab Headers kemudian masukkan key dan value berikut ini :

KEY VALUE
Accept application/json
Content-Type application/json
Authorization Bearer <spasi> Token

Karena akan melakukan proses insert, maka kita akan mengirimkan beberapa data ke dalam server. Silahkan klik tab Body di dalam Postman dan pilih form-data, kemudian masukkan key dan value berikut ini :

KEY TYPE VALUE
title text Silahkan diisi dengan judul place yang diinginkan.
category_id text Silahkan disesuaikan dengan ID category yang diinginkan.
description text Silahkan diisi dengan deskripsi yang diinginkan.
phone text Silahkan diisi dengan phone yang diinginkan.
website text Silahkan diisi dengan website yang diinginkan.
office_hours text Silahkan diisi dengan jam kerja yang diinginkan.
address text Silahkan diisi dengan alamat yang diinginkan.
latitude text Silahkan diisi dengan latitude yang diinginkan (sementara boleh diisi -).
longitude text Silahkan diisi dengan latitude yang diinginkan (sementara boleh diisi -).
image[] file Pilih gambar dari komputer (opsional, boleh dikosongkan).
image[] file Pilih gambar dari komputer (opsional, boleh dikosongkan).
image[] file Pilih gambar dari komputer (opsional, boleh dikosongkan).

Jika sudah mengisi form-data, kurang lebih seperti berikut ini contohnya :

CATATAN : di atas kita contohkan untuk melakukan upload 3 gambar, teman-teman bisa menambahkan sampai tidak terbatas untuk gambar yang akan di upload.

Sekarang, silahkan klik Send dan jika berhasil maka kita akan mendapatkan response dengan format JSON yang berisi informasi data berhasil di insert ke dalam database.

Dan jika coba kita cek di dalam folder storage/app/public/places, maka ketiga gambar tersebut berhasil di upload.

Uji Coba Method Show

Kita lanjutkan untuk melakukan proses uji coba method show atau menampilkan detail data berdasarkan ID. Silahkan buka aplikasi Postman kemudian masukkan URL berikut ini : http://localhost:8000/api/admin/places/1 dan untuk method-nya adalah GET.

INFORMASI : untuk contoh di atas, saya menggunakan data place yang memiliki ID 1.

Selanjutnya silahkan klik tab Headers kemudian masukkan key dan value berikut ini :

KEY VALUE
Accept application/json
Content-Type application/json
Authorization Bearer <spasi> Token

Jika sudah silahkan klik Send dan jika berhasil maka kita akan mendapatkan response dalam format JSON yang berisi informasi detail data place berserta relasi image di dalamnya.

Uji Coba Method Update

Setelah berhasil melakukan proses uji coba insert dan menampilkan detail data, maka sekarang kita akan lanjutkan untuk melakukan uji coba proses update data.

Silahkan buka aplikasi Postman, kemudian masukkan URL berikut ini : http://localhost:8000/api/admin/places/1 dan untuk method-nya silahkan pilih POST.

INFORMASI : untuk contoh di atas, saya menggunakan data place yang memiliki ID 1.

Selanjutnya silahkan klik tab Headers kemudian masukkan key dan value berikut ini :

KEY VALUE
Accept application/json
Content-Type application/json
Authorization Bearer <spasi> Token

Karena akan melakukan proses update, maka kita akan mengirimkan beberapa data ke dalam server. Silahkan klik tab Body di dalam Postman dan pilih form-data, kemudian masukkan key dan value berikut ini :

KEY TYPE VALUE
title text Silahkan diisi dengan judul place yang diinginkan.
category_id text Silahkan disesuaikan dengan ID category yang diinginkan.
description text Silahkan diisi dengan deskripsi yang diinginkan.
phone text Silahkan diisi dengan phone yang diinginkan.
website text Silahkan diisi dengan website yang diinginkan.
office_hours text Silahkan diisi dengan jam kerja yang diinginkan.
address text Silahkan diisi dengan alamat yang diinginkan.
latitude text Silahkan diisi dengan latitude yang diinginkan (sementara boleh diisi -).
longitude text Silahkan diisi dengan latitude yang diinginkan (sementara boleh diisi -).
_method text PATCH

Jika sudah mengisi form-data, kurang lebih seperti berikut ini contohnya :

Di atas, kita tidak menambahkan key untuk image. artinya kita melakukan update data dengan image baru, tapi jika teman-teman ingin mengupdate berserta image baru, silahkan bisa ditambahkan sendiri.

Dan di atas kita juga menambahkan 1 key baru dengan nama _method yang isinya adalah PATCH. Key ini digunakan ketika kita melakukan proses update. Karena pada dasarnya browser itu hanya mengenali 2 jenis request saja, yaitu POST dan GET.

Jika sudah, silahkan klik Send dan jika berhasil maka kita akan mendapatkan response dengan format JSON yang berisi informasi data place yang baru saja di update.

Uji Coba Proses Destroy

Terakhir kita akan lakukan uji coba untuk proses destroy atau menghapus data dari database. Silahkan buka aplikasi Postman, kemudian masukkan URL berikut ini : http://localhost:8000/api/admin/places/1 dan untuk method-nya silahkan pilih DELETE.

INFORMASI : untuk contoh di atas, saya menggunakan data place yang memiliki ID 1.

Selanjutnya silahkan klik tab Headers kemudian masukkan key dan value berikut ini :

KEY VALUE
Accept application/json
Content-Type application/json
Authorization Bearer <spasi> Token

Jika sudah, silahkan klik Send dan jika berhasil maka kita akan mendapatkan sebuah response dengan format JSON yang berisi informasi data telah berhasil dihapus dari database.

Membuat RESTful API CRUD Sliders


Pada materi kali ini kita akan belajar membuat CRUD RESTful API untuk data slider. Slider merupakan gambar banner yang biasanya ada di dalam sebuah website dan berada di halaman homepage paling atas.

Karena data slider, maka kita juga akan belajar untuk melakukan upload gambar ke dalam server seperti yang pernah kita lakukan di materi-materi sebelumnya. Dan di dalam controller nanti kita akan buat beberapa method saja, yaitu index, store dan destroy, karena akan disesuaikan dengan UI (User Interface) di halaman website.

Langkah 1 - Membuat Resource Slider

Pertama, tentu kita akan belajar membuat Resource terlebih dahulu, tujuannya agar data yang di dapatkan dari model diubah menjadi format JSON dengan lebih cepat dan mudah.

Silahkan jalankan perintah berikut ini di dalam terminal/CMD dan pastikan berada di dalam project Laravel.

php artisan make:resource SliderResource

Jika perintah di atas berhasil dijalankan, maka kita akan mendapatkan 1 file baru dengan nama SliderResource.php yang berada di dalam folder app/Http/Resources. Silahkan buka file tersebut dan kita akan melakukan kustomisasi kode di dalamnya menjadi seperti berikut ini.

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class SliderResource extends JsonResource
{
    //public properti
    public $status;
    public $message;
    
    /**
     * __construct
     *
     * @param  mixed $status
     * @param  mixed $message
     * @param  mixed $resource
     * @return void
     */
    public function __construct($status, $message, $resource)
    {
        parent::__construct($resource);
        $this->status  = $status;
        $this->message = $message;
    }

    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return [
            'success'   => $this->status,
            'message'   => $this->message,
            'data'      => $this->resource
        ];
    }
}

Dari perubahan kode di atas, pertama kita membuat 2 public properti, properti tersebut nantinya akan diisi nilai yang dikirimkan oleh controller sebagai parameter.

//public properti
public $status;
public $message;

Setelah itu, kita menambahkan method __contruct. Method ini akan pertama kali dijalankan ketika class SliderResource di panggil, dimana di dalam method ini kita definisikan 3 parameter, yaitu :

  1. $status : merupakan properti $status yang kita buat di atas, yang mana isinya nanti akan berupa nilai boolean, yaitu true atau false yang dikirimkan secara dinamis oleh controller.
  2. $message : merupakan properti $message yang kita buat di atas, yang mana isinya nanti akan berupa pesan/message tentang response dari Rest API yang dikirimkan oleh controller.
  3. $resource : merupakan data yang akan di transformasi menjadi Rest API, ini nanti akan berupa data Model yang dikirim dari controller.

Kemudian kita return ketiga variable di atas di dalam method toArray.

return [
   'success'   => $this->status,
   'message'   => $this->message,
   'data'      => $this->resource
];

Langkah 2 - Membuat Controller Slider

Sekarang kita lanjutkan untuk membuat controller slider. Silahkan jalankan perintah berikut ini di dalam terminal/CMD dan pastikan berada di dalam folder project-nya.

php artisan make:controller Api/Admin/SliderController

Jika perintah di atas berhasil dijalankan, maka kita akan mendapatkan 1 file baru dengan nama SliderController.php yang berada di dalam folder app/Http/Controllers/Api/Admin. Setelah itu, silahkan buka file tersebut dan ubah kode-nya menjadi seperti berikut ini :

<?php

namespace App\Http\Controllers\Api\Admin;

use App\Models\Slider;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Http\Resources\SliderResource;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Validator;

class SliderController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        //get sliders
        $sliders = Slider::latest()->paginate(5);
        
        //return with Api Resource
        return new SliderResource(true, 'List Data Sliders', $sliders);
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'image'    => 'required|image|mimes:jpeg,jpg,png|max:2000',
        ]);

        if ($validator->fails()) {
            return response()->json($validator->errors(), 422);
        }

        //upload image
        $image = $request->file('image');
        $image->storeAs('sliders', $image->hashName(), 'public');

        //create slider
        $slider = Slider::create([
            'image'=> $image->hashName(),
            'user_id'   => auth()->guard('api')->user()->id,
        ]);

        if($slider) {
            //return success with Api Resource
            return new SliderResource(true, 'Data Slider Berhasil Disimpan!', $slider);
        }

        //return failed with Api Resource
        return new SliderResource(false, 'Data Slider Gagal Disimpan!', null);
    }

        /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy(Slider $slider)
    {
        //remove image
        Storage::disk('public')->delete('sliders/'.basename($slider->image));

        if($slider->delete()) {
            //return success with Api Resource
            return new SliderResource(true, 'Data Slider Berhasil Dihapus!', null);
        }

        //return failed with Api Resource
        return new SliderResource(false, 'Data Slider Gagal Dihapus!', null);
    }
}

Dari perubahan yang kita laakukan di atas, pertama kita melakukan import Model Slider terlebih dahulu.

use App\Models\Slider;

Kemudian kita juga melakukan import HTTP Request dari Laravel, yang digunakan untuk menerima sebuah request yang dikirimkan oleh form, cookies, url dan lain-lain.

use Illuminate\Http\Request;

Dan kita juga import SliderResource yang sudah kita buat sebelumnya. Dimana akan kita gunakan untuk melakukan transformasi data di dalam Model menjadi format JSON.

use App\Http\Resources\SliderResource;

Dan karena akan melakukan proses upload gambar, maka kita butuh Facades Storage dari Laravel.

use Illuminate\Support\Facades\Storage;

Untuk memastikan data yang dikirim aman, maka kita butuh sebuah validasi di dalam proses insert nantinya dan disini kita akan mengunakan Facades Validator dari Laravel.

use Illuminate\Support\Facades\Validator;

Dan di dalam class SliderController kita menambahkan 3 method baru, yaitu :

  1. function index - menampilkan list data sliders.
  2. function store - melakukan proses insert data slider.
  3. function destroy - mengahapus data slider.

function index

Method ini akan kita gunakan untuk menampilkan list data sliders dari database. Dan disini kita menggunakan Model untuk mengambilnya.

//get sliders
$sliders = Slider::latest()->paginate(5);

Dia atas, kita tambahkan method latest untuk mengurutkan data yang ditampilkan berdasarkan yang paling terbaru dan kita batas data yang akan ditampilkan perhalaman menggunakan method paginate.

Jika data sudah didapatkan, selanjutnya kita masukkan di dalam SliderResource agar data tersebut diubah menjadi format JSON.

//return with Api Resource
return new SliderResource(true, 'List Data Sliders', $sliders);

function store

Method ini akan kita gunakan untuk melakukan proses insert data ke dalam database dan melakukan proses upload gambar ke dalam server.

Disini pertama-tama kita akan melakukan konfigurasi validasi terlebih dahulu, dimana untuk memastikan data yang akan di insert sudah sesuai dengan yang diharapkan.

$validator = Validator::make($request->all(), [
    'image'    => 'required|image|mimes:jpeg,jpg,png|max:2000',
]);

Dari penambahan kode validasi di atas, kurang lebih penjelasannya seperti berikut ini :

KEY VALIDATION DESCRIPTION
images required field wajib diisi.
image field harus gambar.
mimes:jpeg,jpg,png field harus memiliki extensi .jpg, .jpeg dan .png.
max:2000 field maksimal memiliki ukuran 2 Mb.

Jika data yang dikirimkan belum sesuai dengan validasi di atas, maka kita akan melakuakn return menggunakan format JSON dengan informasi error validasi.

if ($validator->fails()) {
  return response()->json($validator->errors(), 422);
}

Tapi, jika data yang dikirimkan sudah sesuai, maka pertama kita akan melakukan proses upload gambar ke dalam server.

//upload image
$image = $request->file('image');
$image->storeAs('sliders', $image->hashName(), 'public');

Di atas, kita membuat variable baru dengan nama $image yang isinya adalah request dengan jenis file yang bernama image.

Setelah itu, kita move atau pindahkan gambar tersebut ke dalam folder storage/app/public/sliders menggunakan method storeAs dan untuk nama file-nya akan di ubah menjadi random menggunakan method hashName.

Setelah data gambar berhasil di upload di dalam server, maka selanjutnya kita akan melakukan proses insert data slider ke dalam database menggunakan Eloquent.

//create slider
$slider = Slider::create([
   'image'=> $image->hashName(),
   'user_id'   => auth()->guard('api')->user()->id,
]);

Jika proses insert data di atas berhasil, maka kita akan return menggunakan SliderResource dengan status success true.

//return success with Api Resource
return new SliderResource(true, 'Data Slider Berhasil Disimpan!', $slider);

Tapi, jika proses insert data gagal dilakukan, maka kita akan melakukan return menggunakan SliderResource dengan status success false.

//return failed with Api Resource
return new SliderResource(false, 'Data Slider Gagal Disimpan!', null);

function destroy

Method ini akan digunakan untuk melakukan proses hapus data dari database. Disini kita juga akan melakukan proses hapus data gambar yang ada di dalam server.

//remove image
Storage::disk('public')->delete('sliders/'.basename($slider->image));

Di atas kita melakukan proses hapus gambar yang ada di dalam folder storage/app/public/sliders.

Setelah gambar berhasil dihapus di dalam server, maka selanjutnya kita akan menghapus data slider yang ada di dalam database.

$slider->delete()

Jika dari proses hapus data berhasil dilakukan, maka kita akan return menggunakan SliderResource dengan status success true.

//return success with Api Resource
return new SliderResource(true, 'Data Slider Berhasil Dihapus!', null);

Tapi, jika proses hapus data gagal dilakukan, maka kita juga akan return menggunakan SliderResource dengan status success false.

//return failed with Api Resource
return new SliderResource(false, 'Data Slider Gagal Dihapus!', null);

Langkah 3 - Menambahkan Route API Sliders

Setelah berhasil membuat controller beserta method-method di dalamnya, maka sekarang kita akan lanjutkan membuat route agar controller kita dapat diakses melalui web browser.

Silahkan buka file routes/api.php, kemudian tambahkan route berikut ini di dalam prefix admin dan group middleware auth:api, tepatnya di bawah route /places.

//sliders resource
Route::apiResource('/sliders', App\Http\Controllers\Api\Admin\SliderController::class, ['except' => ['create', 'show', 'edit', 'update'], 'as' => 'admin']);

Untuk memastikan route berhasil di tambahkan, silahkan jalankan perintah berkut ini di dalam terminal/CMD dan pastikan berada di dalam project Laravel.

php artisan route:list

Langkah 4 - Uji Coba API Sliders

Sekarang kita akan belajar melakukan proses uji coba Rest API yang sudah kita buat di atas. Disini kita akan menguji setiap method yang kita buat.

Uji Coba Method Index

Pertama, kita akan melakukan uji coba untuk menampilkan list data sliders dari database. Silahkan buka aplikasi Postman kemudian masukkan URL berikut ini : http://localhost:8000/api/admin/sliders dan untuk method-nya silahkan pilih GET.

Selanjutnya silahkan klik tab Headers kemudian masukkan key dan value berikut ini :

KEY VALUE
Accept application/json
Content-Type application/json
Authorization Bearer <spasi> Token

Jika sudah, silahkan klik Send dan jika berhasil maka kita akan mendapatkan response dalam format JSON dengan informasi list data sliders.

Uji Coba Method Store

Sekarang kita lanjutkan untuk melakukan proses uji coba insert data slider. SIlahkan buka aplikasi Postman kemudian masukkan URL berikut ini : http://localhost:8000/api/admin/sliders dan untuk method-nya adalah POST.

Selanjutnya silahkan klik tab Headers kemudian masukkan key dan value berikut ini :

KEY VALUE
Accept application/json
Content-Type application/json
Authorization Bearer <spasi> Token

Kemudian klik tab Body dan pilih form-data. Selanjutnya silahkan masukkan key dan value berikut ini :

KEY TYPE VALUE
image file Pilih gambar dari komputer.

Jika sudah, silhakan klik Send dan jika berhasil maka kita akan mendapatkan response dalam bentuk JSON yang berisi informasi data slider berhasil di insert.

Uji Coba Destroy

Sekarang kita lanjuitkan untuk proses uji coba hapus data dari database dan sekalian menghapus file gambar dari server. Silahkan buka aplikasi Postman dan masukkan URL berikut ini http://localhost:8000/api/admin/sliders/1 dan untuk method-nya silahkan pilih DELETE.

Selanjutnya silahkan klik tab Headers kemudian masukkan key dan value berikut ini :

KEY VALUE
Accept application/json
Content-Type application/json
Authorization Bearer <spasi> Token

Jika sudah, silahkan klik Send dan jika berhasil maka kita akan mendapatkan sebuah response dalam format JSON yang berisi informasi data slider yang berhasil dihapus.

Membuat RESTful API CRUD Users


Pada materi kali ini kita akan belajar membuat CRUD RESTful API untuk data users. User disini merupakan pengguna yang dapat mengakses halaman admin dan dapat merubah isi konten yang ada di website, baik itu melakukan proses insert, store, edit, update maupun delete dari semua data yang ada.

Langkah 1 - Membuat Resource User

Sebelum membuat controller, pertama-tama kita akan belajar membuat Resource terlebih dahulu, dimana Resource ini akan kita gunakan untuk mengubah data yang kita dapatkan dari Model menjadi format JSON dengan lebih mudah dan cepat.

Silahkan jalankan perintah berikut ini di dalam terminal/CMD dan pastikan teman-teman berada di dalam project Laravel-nya.

php artisan make:resource UserResource

Jika perintah di atas berhasil dijalankan, maka kita akan mendapatkan 1 file resource baru dengan nama UserResource.php di dalam folder app/Http/Resources. SIlahkan buka file tersebut dan ubah semua kode-nya menjadi seperti berikut ini :

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class UserResource extends JsonResource
{
    //public properti
    public $status;
    public $message;
    
    /**
     * __construct
     *
     * @param  mixed $status
     * @param  mixed $message
     * @param  mixed $resource
     * @return void
     */
    public function __construct($status, $message, $resource)
    {
        parent::__construct($resource);
        $this->status  = $status;
        $this->message = $message;
    }

    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return [
            'success'   => $this->status,
            'message'   => $this->message,
            'data'      => $this->resource
        ];
    }
}

Dari perubahan kode di atas, pertama kita membuat 2 public properti, properti tersebut nantinya akan diisi nilai yang dikirimkan oleh controller sebagai parameter.

//public properti
public $status;
public $message;

Setelah itu, kita menambahkan method __contruct. Method ini akan pertama kali dijalankan ketika class UserResource di panggil, dimana di dalam method ini kita definisikan 3 parameter, yaitu :

  1. $status : merupakan properti $status yang kita buat di atas, yang mana isinya nanti akan berupa nilai boolean, yaitu true atau false yang dikirimkan secara dinamis oleh controller.
  2. $message : merupakan properti $message yang kita buat di atas, yang mana isinya nanti akan berupa pesan/message tentang response dari Rest API yang dikirimkan oleh controller.
  3. $resource : merupakan data yang akan di transformasi menjadi Rest API, ini nanti akan berupa data Model yang dikirim dari controller.

Kemudian kita return ketiga variable di atas di dalam method toArray.

return [
   'success'   => $this->status,
   'message'   => $this->message,
   'data'      => $this->resource
];

Langkah 2 - Membuat Controller User

Setelah berhasil membuat UserResource untuk menangani response JSON, maka sekarang kita akan lanjutkan untuk membuat controller baru untuk user.

Silahkan jalankan perintah berikut ini di dalam terminal/CMD dan pastikan teman-teman menjalankan perintahnya di dalam project Laravel.

php artisan make:controller Api/Admin/UserController

Jika perintah di atas berhasil dijalankan, maka kita akan mendapatkan 1 file controller baru dengan nama UserController.php yang berada di dalam folder app/Http/Controllers/Api/Admin.

Silahkan buka file tersebut, kemudian ubah semua kode-nya menjadi seperti berikut ini :

<?php

namespace App\Http\Controllers\Api\Admin;

use App\Models\User;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Http\Resources\UserResource;
use Illuminate\Support\Facades\Validator;

class UserController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        //get users
        $users = User::when(request()->q, function($users) {
            $users = $users->where('name', 'like', '%'. request()->q . '%');
        })->latest()->paginate(5);
        
        //return with Api Resource
        return new UserResource(true, 'List Data Users', $users);
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'name'     => 'required',
            'email'    => 'required|unique:users',
            'password' => 'required|confirmed' 
        ]);

        if ($validator->fails()) {
            return response()->json($validator->errors(), 422);
        }

        //create user
        $user = User::create([
            'name'      => $request->name,
            'email'     => $request->email,
            'password'  => bcrypt($request->password)
        ]);

        if($user) {
            //return success with Api Resource
            return new UserResource(true, 'Data User Berhasil Disimpan!', $user);
        }

        //return failed with Api Resource
        return new UserResource(false, 'Data User Gagal Disimpan!', null);
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        $user = User::whereId($id)->first();
        
        if($user) {
            //return success with Api Resource
            return new UserResource(true, 'Detail Data User!', $user);
        }

        //return failed with Api Resource
        return new UserResource(false, 'Detail Data User Tidak DItemukan!', null);
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, User $user)
    {
        $validator = Validator::make($request->all(), [
            'name'     => 'required',
            'email'    => 'required|unique:users,email,'.$user->id,
            'password' => 'confirmed'
        ]);

        if ($validator->fails()) {
            return response()->json($validator->errors(), 422);
        }

        if($request->password == "") {

            //update user without password
            $user->update([
                'name'      => $request->name,
                'email'     => $request->email,
            ]);
        } else {

            //update user with new password
            $user->update([
                'name'      => $request->name,
                'email'     => $request->email,
                'password'  => bcrypt($request->password)
            ]);

        }

        if($user) {
            //return success with Api Resource
            return new UserResource(true, 'Data User Berhasil Diupdate!', $user);
        }

        //return failed with Api Resource
        return new UserResource(false, 'Data User Gagal Diupdate!', null);
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy(User $user)
    {
        if($user->delete()) {
            //return success with Api Resource
            return new UserResource(true, 'Data User Berhasil Dihapus!', null);
        }

        //return failed with Api Resource
        return new UserResource(false, 'Data User Gagal Dihapus!', null);
    }
}

Dari perubahan kode di dalam UserController di atas, pertama-tama kita melalukan import Model User terlebih dahulu. Karena kita akan menggunakan Model tersebut untuk melakukan manipulasi data ke dalam database.

use App\Models\User;

Kemudian kita juga melakukan import HTTP Request dari Laravel, yang digunakan untuk menerima sebuah request yang dikirimkan oleh form, cookies, url dan lain-lain.

use Illuminate\Http\Request;

Dan kita juga import UserResource yang sudah kita buat sebelumnya. Dimana akan kita gunakan untuk melakukan transformasi data di dalam Model menjadi format JSON.

use App\Http\Resources\UserResource;

Karena akan membuat proses insert maupun update, tentu saja kita akan butuh yang namanya validasi. Dimana kita akan melakukan pengecekan terhadap data yang akan di insert ke dalam database. Dan disini kita akan menggunakan Facades Validator dari Laravel.

use Illuminate\Support\Facades\Validator;

Dan jika kita perhatikan, di dalam class UserController kita menambahkan 5 method baru di dalamnya, yaitu :

  1. function index - menampilkan list data users.
  2. function store - melakukan proses insert data user.
  3. function show - menampilkan detail data user.
  4. function update - melakukan proses update data user.
  5. function destroy - mengahapus data user.

function index

Method ini akan kita gunakan untuk menampilkan list data users dari database melalui Model. Dan disini kita juga akan membuat sebuah kondisi untuk pencarian data menggunakan method when.

//get users
$users = User::when(request()->q, function($users) {
   $users = $users->where('name', 'like', '%'. request()->q . '%');
})->latest()->paginate(5);

Jadi, jika ada sebuah request dengan nama q, maka kita akan menjalankan fungsi untuk pencarian data ke dalam table users berdasarkan nama.

Kemudian, kita urutkan datanya berdasarkan yang paling terbaru menggunakan method latest dan membatas data yang ditampilkan perhalaman menggunakan method paginate. Setelah itu, kita akan ubah datanya menjadi format JSON menggunakan UserResource.

//return with Api Resource
return new UserResource(true, 'List Data Users', $users);

function store

Method ini akan digunakan untuk proses insert data baru ke dalam database. Dimana sebelum data akan di insert kita akan menambahkan sebuah validasi terlebih dahulu. Tujuannya untuk memastikan data tersebut sudah sesuai atau belum.

$validator = Validator::make($request->all(), [
    'name'     => 'required',
    'email'    => 'required|unique:users',
    'password' => 'required|confirmed' 
]);

Dari penambahan validasi di atas, kurang lebih penjelassannya seperti berikut ini :

KEY VALIDATION DESCRIPTION
name required field wajib diisi.
email required field wajib diisi.
unique:users field bersifat unik dan tidak boleh ada yang sama di dalam table users.
password required field wajib diisi.
confirmed field wajib sama dengan isi password.

Jika data yang dikirim belum sesuai dengan ketentuan validasi di atas, maka kita akan melakukan return menggunakan format JSON yang berisi informasi error validasi.

if ($validator->fails()) {
  return response()->json($validator->errors(), 422);
}

Tapi, jika data tersebut sudah sesuai maka kita akan melakukan proses insert menggunkan Eloquent.

//create user
$user = User::create([
    'name'      => $request->name,
    'email'     => $request->email,
    'password'  => bcrypt($request->password)
]);

Jika proses insert data di atas berhasil, maka kita akan return menggunakan UserResource.

//return success with Api Resource
return new UserResource(true, 'Data User Berhasil Disimpan!', $user);

Tapi, jika proses insert data gagal dilakukan, maka kita akan return menggunakan UserResource dengan status success false.

//return failed with Api Resource
return new UserResource(false, 'Data User Gagal Disimpan!', null);

function show

Method ini akan digunakan untuk menampilkan detail data user berdasarkan ID. Disini kita menggunakan Eloquent untuk mencari data tersebut.

$user = User::whereId($id)->first();

Di atas, kita menjadi data user berdasarkan ID dan kita gunakan method first untuk mendapatkan object dari data tersebut.

Jika data user ditemukan, maka kita akanr return menggunakan UserResource dengan status success true.

//return success with Api Resource
return new UserResource(true, 'Detail Data User!', $user);

Tapi, jika data user tidak ditemukan, maka kita akan melakukan return menggunakan UserResource dengan status success false.

//return failed with Api Resource
return new UserResource(false, 'Detail Data User Tidak DItemukan!', null);

function update

Method ini digunakan untuk melakukan proses update data ke dalam database. Sebelum itu kita juga akan melakukan proses valiasi untuk memastikan data yang akan diupdate sudah sesuai dengan yang diharapkan.

$validator = Validator::make($request->all(), [
    'name'     => 'required',
    'email'    => 'required|unique:users,email,'.$user->id,
    'password' => 'confirmed'
]);

Dari deklarasi validasi di atas, kurang lebih seperti berikut ini penjelasannya.

KEY VALIDATION DESCRIPTION
name required field wajib diisi.
email required field wajib diisi.
unique:users,email,'.$user->id field bersifat unik dan tidak boleh ada yang sama di dalam table users. Karena bersifat unik, maka untuk proses update kita tambahkan email,'.$user->id, yang artinya kusus ID category yang diupdate akan dikecualikan.
password confirmed field wajib sama dengan isi password.

Jika data yang akan diupdate belum sesuai dengan validasi di atas, maka kita akan melakukan return menggunakan JSON dengan informasi error validasi.

if ($validator->fails()) {
    return response()->json($validator->errors(), 422);
}

Tapi jika data sudah sesuai, maka kita akan lakukan proses update data. Tapi disini kita akan membuat kondisi lagi untuk memastikan apakah kita akan mengupdate data beserta password atau tidak.

if($request->password == "") {

	//...

}

Jika request dengan nama password tidak memiliki value, artinya kita akan melakukan update data tanpa mengubah password yang lama.

//update user without password
$user->update([
    'name'      => $request->name,
    'email'     => $request->email,
]);

Tapi, kalau request dengan nama password memiliki value, maka kita akan melakukan update data user beserta password-nya.

//update user with new password
$user->update([
    'name'      => $request->name,
    'email'     => $request->email,
    'password'  => bcrypt($request->password)
]);

Jika proses update data user di atas berhasil, maka kita akan return menggunakan UserResource.

//return success with Api Resource
return new UserResource(true, 'Data User Berhasil Diupdate!', $user);

Tapi jika proses update data gagal dilakukan, maka kita akan return menggunakan UserResource dengan status success false.

//return failed with Api Resource
return new UserResource(false, 'Data User Gagal Diupdate!', null);

function destroy

Method ini akan digunakan untuk proses menghapus data dari database. Disini untuk proses hapus data kita mengunakan Eloquent dengan method delete.

$user->delete()

Jika data user behasil dihapus, maka kita akan return mengunakan UserResource dengan status success true.

//return success with Api Resource
return new UserResource(true, 'Data User Berhasil Dihapus!', null);

Tapi jika data user gagal dihapus, maka akan return menggunakan UserResource dengan status success false.

//return failed with Api Resource
return new UserResource(false, 'Data User Gagal Dihapus!', null);

Langkah 3 - Menambahkan Route API Users

Setelah berhasil membuat controller beserta method-method di dalamnya, maka sekarang kita akan lanjutkan membuat route agar controller kita dapat diakses melalui web browser.

Silahkan buka file routes/api.php, kemudian tambahkan route berikut ini di dalam prefix admin dan group middleware auth:api, tepatnya di bawah route /sliders.

//users resource
Route::apiResource('/users', App\Http\Controllers\Api\Admin\UserController::class, ['except' => ['create', 'edit'], 'as' => 'admin']);

Untuk memastikan route berhasil di tambahkan, silahkan jalankan perintah berkut ini di dalam terminal/CMD dan pastikan berada di dalam project Laravel.

php artisan route:list

Langkah 4 - Uji Coba API Users

Sekarang kita lanjutkan untuk melakukan uji coba dari setiap method yang sudah kita buat di atas. Disini kita akan melakukan uji coba di 5 method yang ada di dalam controller UserController.

Uji Coba Method Index

Pertama kita akan melakukan proses uji coba untuk method index, silahkan buka aplikasi Postman kemudian masukkan URL berikut ini http://localhost:8000/api/admin/users dan untuk method-nya silahkan pilih GET.

Selanjutnya silahkan klik tab Headers kemudian masukkan key dan value berikut ini :

KEY VALUE
Accept application/json
Content-Type application/json
Authorization Bearer <spasi> Token

Jika sudah, silahkan klik Send dan jika berhasil maka kita akan mendapatkan sebuah response dalam format JSON yang berisi informasi data users.

Uji Coba Method Store

Sekarang kita lanjutkan untuk melakukan proses uji coba insert data ke dalam database. Silahkan buka aplikasi Postman dan masukkan URL berikut ini http://localhost:8000/api/admin/users dan untuk method-nya silahkan pilih POST.

Selanjutnya silahkan klik tab Headers kemudian masukkan key dan value berikut ini :

KEY VALUE
Accept application/json
Content-Type application/json
Authorization Bearer <spasi> Token JWT

Setelah itu silahkan klik tab Body dan pilih form-data kemudian masukkan key dan value berikut ini :

KEY TYPE VALUE
name text Silahkan isi dengan nama User yang diinginan.
email text Silahkan isi dengan email User yang diinginan.
password text Silahkan isi dengan password User yang diinginan.
password_confirmation text Silahkan isi dengan password User yang diinginan.

Jika sudah, silahkan klik Send dan jika berhasil maka kita akan mendapatkan sebuah response dalam format JSON yang berisi informasi data user yang baru saja di insert.

Uji Coba Method Show

Setelah berhasil melakukan proses insert data user ke dalam database, sekarang kita lanjutkan untuk menampilkaan detail dari user tersebut. Silahkan buka aplikasi Postman dan masukkan URL berikut ini http://localhost:8000/api/admin/users/3 dan untuk method-nya silahkan pilih GET.

Selanjutnya silahkan klik tab Headers kemudian masukkan key dan value berikut ini :

KEY VALUE
Accept application/json
Content-Type application/json
Authorization Bearer <spasi> Token JWT

Jika sudah, silahkan klik Send dan jika berhasil maka kita akan mendapatkan sebuah response dalam format JSON yang berisi informasi detail data user.

Uji Coba Method Update

Sekarang kita lanjutkan untuk uji coba proses update data user ke dalam database. Silahkan buka aplikasi Postman dan masukkan URL berikut ini http://localhost:8000/api/admin/users/3 dan untuk method-nya silahkan pilih POST.

Selanjutnya silahkan klik tab Headers kemudian masukkan key dan value berikut ini :

KEY VALUE
Accept application/json
Content-Type application/json
Authorization Bearer <spasi> Token JWT

Setelah itu klik tab Body dan pilih form-data kemudian masukkan key dan value seperti berikut ini :

KEY TYPE VALUE
name text Silahkan isi dengan nama User yang diinginan.
email text Silahkan diisi dengan email User yang diinginkan.
_method text PATCH

Jika sudah, silahkan klik Send dan jika berhasil maka kita akan mendapatkan sebuah response dalam format JSON yang berisi informasi tentang data user yang diupdate.

Uji Coba Method Destroy

Sekarang kita lanjutkan untuk melakukan proses hapus data, silahkan buka aplikasi Postman kemudian masukkan URL berikut ini http://localhost:8000/api/admin/users/3 dan untuk method-nya silahkan pilih DELETE.

Selanjutnya silahkan klik tab Headers kemudian masukkan key dan value berikut ini :

KEY VALUE
Accept application/json
Content-Type application/json
Authorization Bearer <spasi> Token JWT

Jika sudah, silahkan klik Send dan jika berhasil maka kita akan mendapatkan sebuah response dalam format JSON yang berisi informasi data user telah berhasil dihapus.

Beranda Mundur Maju