softigital-dev / core
some of our usefull things that is needed in any laravel project
Requires
- php: ^8.2
- illuminate/support: ^11.0|^12.0
README
A powerful Laravel package for rapid API development with authentication, code generators, and smart middleware.
Streamline your Laravel projects with pre-built authentication components, Google OAuth integration, standardized API responses, and intelligent code generators that follow best practices.
๐ Table of Contents
- Overview
- Requirements
- Installation
- Quick Start Guide
- Commands Reference
- Middleware
- API Response Utility
- Usage Examples
- Configuration
- Testing
- Security
- Contributing
- License
๐ฏ Overview
Softigital Core is designed to eliminate repetitive boilerplate code and accelerate Laravel API development. Install complete authentication systems with a single command, generate well-structured services and routes instantly, and enjoy auto-configured middleware that just works.
Key Features:
- ๐ Complete authentication system (register, login, profile)
- ๐ Google OAuth integration with ID token verification
- ๐ฆ Standardized JSON response formatting
- ๐ก๏ธ Smart middleware (auto-applied JSON responses, optional auth)
- ๐จ Code generators for CRUD, routes, and services
- ๐ Automatic API route structure (v1 versioning)
- โก One-command CRUD generation (model, migration, controller, service, requests, resource, routes)
- โ๏ธ Fully configurable via published config file
๐ Requirements
- PHP: 8.2 or higher
- Laravel: 11.0 or higher
- Laravel Sanctum: For token-based authentication
๐ฆ Installation
Install via Composer:
composer require softigital-dev/core
The service provider registers automatically via Laravel's package auto-discovery.
Optional: Publish Configuration
To customize middleware behavior:
php artisan vendor:publish --tag=softigital-config
This creates config/softigital-core.php for middleware configuration.
๐ Quick Start Guide
1. Install Base Setup (Recommended First Step)
Set up the foundational API structure:
php artisan softigital:install base
What you get:
- routes/v1/api.php structure
- bootstrap/app.php configured for v1 routing
- ApiResponse utility for standardized responses
2. Install Authentication (Optional)
Add a complete authentication system:
php artisan softigital:install auth
What you get:
- Login endpoint (
POST /api/v1/auth/login) - Register endpoint (
POST /api/v1/auth/register) - Profile endpoint (
GET /api/v1/auth/me) - Complete controllers, services, requests, and routes
3. Generate Additional Resources
Create a full CRUD API in seconds:
# Create complete CRUD structure for a model php artisan make:crud Post # Or create individual components: # Create route file with API resource routes php artisan make:route posts --controller=PostController --api # Generate service with repository pattern php artisan make:service Post --model=Post --repository
4. Start Using
Your API is ready! The middleware automatically handles JSON responses.
# Test the registration endpoint curl -X POST http://localhost/api/v1/auth/register \ -H "Content-Type: application/json" \ -d '{"name":"John","email":"john@example.com","password":"secret123"}'
๐ Commands Reference
Installation Commands
softigital:install {type}
Install pre-built authentication components.
Available Types:
| Type | Description | What Gets Installed |
|---|---|---|
base |
Base API setup | routes/v1 structure, bootstrap/app.php config, ApiResponse utility |
auth |
Basic authentication | AuthController, AuthService, LoginRequest, RegisterRequest, routes |
google-auth |
Google OAuth | GoogleAuthController, GoogleLoginRequest, google config, migration, google/apiclient package |
Options:
--force: Overwrite existing files without prompting--skip-migration: Skip migration publishing and execution (google-auth only)--skip-composer: Skip composer package installation
Examples:
# Install base setup (recommended first step) php artisan softigital:install base # Install basic authentication php artisan softigital:install auth # Install Google OAuth with force overwrite php artisan softigital:install google-auth --force # Install without running migrations php artisan softigital:install google-auth --skip-migration # Display help php artisan softigital:install --help
After installing Google auth, configure .env:
GOOGLE_CLIENT_ID=your-client-id-here GOOGLE_CLIENT_SECRET=your-client-secret-here GOOGLE_REDIRECT_URI=your-redirect-uri-here
Generator Commands
make:route {name}
Create a new route file in routes/v1/ with automatic registration.
Options:
--controller=Name: Specify controller and import it--resource: Generate full resourceful routes (index, create, store, show, edit, update, destroy)--api: Generate API resource routes (excludes create, edit)
Examples:
# Basic route file php artisan make:route posts # With controller php artisan make:route posts --controller=PostController # API resource routes (recommended for APIs) php artisan make:route posts --controller=PostController --api # Full resource routes php artisan make:route products --controller=ProductController --resource
Generated file (routes/v1/posts.php):
<?php use Illuminate\Support\Facades\Route; use App\Http\Controllers\PostController; Route::apiResource('posts', PostController::class);
The route file is automatically registered in routes/v1/api.php.
make:service {name}
Generate service classes in app/Services/ with subdirectory support.
Options:
--model=Name: Inject model dependency--repository: Generate CRUD repository pattern methods
Subdirectory Support:
Use /, \, or . notation for nested directories:
# All these work the same: php artisan make:service Auth/Login php artisan make:service Auth\Login php artisan make:service Auth.Login
Examples:
# Basic service php artisan make:service Post # Service with model php artisan make:service Post --model=Post # Full repository pattern with CRUD php artisan make:service Post --model=Post --repository # Organized in subdirectories php artisan make:service Auth/Login --model=User --repository php artisan make:service Blog/Post --repository php artisan make:service Payment/Stripe
Generated structure:
app/Services/
โโโ PostService.php
โโโ Auth/
โ โโโ LoginService.php
โ โโโ RegisterService.php
โโโ Blog/
โโโ PostService.php
make:crud {name}
Generate a complete CRUD structure for a model with all necessary files in one command.
What Gets Generated:
- โ
Model in
app/Models/ - โ
Migration in
database/migrations/ - โ
Service in
app/Services/ - โ
Controller in
app/Http/Controllers/ - โ
Store Request (POST) in
app/Http/Requests/ - โ
Update Request (PATCH) in
app/Http/Requests/ - โ
Resource in
app/Http/Resources/ - โ
Route file in
routes/v1/
Options:
--api-prefix=v1: API version prefix for routes (default: v1)--force: Overwrite existing files without prompting
Examples:
# Generate CRUD for Post model php artisan make:crud Post # Generate with different API version php artisan make:crud Product --api-prefix=v2 # Overwrite existing files php artisan make:crud BlogPost --force
Generated Files for php artisan make:crud Post:
app/
โโโ Models/Post.php (empty - define your fields)
โโโ Services/PostService.php (full CRUD methods)
โโโ Http/
โ โโโ Controllers/PostController.php (complete REST API)
โ โโโ Requests/
โ โ โโโ StorePostRequest.php (empty - add validation rules)
โ โ โโโ UpdatePostRequest.php (empty - add validation rules)
โ โโโ Resources/PostResource.php (empty - define response shape)
database/migrations/2025_xx_xx_xxxxxx_create_posts_table.php (empty)
routes/v1/posts.php (RESTful routes with auth:sanctum)
Generated Controller Methods:
index()- GET /posts (list with pagination)show($id)- GET /posts/{id} (single resource)store(StorePostRequest)- POST /posts (create)update(UpdatePostRequest, $id)- PATCH /posts/{id} (update)destroy($id)- DELETE /posts/{id} (delete)
Generated Routes:
Route::middleware('auth:sanctum')->group(function () { Route::get('posts', [PostController::class, 'index']); Route::get('posts/{id}', [PostController::class, 'show']); Route::post('posts', [PostController::class, 'store']); Route::patch('posts/{id}', [PostController::class, 'update']); Route::delete('posts/{id}', [PostController::class, 'destroy']); });
Next Steps After Generation:
- Define model properties and relationships in
app/Models/Post.php - Add table columns in the migration file and run
php artisan migrate - Define validation rules in
StorePostRequest.phpandUpdatePostRequest.php - Customize the resource fields in
PostResource.php - Register the route file in
routes/api.php:require __DIR__.'/v1/posts.php';
Controller Features:
- Uses service layer for clean separation of concerns
- Returns proper HTTP status codes (200, 201, 404, 500)
- Automatic pagination with metadata for index endpoint
- Uses Resource for consistent response formatting
- Integrates with ApiResponse utility for standardized responses
Generated service with --repository (app/Services/PostService.php):
<?php namespace App\Services; use App\Models\Post; class PostService { public function getAll() { return Post::all(); } public function findById($id) { return Post::findOrFail($id); } public function create(array $data) { return Post::create($data); } public function update($id, array $data) { $post = $this->findById($id); $post->update($data); return $post; } public function delete($id) { $post = $this->findById($id); return $post->delete(); } }
๐ก๏ธ Middleware
The package includes two smart middleware that enhance your API automatically.
Force JSON Response
Ensures all API requests return JSON (no HTML error pages).
Auto-Applied: Automatically applies to all api/* routes.
Configuration (config/softigital-core.php):
'force_json' => [ 'enabled' => true, // Enable/disable middleware 'auto_apply' => true, // Auto-apply to 'api' middleware group ],
What it does:
- Sets
Accept: application/jsonheader for all API routes - Prevents HTML error pages in your API
- Ensures consistent JSON responses for validation errors and exceptions
Disable globally:
// config/softigital-core.php 'force_json' => ['enabled' => false],
Optional Sanctum Authentication
Allows routes to work for both authenticated and guest users.
Alias: auth.optional
Configuration:
'optional_auth' => [ 'enabled' => true, ],
Usage Example:
Route::get('/posts', [PostController::class, 'index']) ->middleware('auth.optional');
In your controller:
public function index(Request $request) { $user = $request->user(); // null if guest, User if authenticated if ($user) { return ApiResponse::success('Your posts', $user->posts); } return ApiResponse::success('Public posts', Post::where('public', true)->get()); }
Use Cases:
- Public feeds with personalized content for logged-in users
- Like/favorite features that work without login
- Content that varies based on authentication status
๐ฆ API Response Utility
The package includes ApiResponse utility for standardized JSON responses.
Available Methods
use App\Utils\ApiResponse; // Success (200) ApiResponse::success('Operation successful', ['key' => 'value']); // Created (201) ApiResponse::created('Resource created', $resource); // Bad Request (400) ApiResponse::badRequest('Invalid input', ['field' => 'error message']); // Not Found (404) ApiResponse::notFound('Resource not found'); // Forbidden (403) ApiResponse::forbidden('Access denied'); // Validation Error (422) ApiResponse::validationError('Validation failed', $validator->errors()); // Server Error (500) ApiResponse::error('Something went wrong');
Response Format
All responses follow this structure:
{
"status": 200,
"message": "Operation successful",
"meta": null,
"data": {
"key": "value"
}
}
Usage in Controllers
class PostController extends Controller { public function __construct(private PostService $postService) {} public function index() { $posts = $this->postService->getAll(); return ApiResponse::success('Posts retrieved', $posts); } public function store(StorePostRequest $request) { $post = $this->postService->create($request->validated()); return ApiResponse::created('Post created successfully', $post); } public function show($id) { $post = $this->postService->findById($id); if (!$post) { return ApiResponse::notFound('Post not found'); } return ApiResponse::success('Post retrieved', $post); } }
๐ป Usage Examples
Authentication Flow
Register a New User
Request:
POST /api/v1/auth/register
Content-Type: application/json
{
"name": "John Doe",
"email": "john@example.com",
"password": "securepass123"
}
Response:
{
"status": 201,
"message": "User registered successfully",
"meta": null,
"data": {
"user": {
"id": 1,
"name": "John Doe",
"email": "john@example.com"
},
"token": "1|abc123xyz..."
}
}
Login
Request:
POST /api/v1/auth/login
Content-Type: application/json
{
"email": "john@example.com",
"password": "securepass123"
}
Response:
{
"status": 200,
"message": "Login successful",
"meta": null,
"data": {
"user": {
"id": 1,
"name": "John Doe",
"email": "john@example.com"
},
"token": "2|def456uvw..."
}
}
Get Authenticated User Profile
Request:
GET /api/v1/auth/me
Authorization: Bearer 2|def456uvw...
Response:
{
"status": 200,
"message": "User retrieved successfully",
"meta": null,
"data": {
"user": {
"id": 1,
"name": "John Doe",
"email": "john@example.com"
}
}
}
Google OAuth Flow
Request:
POST /api/v1/auth/google
Content-Type: application/json
{
"id_token": "google-id-token-from-frontend"
}
Response:
{
"status": 200,
"message": "User authenticated successfully",
"meta": null,
"data": {
"token": "3|ghi789rst...",
"user": {
"id": 2,
"name": "Jane Smith",
"email": "jane@gmail.com",
"google_id": "1234567890"
},
"first_time": true
}
}
Complete CRUD Example
Building a full REST API for posts:
# 1. Create route file with API resource routes php artisan make:route posts --controller=PostController --api # 2. Generate service with repository pattern php artisan make:service Post --model=Post --repository # 3. Create controller php artisan make:controller PostController --api # 4. Create form requests php artisan make:request StorePostRequest php artisan make:request UpdatePostRequest
Wire up the controller:
// app/Http/Controllers/PostController.php namespace App\Http\Controllers; use App\Services\PostService; use App\Http\Requests\StorePostRequest; use App\Http\Requests\UpdatePostRequest; use App\Utils\ApiResponse; class PostController extends Controller { public function __construct(private PostService $postService) {} public function index() { return ApiResponse::success( 'Posts retrieved', $this->postService->getAll() ); } public function store(StorePostRequest $request) { $post = $this->postService->create($request->validated()); return ApiResponse::created('Post created', $post); } public function show($id) { $post = $this->postService->findById($id); return ApiResponse::success('Post retrieved', $post); } public function update(UpdatePostRequest $request, $id) { $post = $this->postService->update($id, $request->validated()); return ApiResponse::success('Post updated', $post); } public function destroy($id) { $this->postService->delete($id); return ApiResponse::success('Post deleted'); } }
Your routes are ready:
GET /api/v1/posts- List all postsPOST /api/v1/posts- Create postGET /api/v1/posts/{id}- Show postPUT /api/v1/posts/{id}- Update postDELETE /api/v1/posts/{id}- Delete post
โ๏ธ Configuration
Route Structure
The package automatically creates a versioned API structure:
Generated Structure:
routes/
โโโ v1/
โโโ api.php # Main route file
โโโ auth.php # Auth routes (if installed)
โโโ google.php # Google OAuth routes (if installed)
Bootstrap Configuration
Your bootstrap/app.php is automatically updated:
return Application::configure(basePath: dirname(__DIR__)) ->withRouting( web: __DIR__.'/../routes/web.php', commands: __DIR__.'/../routes/console.php', health: '/health', then: function () { Route::prefix('api/v1') ->middleware('api') ->group(base_path('routes/v1/api.php')); } ) // ... rest of configuration
Middleware Configuration
Publish and edit config/softigital-core.php:
return [ 'force_json' => [ 'enabled' => true, 'auto_apply' => true, // Auto-apply to 'api' middleware group ], 'optional_auth' => [ 'enabled' => true, ], ];
Environment Variables (Google OAuth)
Add to .env after installing Google authentication:
GOOGLE_CLIENT_ID=your-google-client-id GOOGLE_CLIENT_SECRET=your-google-client-secret GOOGLE_REDIRECT_URI=http://localhost:8000/auth/google/callback
๐งช Testing
Example Test Cases
namespace Tests\Feature; use Tests\TestCase; use App\Models\User; use Illuminate\Support\Facades\Hash; class AuthenticationTest extends TestCase { public function test_user_can_register(): void { $response = $this->postJson('/api/v1/auth/register', [ 'name' => 'Test User', 'email' => 'test@example.com', 'password' => 'password123', ]); $response->assertStatus(201) ->assertJsonStructure([ 'status', 'message', 'data' => ['user', 'token'], ]); $this->assertDatabaseHas('users', [ 'email' => 'test@example.com', ]); } public function test_user_can_login(): void { $user = User::factory()->create([ 'password' => Hash::make('password123'), ]); $response = $this->postJson('/api/v1/auth/login', [ 'email' => $user->email, 'password' => 'password123', ]); $response->assertStatus(200) ->assertJsonStructure(['data' => ['token', 'user']]); } public function test_authenticated_user_can_get_profile(): void { $user = User::factory()->create(); $token = $user->createToken('test-token')->plainTextToken; $response = $this->withToken($token) ->getJson('/api/v1/auth/me'); $response->assertStatus(200) ->assertJson([ 'data' => [ 'user' => [ 'email' => $user->email, ], ], ]); } }
๐ Security
Token Management
- Uses Laravel Sanctum for secure token-based authentication
- Tokens stored in
personal_access_tokenstable - Each login creates a new token
- Revoke tokens by deleting from database or calling
$token->delete()
Password Security
- Passwords hashed with bcrypt
- Minimum 8 characters enforced
- Never logs or displays passwords
Google OAuth Security
- Google ID tokens verified server-side
- Uses official Google API Client library
google_idstored for account linking- Handles edge cases (existing email conflicts)
Best Practices:
// Always verify Google tokens server-side $client = new Google_Client(['client_id' => config('google.client_id')]); $payload = $client->verifyIdToken($idToken);
๐ค Contributing
Contributions are welcome! Please follow these steps:
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Commit changes:
git commit -m 'Add amazing feature' - Push to branch:
git push origin feature/amazing-feature - Open a Pull Request
Development Setup
git clone https://github.com/softigital-dev/core.git
cd core
composer install
๐ License
This package is open-sourced software licensed under the MIT license.
๐ Support
- GitHub Issues: https://github.com/softigital-dev/core/issues
- Author: Youssef Ehab - youssefehab.ofice@gmail.com
๐ฏ Roadmap
- Email verification flow
- Password reset functionality
- Two-factor authentication (2FA)
- Additional OAuth providers (Facebook, GitHub)
- Role-based access control (RBAC)
- API rate limiting utilities
Made with โค๏ธ by Youssef Ehab