Installation:
composer require rpvirtual/laravel-api-module
Laravel’s Package Discovery will auto-register the service provider. If not, manually add it to config/app.php.
Publish Configuration (Optional):
php artisan vendor:publish --provider="Rpvirtual\LaravelApiModule\LaravelApiModuleServiceProvider" --tag="config"
This generates config/moduleapi.php for customization (e.g., default namespace, storage paths).
Generate Your First Module:
php artisan moduleapi:make User
This creates a skeleton module in app/Modules/User/ with:
Http/Controllers/ (API controllers)Database/Migrations/ (module-specific migrations)Providers/ (module service provider)Resources/ (translations, configs)Routes/api.php (module routes)Register the Module:
Add the module’s provider to config/app.php under providers:
Rpvirtual\LaravelApiModule\Modules\User\Providers\UserModuleServiceProvider::class,
Or use the moduleapi:register command:
php artisan moduleapi:register User
Run Migrations:
php artisan migrate
The module’s migrations will execute alongside your app’s.
Test the API:
The module auto-registers routes under /api/user/.... Test with:
php artisan route:list | grep user
PascalCase for module names (e.g., User, Product).app/Modules/{ModuleName}/
├── Http/
│ ├── Controllers/ # API controllers (e.g., UserController)
│ ├── Middleware/ # Module-specific middleware
│ └── Resources/ # Request/Response transformers
├── Database/
│ └── Migrations/ # Module migrations
├── Providers/
│ └── {ModuleName}ModuleServiceProvider.php # Registers routes, configs, etc.
├── Resources/
│ ├── lang/ # Translations
│ ├── views/ # (Optional) If extending to include views later
│ └── configs/ # Module-specific configs
└── Routes/
└── api.php # Module routes
app/Modules/ for valid modules on boot.{Module}/Routes/api.php:
Route::prefix('users')->group(function () {
Route::get('/', [UserController::class, 'index']);
Route::post('/', [UserController::class, 'store']);
});
/api prefix in config/moduleapi.php:
'route_prefix' => 'v1',
spatie/laravel-api for versioned modules.Rpvirtual\LaravelApiModule\Http\Controllers\ApiController for shared logic (e.g., API responses, auth).
namespace App\Modules\User\Http\Controllers;
use Rpvirtual\LaravelApiModule\Http\Controllers\ApiController;
class UserController extends ApiController
{
public function index()
{
return $this->successResponse(User::all());
}
}
FormRequest in {Module}/Http/Controllers/:
use App\Modules\User\Http\Requests\StoreUserRequest;
public function store(StoreUserRequest $request)
{
// Validated data: $request->validated()
}
{Module}/Database/Migrations/.Schema::create() or create:module command:
php artisan make:migration create_users_table --module=user
{Module}/Database/Seeders/ and register them in the module provider.{Module}/Providers/{Module}ModuleServiceProvider.php:
public function register()
{
$this->registerRoutes();
$this->registerConfigs();
$this->registerBindings();
}
protected function registerRoutes()
{
Route::module('user', function () {
require __DIR__.'/../../Routes/api.php';
});
}
php artisan vendor:publish --tag="moduleapi-config" --module=user
{Module}/Resources/lang/ and load them in the provider:
public function boot()
{
$this->loadTranslationsFrom(__DIR__.'/../../Resources/lang', 'user');
}
{Module}/Http/Middleware/ and register it in the module provider:
protected function registerMiddleware()
{
$this->app['router']->moduleMiddleware('user', function ($router) {
$router->aliasMiddleware('user.auth', \App\Modules\User\Http\Middleware\Authenticate::class);
});
}
{Module}/Routes/api.php:
Route::middleware(['user.auth'])->group(function () {
// Protected routes
});
public function test_user_module()
{
$response = $this->getJson('/api/users');
$response->assertStatus(200);
}
ModuleTestCase (if provided) or extend PHPUnit\Framework\TestCase with module-specific setup.API Documentation:
routes/api.php to include OpenAPI annotations.Route::get('/users', [UserController::class, 'index'])
->middleware('auth:api')
->name('users.index')
->middleware('swagger.document');
Authentication:
Route::middleware('auth:api')->group(function () {
// Authenticated routes
});
Event Handling:
// In UserController
event(new UserCreated($user));
// In UserModuleServiceProvider
public function boot()
{
event(new UserCreated());
}
Caching:
ApiController helpers:
return $this->cachedResponse(60, function () {
return User::all();
});
Rate Limiting:
app/Http/Kernel.php:
'api' => [
\App\Modules\User\Http\Middleware\LimitRequests::class,
// Other middleware
],
Logging:
config/moduleapi.php:
'log_channel' => 'user',
config/logging.php.Queues & Jobs:
// In UserController
dispatch(new SendUserWelcomeEmail($user))->onQueue('user-queue');
config/moduleapi.php:
'queue_connection' => 'user-connection',
API Resources:
ApiResource for consistent JSON responses. Place resources in {Module}/Http/Resources/:
namespace App\Modules\User\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class UserResource extends JsonResource
{
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
];
}
}
return UserResource::collection(User::all());
How can I help you explore Laravel packages today?