buat model dan migration
php artisan make:model NamaModel -m
buat folder app/Interfaces
buat folder app/Repositories
buat provider
php artisan make:provider RepositoryServiceProvider
buat file app/Interfaces/NamaRepositoryInterface.php
buat file app/Repositories/NamaRepository.php
buat register app/Providers/RepositoryServiceProvider.php
buat controller
php artisan make:controller NamaController --api
buat resource
php artisan make:resource NamaResource
buat app/Http/Resources/PaginatedResource.php
buat app/route/api
buat factory
php artisan make:factory NamaFactory
buat seeder
php artisan make:seed NamaSeeder
buat data
php artisan db:seed NamaSeeder
buat request
php artisan make:request NamaStoreRequest
php artisan make:request NamaUpdateRequest
buat bahasa
php artisan lang:publish
buat bahasa indinesia lang/id/validation.php
buat permission
buat folder dan file app/Traits/UUID.php
<?php
namespace App\Traits;
use Illuminate\Support\Str;
trait UUID
{
protected static function boot()
{
parent::boot();
static::creating(function ($model) {
if ($model->getKey() === null) {
$model->setAttribute($model->getKeyName(), Str::uuid()->toString());
}
});
}
public function getIncrementing()
{
return false;
}
public function getKeyType()
{
return 'String';
}
}
buat folder dan file app/Helpers/ResponseHelper.php
<?php
/**
* supaya response dari api nya tidak berantakan
* agar sesuai dengan ini
*/
namespace App\Helpers;
use Illuminate\Http\JsonResponse;
class ResponseHelper
{
public static function jsonResponse($success, $message, $data, $statusCode): JsonResponse
{
return response()->json([
'success' => $success,
'message' => $message,
'data' => $data,
], $statusCode);
}
}
Pasang api
php artisan install:api
php artisan make:model PersonalAccessToken
edit app/Models/PersonalAccessToken.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Support\Str;
use Laravel\Sanctum\PersonalAccessToken as SanctumPersonalAccessToken;
class PersonalAccessToken extends SanctumPersonalAccessToken
{
use HasFactory;
// public $keyType = 'string';
// public $incrementing = false;
// public static function boot()
// {
// parent::boot();
// static::creating(function ($model) {
// $model->id = (string) Str::uuid();
// });
// }
// }
protected $primaryKey = 'uuid'; // 👈 kasih tahu primary key
public $incrementing = false;
protected $keyType = 'string';
protected static function boot()
{
parent::boot();
static::creating(function ($model) {
if (empty($model->uuid)) {
$model->uuid = (string) Str::uuid();
}
});
}
}
edit app/Providers/AppServiceProvider.php
<?php
namespace App\Providers;
use App\Models\PersonalAccessToken;
use Illuminate\Support\ServiceProvider;
use Laravel\Sanctum\Sanctum;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*/
public function register(): void
{
//
}
/**
* Bootstrap any application services.
*/
public function boot(): void
{
//
Sanctum::usePersonalAccessTokenModel(PersonalAccessToken::class);
}
}
edit database/migrations/2025_09_17_131012_create_personal_access_tokens_table.php
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('personal_access_tokens', function (Blueprint $table) {
$table->uuid()->primary(); // ubah menjadi uuid dan primary
$table->uuidMorphs('tokenable'); // ubah menjadi uuid
$table->text('name');
$table->string('token', 64)->unique();
$table->text('abilities')->nullable();
$table->timestamp('last_used_at')->nullable();
$table->timestamp('expires_at')->nullable()->index();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('personal_access_tokens');
}
};
Pasang spatie/laravel-permission
composer require spatie/laravel-permission
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider"
edit bootstrap/providers.php
<?php
return [
App\Providers\AppServiceProvider::class,
Spatie\Permission\PermissionServiceProvider::class, // Tambahkan
];
edit bootstrap/app.php
<?php
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__ . '/../routes/web.php',
api: __DIR__ . '/../routes/api.php',
commands: __DIR__ . '/../routes/console.php',
health: '/up',
)
->withMiddleware(function (Middleware $middleware): void {
// Tambahkan ==================================
$middleware->alias([
'role' => \Spatie\Permission\Middleware\RoleMiddleware::class,
'permission' => \Spatie\Permission\Middleware\PermissionMiddleware::class,
'role_or_permission' => \Spatie\Permission\Middleware\RoleOrPermissionMiddleware::class,
]);
// ===========================================
})
->withExceptions(function (Exceptions $exceptions): void {
//
})->create();
buat PermissionSeeder
php artisan make:seeder PermissionSeeder
edit semua database/seeders/PermissionSeeder.php dengan
<?php
namespace Database\Seeders;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use Spatie\Permission\Models\Permission;
class PermissionSeeder extends Seeder
{
private $permissions = [
'dashboard' => [
'menu'
],
'head-of-family' => [
'menu',
'list',
'create',
'edit',
'delete'
],
'family-member' => [
'menu',
'list',
'create',
'edit',
'delete'
],
'social-assistance' => [
'menu',
'list',
'create',
'edit',
'delete'
],
'social-assistance-recipient' => [
'menu',
'list',
'create',
'edit',
'delete'
],
'event' => [
'menu',
'list',
'create',
'edit',
'delete'
],
'event-participant' => [
'menu',
'list',
'create',
'edit',
'delete'
],
'development' => [
'menu',
'list',
'create',
'edit',
'delete'
],
'development-applicant' => [
'menu',
'list',
'create',
'edit',
'delete'
],
'profile' => [
'menu',
'create',
'edit',
],
];
/**
* Run the database seeds.
*/
public function run(): void
{
foreach ($this->permissions as $key => $value) {
foreach ($value as $permission) {
Permission::firstOrCreate([
'name' => $key . '-' . $permission,
'guard_name' => 'sanctum'
]);
}
}
}
}
edit database/migrations/2025_09_04_105112_create_permission_tables.php , ganti semua supaya gampang ,jika menggunakan uuid ,jika tidak abaikan step ini
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
$teams = config('permission.teams');
$tableNames = config('permission.table_names');
$columnNames = config('permission.column_names');
$pivotRole = $columnNames['role_pivot_key'] ?? 'role_id';
$pivotPermission = $columnNames['permission_pivot_key'] ?? 'permission_id';
if (empty($tableNames)) {
throw new \Exception('Error: config/permission.php not loaded. Run [php artisan config:clear] and try again.');
}
if ($teams && empty($columnNames['team_foreign_key'] ?? null)) {
throw new \Exception('Error: team_foreign_key on config/permission.php not loaded. Run [php artisan config:clear] and try again.');
}
Schema::create($tableNames['permissions'], function (Blueprint $table) {
$table->bigIncrements('id'); // permission id
$table->string('name'); // For MySQL 8.0 use string('name', 125);
$table->string('guard_name'); // For MySQL 8.0 use string('guard_name', 125);
$table->timestamps();
$table->unique(['name', 'guard_name']);
});
Schema::create($tableNames['roles'], function (Blueprint $table) use ($teams, $columnNames) {
$table->bigIncrements('id'); // role id
if ($teams || config('permission.testing')) { // permission.testing is a fix for sqlite testing
$table->unsignedBigInteger($columnNames['team_foreign_key'])->nullable();
$table->index($columnNames['team_foreign_key'], 'roles_team_foreign_key_index');
}
$table->string('name'); // For MySQL 8.0 use string('name', 125);
$table->string('guard_name'); // For MySQL 8.0 use string('guard_name', 125);
$table->timestamps();
if ($teams || config('permission.testing')) {
$table->unique([$columnNames['team_foreign_key'], 'name', 'guard_name']);
} else {
$table->unique(['name', 'guard_name']);
}
});
Schema::create($tableNames['model_has_permissions'], function (Blueprint $table) use ($tableNames, $columnNames, $pivotPermission, $teams) {
$table->unsignedBigInteger($pivotPermission);
$table->string('model_type');
$table->uuid($columnNames['model_morph_key']);
$table->index([$columnNames['model_morph_key'], 'model_type'], 'model_has_permissions_model_id_model_type_index');
$table->foreign($pivotPermission)
->references('id') // permission id
->on($tableNames['permissions'])
->onDelete('cascade');
if ($teams) {
$table->unsignedBigInteger($columnNames['team_foreign_key']);
$table->index($columnNames['team_foreign_key'], 'model_has_permissions_team_foreign_key_index');
$table->primary(
[$columnNames['team_foreign_key'], $pivotPermission, $columnNames['model_morph_key'], 'model_type'],
'model_has_permissions_permission_model_type_primary'
);
} else {
$table->primary(
[$pivotPermission, $columnNames['model_morph_key'], 'model_type'],
'model_has_permissions_permission_model_type_primary'
);
}
});
Schema::create($tableNames['model_has_roles'], function (Blueprint $table) use ($tableNames, $columnNames, $pivotRole, $teams) {
$table->unsignedBigInteger($pivotRole);
$table->string('model_type');
$table->uuid($columnNames['model_morph_key']);
$table->index([$columnNames['model_morph_key'], 'model_type'], 'model_has_roles_model_id_model_type_index');
$table->foreign($pivotRole)
->references('id') // role id
->on($tableNames['roles'])
->onDelete('cascade');
if ($teams) {
$table->unsignedBigInteger($columnNames['team_foreign_key']);
$table->index($columnNames['team_foreign_key'], 'model_has_roles_team_foreign_key_index');
$table->primary(
[$columnNames['team_foreign_key'], $pivotRole, $columnNames['model_morph_key'], 'model_type'],
'model_has_roles_role_model_type_primary'
);
} else {
$table->primary(
[$pivotRole, $columnNames['model_morph_key'], 'model_type'],
'model_has_roles_role_model_type_primary'
);
}
});
Schema::create($tableNames['role_has_permissions'], function (Blueprint $table) use ($tableNames, $pivotRole, $pivotPermission) {
$table->unsignedBigInteger($pivotPermission);
$table->unsignedBigInteger($pivotRole);
$table->foreign($pivotPermission)
->references('id') // permission id
->on($tableNames['permissions'])
->onDelete('cascade');
$table->foreign($pivotRole)
->references('id') // role id
->on($tableNames['roles'])
->onDelete('cascade');
$table->primary([$pivotPermission, $pivotRole], 'role_has_permissions_permission_id_role_id_primary');
});
app('cache')
->store(config('permission.cache.store') != 'default' ? config('permission.cache.store') : null)
->forget(config('permission.cache.key'));
}
/**
* Reverse the migrations.
*/
public function down(): void
{
$tableNames = config('permission.table_names');
if (empty($tableNames)) {
throw new \Exception('Error: config/permission.php not found and defaults could not be merged. Please publish the package configuration before proceeding, or drop the tables manually.');
}
Schema::drop($tableNames['role_has_permissions']);
Schema::drop($tableNames['model_has_roles']);
Schema::drop($tableNames['model_has_permissions']);
Schema::drop($tableNames['roles']);
Schema::drop($tableNames['permissions']);
}
};
buat RoleSeeder
php artisan make:seeder RoleSeeder
edit database/seeders/RoleSeeder.php
<?php
namespace Database\Seeders;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use Spatie\Permission\Models\Permission;
use Spatie\Permission\Models\Role;
class RoleSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
Role::firstOrCreate([
'name' => 'admin',
'guard_name' => 'sanctum'
])->givePermissionTo(Permission::all());
Role::firstOrCreate([
'name' => 'head-of-family',
'guard_name' => 'sanctum'
])->givePermissionTo([
'dashboard-menu',
'family-member-menu',
'family-member-list',
'family-member-create',
'family-member-edit',
'family-member-delete',
'social-assistance-menu',
'social-assistance-list',
'social-assistance-recipient-menu',
'social-assistance-recipient-list',
'social-assistance-recipient-create',
'social-assistance-recipient-edit',
'social-assistance-recipient-delete',
'event-menu',
'event-list',
'event-participant-menu',
'event-participant-list',
'event-participant-create',
'event-participant-edit',
'event-participant-delete',
'development-menu',
'development-list',
'development-applicant-menu',
'development-applicant-list',
'development-applicant-create',
'development-applicant-edit',
'development-applicant-delete',
'profile-menu',
]);
}
}
edit config/auth.php
<?php
return [
/*
|--------------------------------------------------------------------------
| Authentication Defaults
|--------------------------------------------------------------------------
|
| This option defines the default authentication "guard" and password
| reset "broker" for your application. You may change these values
| as required, but they're a perfect start for most applications.
|
*/
'defaults' => [
'guard' => env('AUTH_GUARD', 'sanctum'), // edit dari web menjadi sanctum
'passwords' => env('AUTH_PASSWORD_BROKER', 'users'),
],
/*
|--------------------------------------------------------------------------
| Authentication Guards
|--------------------------------------------------------------------------
|
| Next, you may define every authentication guard for your application.
| Of course, a great default configuration has been defined for you
| which utilizes session storage plus the Eloquent user provider.
|
| All authentication guards have a user provider, which defines how the
| users are actually retrieved out of your database or other storage
| system used by the application. Typically, Eloquent is utilized.
|
| Supported: "session"
|
*/
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
// Tambahan ======================
'api' => [
'driver' => 'sanctum',
'provider' => 'users',
'hash' => 'false',
],
'sanctum' => [
'driver' => 'sanctum',
'provider' => 'users',
'hash' => 'false',
],
// =================================
],
buat app/Interfaces/AuthRepositoryInterface.php
<?php
/**
* definisikan fungsi fungsi yang akan kita buat
*/
namespace App\Interfaces;
interface AuthRepositoryInterface
{
public function login(
array $data
);
public function logout();
public function me();
}
buat app/Repositories/AuthRepository.php
<?php
namespace App\repositories;
use App\Http\Resources\HeadOfFamilyResource;
use App\Interfaces\AuthRepositoryInterface;
use App\Models\Event;
use Exception;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
class AuthRepository implements AuthRepositoryInterface
{
public function login(array $data)
{
if (!Auth::guard('web')->attempt($data)) {
return response([
'success' => false,
'message' => 'Unauthorized',
], 401);
}
$user = Auth::user();
$token = $user->createToken('auth_token')->plainTextToken;
return response()->json([
'success' => true,
'token' => $token,
'message' => "Login Success"
]);
}
public function logout()
{
$user = Auth::user();
$user->currentAccessToken()->delete();
$response = [
'success' => true,
'message' => "Logout Success"
];
return response($response, 200);
}
public function me()
{
if (Auth::check()) {
$user = Auth::user();
$user->load('roles.permissions');
$permissions = $user->roles->flatMap->permissions->pluck('name');
$role = $user->roles->first()->name;
return response()->json([
'message' => 'User data',
'data' => [
'id' => $user->id,
'name' => $user->name,
'email' => $user->email,
'permissions' => $permissions,
'role' => $role,
// 'head_of_family' => new HeadOfFamilyResource($user->headOfFamily)
'head_of_family' => $user->headOfFamily
? new HeadOfFamilyResource($user->headOfFamily)
: null,
],
]);
}
return response()->json([
'message' => 'You are not logged in'
], 401);
}
}
buat AuthController
php artisan make:controller AuthController
edit AuthController.php
<?php
namespace App\Http\Controllers;
use App\Http\Requests\LoginStoreRequest;
use App\Interfaces\AuthRepositoryInterface;
use Illuminate\Http\Request;
class AuthController extends Controller
{
private AuthRepositoryInterface $authRepository;
public function __construct(AuthRepositoryInterface $authRepository)
{
$this->authRepository = $authRepository;
}
public function login(LoginStoreRequest $request)
{
$request = $request->validated();
return $this->authRepository->login($request);
}
public function logout()
{
return $this->authRepository->logout();
}
public function me()
{
return $this->authRepository->me();
}
}
buat request LoginStoreRequest
php artisan make:request LoginStoreRequest
edit app/Http/Requests/LoginStoreRequest.php
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class LoginStoreRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'email' => 'required|email',
'password' => 'required'
];
}
public function attributes()
{
return [
'email' => 'Email',
'password' => 'Kata Sandi'
];
}
}
edit Models/User.php
<?php
namespace App\Models;
// use Illuminate\Contracts\Auth\MustVerifyEmail;
use App\Traits\UUID;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
use Spatie\Permission\Traits\HasRoles;
class User extends Authenticatable
{
/** @use HasFactory<\Database\Factories\UserFactory> */
use HasFactory, Notifiable, UUID, SoftDeletes, HasRoles, HasApiTokens;
/**
* 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',
];
}
public function scopeSearch($query, $search)
{
return $query->where('name', 'like', '%' . $search . '%')
->orWhere('email', 'like', '%' . $search . '%');
}
// satu user hanya memiliki 1 head family
public function headOfFamily()
{
return $this->hasOne(HeadOfFamily::class);
}
}
buat UserRepositoryInterface.php
<?php
/**
* definisikan fungsi fungsi yang akan kita buat
*/
namespace App\Interfaces;
interface UserRepositoryInterface
{
public function getAll(
?string $search, // ketika search langsung di terima di fungsi getall
?int $limit, // kita bisa melimit data yang ingin di tampilkan
bool $execute // akan exe langsung ,tapi di paginasi tidak
);
public function getAllPaginated(
?string $search, // ketika search langsung di terima di fungsi getall
?int $rowPerPage, // kita bisa melimit data yang ingin di tampilkan
);
public function getById(
string $id
);
public function create(
array $data
);
public function update(
string $id,
array $data
);
public function delete(
string $id
);
}
buat UserRepository.php
<?php
namespace App\repositories;
use App\Interfaces\UserRepositoryInterface;
use App\Models\User;
use Exception;
use Illuminate\Support\Facades\DB;
class UserRepository implements UserRepositoryInterface
{
public function getAll(?string $search, ?int $limit, bool $execute)
{
$query = User::where(function ($query) use ($search) {
//jika ada parameter search dia akan melakukan search, yang kita definisikan pada model user
if ($search) {
$query->search($search);
}
});
if ($limit) {
// take adalah mengambil beberapa berdsarkan limit
$query->take($limit);
}
if ($execute) {
return $query->get();
}
return $query;
}
public function getAllPaginated(?string $search, ?int $rowPerPage)
{
$query = $this->getAll(
$search,
$rowPerPage,
false
);
return $query->paginate($rowPerPage);
}
public function getById(string $id)
{
$query = User::where('id', $id);
return $query->first();
}
public function create(array $data)
{
// jika ada data yang salah tidak akan langsung di dinput
DB::beginTransaction();
try {
$user = new User;
$user->name = $data['name'];
$user->email = $data['email'];
$user->password = bcrypt($data['password']);
$user->save();
DB::commit();
return $user;
} catch (\Exception $e) {
DB::rollBack();
throw new Exception($e->getMessage());
}
}
public function update(string $id, array $data)
{
// jika ada data yang salah tidak akan langsung di dinput
DB::beginTransaction();
try {
$user = User::find($id);
$user->name = $data['name'];
// $user->email = $data['email'];
if (isset($data['password'])) {
$user->password = bcrypt($data['password']);
}
$user->save();
DB::commit();
return $user;
} catch (\Exception $e) {
DB::rollBack();
throw new Exception($e->getMessage());
}
}
public function delete(string $id)
{
// jika ada data yang salah tidak akan langsung di dinput
DB::beginTransaction();
try {
$user = User::find($id);
$user->delete();
DB::commit();
return $user;
} catch (\Exception $e) {
DB::rollBack();
throw new Exception($e->getMessage());
}
}
}
register di RepositoryServiceProvider.php
<?php
/**
* di gunakan untuk mendaftarkan repositories dan interfaces
*/
namespace App\Providers;
use App\Interfaces\AuthRepositoryInterface;
use App\Interfaces\DashboardRepositoryInterface;
use App\Interfaces\DevelopmentApplicantRepositoryInterface;
use App\Interfaces\DevelopmentRepositoryInterface;
use App\Interfaces\EventParticipantRepositoryInterface;
use App\Interfaces\EventRepositoryInterface;
use App\Interfaces\FamilyMemberRepositoryInterface;
use App\Interfaces\HeadOfFamilyRepositoryInterface;
use App\Interfaces\ProfileRepositoryInterface;
use App\Interfaces\SocialAssistanceRecipientRepositoryInterface;
use App\Interfaces\SocialAssistanceRepositoryInterface;
use App\Interfaces\UserRepositoryInterface;
use App\repositories\AuthRepository;
use App\repositories\DashboardRepository;
use App\repositories\DevelopmentApplicantRepository;
use App\repositories\DevelopmentRepository;
use App\repositories\EventParticipantRepository;
use App\repositories\EventRepository;
use App\repositories\FamilyMemberRepository;
use App\repositories\HeadOfFamilyRepository;
use App\repositories\ProfileRepository;
use App\repositories\SocialAssistanceRecipientRepository;
use App\repositories\SocialAssistanceRepository;
use App\repositories\UserRepository;
use Illuminate\Support\ServiceProvider;
class RepositoryServiceProvider extends ServiceProvider
{
/**
* Register services.
*/
public function register(): void
{
//
$this->app->bind(UserRepositoryInterface::class, UserRepository::class);
$this->app->bind(HeadOfFamilyRepositoryInterface::class, HeadOfFamilyRepository::class);
$this->app->bind(FamilyMemberRepositoryInterface::class, FamilyMemberRepository::class);
$this->app->bind(SocialAssistanceRepositoryInterface::class, SocialAssistanceRepository::class);
$this->app->bind(SocialAssistanceRecipientRepositoryInterface::class, SocialAssistanceRecipientRepository::class);
$this->app->bind(EventRepositoryInterface::class, EventRepository::class);
$this->app->bind(EventParticipantRepositoryInterface::class, EventParticipantRepository::class);
$this->app->bind(DevelopmentRepositoryInterface::class, DevelopmentRepository::class);
$this->app->bind(DevelopmentApplicantRepositoryInterface::class, DevelopmentApplicantRepository::class);
$this->app->bind(ProfileRepositoryInterface::class, ProfileRepository::class);
$this->app->bind(AuthRepositoryInterface::class, AuthRepository::class);
$this->app->bind(DashboardRepositoryInterface::class, DashboardRepository::class);
}
/**
* Bootstrap services.
*/
public function boot(): void
{
//
}
}
buat UserResource.php
php artisan make:resource UserResource
edit UserResource.php
<?php
/**
* menampilkan apa saja yang kita ingin kana agar json rapih
*/
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class UserResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
// return parent::toArray($request);
return [
'id' => $this->id,
'name' => $this->name,
'email' => $this->email
];
}
}
Buat UserController
php artisan make:controller UserController --api
Edit UserController.php
<?php
namespace App\Http\Controllers;
use App\Helpers\ResponseHelper;
use App\Http\Requests\UserStoreRequest;
use App\Http\Requests\UserUpdateRequest;
use App\Http\Resources\PaginateResource;
use App\Http\Resources\UserResource;
use App\Interfaces\UserRepositoryInterface;
use Illuminate\Http\Request;
class UserController extends Controller
{
private UserRepositoryInterface $userRepository;
public function __construct(UserRepositoryInterface $userRepository)
{
$this->userRepository = $userRepository;
}
/**
* Display a listing of the resource.
*/
public function index(Request $request)
{
//
try {
$users = $this->userRepository->getAll($request->search, $request->limit, true);
return ResponseHelper::jsonResponse(true, 'Data User Berhasil Diambil', UserResource::collection($users), 200);
} catch (\Exception $e) {
return ResponseHelper::jsonResponse(false, $e->getMessage(), null, 500);
}
}
public function getAllPaginated(Request $request)
{
$request = $request->validate([
'search' => 'nullable|string',
'row_per_page' => 'required|integer'
]);
try {
$users = $this->userRepository->getAllPaginated(
$request['search'] ?? null,
$request['row_per_page'],
);
return ResponseHelper::jsonResponse(true, 'Data User Berhasil Diambil', PaginateResource::make($users, UserResource::class), 200);
} catch (\Exception $e) {
return ResponseHelper::jsonResponse(false, $e->getMessage(), null, 500);
}
}
/**
* Store a newly created resource in storage.
*/
public function store(UserStoreRequest $request)
{
$request = $request->validated();
try {
$user = $this->userRepository->create($request);
return ResponseHelper::jsonResponse(true, 'User berhasil ditambahkan', new UserResource($user), 201);
} catch (\Exception $e) {
return ResponseHelper::jsonResponse(false, $e->getMessage(), null, 500);
}
}
/**
* Display the specified resource.
*/
public function show(string $id)
{
try {
$user = $this->userRepository->getById($id);
if (!$user) {
return ResponseHelper::jsonResponse(false, 'User tidak ditemukan', null, 404);
}
return ResponseHelper::jsonResponse(true, 'Detail user berhasil di ambil', new UserResource($user), 200);
} catch (\Exception $e) {
return ResponseHelper::jsonResponse(false, $e->getMessage(), null, 500);
}
}
/**
* Update the specified resource in storage.
*/
public function update(UserUpdateRequest $request, string $id)
{
$request = $request->validated();
try {
$user = $this->userRepository->getById($id);
if (!$user) {
return ResponseHelper::jsonResponse(false, 'User tidak ditemukan', null, 404);
}
$user = $this->userRepository->update(
$id,
$request
);
return ResponseHelper::jsonResponse(true, 'Data user berhasil diupdate', new UserResource($user), 200);
} catch (\Exception $e) {
return ResponseHelper::jsonResponse(false, $e->getMessage(), null, 500);
}
}
/**
* Remove the specified resource from storage.
*/
public function destroy(string $id)
{
try {
$user = $this->userRepository->getById($id);
if (!$user) {
return ResponseHelper::jsonResponse(false, 'User tidak ditemukan', null, 404);
}
$user = $this->userRepository->delete(
$id,
);
return ResponseHelper::jsonResponse(true, 'Data user berhasil dihapus', new UserResource($user), 200);
} catch (\Exception $e) {
return ResponseHelper::jsonResponse(false, $e->getMessage(), null, 500);
}
}
}
buat user store dan update request
php artisan make:request UserStoreRequest
php artisan make:request UserUpdateRequest
edit UserStoreRequest.php
<?php
/**
* untuk validasi
*/
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class UserStoreRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:8'
];
}
public function attributes()
{
return [
'name' => 'Nama',
'email' => 'Email',
'password' => 'Kata Sandi'
];
}
// public function messages()
// {
// return [
// 'required' => ':attribute harus diisi',
// 'string' => ':attribute harus berupa string',
// 'max' => ':attribute maksimal :max karakter',
// 'min' => ':attribute minimal :min karakter',
// 'unique' => ':attribute sudah ada',
// 'email' => ':attribute harus berupa email',
// ];
// }
}
edit UserUpdateRequest.php
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class UserUpdateRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'name' => 'required|string|max:255',
'password' => 'nullable|string|min:8'
];
}
public function attributes()
{
return [
'name' => 'Nama',
'password' => 'Password'
];
}
// public function messages()
// {
// return [
// 'required' => ':attribute harus diisi',
// 'string' => ':attribute harus berupa string',
// 'max' => ':attribute maksimal :max karakter',
// 'min' => ':attribute minimal :min karakter',
// ];
// }
}
buat UserSeeder
php artisan make:seeder UserSeeder
edit UserSeeder.php
<?php
namespace Database\Seeders;
use App\Models\User;
use Database\Factories\UserFactory;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
class UserSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
//
User::create([
'name' => 'Admin',
'email' => 'admin@app.com',
'password' => bcrypt('password')
])->assignRole('admin');
User::create([
'name' => 'Kepala Keluarga',
'email' => 'headoffamily@app.com',
'password' => bcrypt('password')
])->assignRole('head-of-family');
UserFactory::new()->count(15)->create();
}
}
buat PaginateResource.php
edit PaginateResource.php
buat RepositoryServiceProvider.php
edit providers.php
publish lang
php artisan lang:publish
buat lang/id
buat model dan migration HeadOfFamily
php artisan make:model HeadOfFamily -m
php artisan make:interface HeadOfFamilyRepositoryInterface
php artisan make:resource HeadOfFamilyResource
php artisan make:controller HeadOfFamilyController --api
php artisan make:request HeadOfFamilyStoreRequest
php artisan make:request HeadOfFamilyUpdateRequest
php artisan make:factory HeadOfFamilyFactory
php artisan make:seeder HeadOfFamilySeeder
edit
- edit HeadOfFamily.php
- edit 2025_09_01_132434_create_head_of_families_table.php
- edit HeadOfFamilyRepositoryInterface.php
- buat HeadOfFamilyRepository.php
- edit RepositoryServiceProvider.php
- edit HeadOfFamilyResource.php
- edit HeadOfFamilyController.php
- edit HeadOfFamilyStoreRequest.php
- edit HeadOfFamilyUpdateRequest.php
- edit HeadOfFamilyFactory.php
- edit HeadOfFamilySeeder.php
- edit DatabaseSeeder.php
- edit api.php