โจ Features
Everything you need to build production-ready APIs with Laravel, standardized and ready to use.
Standardized Responses
Consistent JSON response format across all your API endpoints.
Fractal Transformers
Clean data transformation layer for consistent API outputs.
Exception Handling
Centralized error handling for all API errors with proper HTTP codes.
Rate Limiting
Built-in API rate limiting to protect your endpoints.
Authentication
Laravel Sanctum integration ready out of the box.
Scaffolding Commands
Generate API resources with a single artisan command.
Pagination
Built-in pagination with metadata and navigation links.
Caching
Optional response caching for improved performance.
CORS Support
Cross-origin request handling with built-in middleware.
Validation
Standardized validation error responses for client errors.
Base Controllers
Extendable foundation classes with helpful methods.
ApiModel
Base model with automatic transformer support.
๐ฆ Installation
Requirements
- PHP 8.0 or higher
- Laravel 9.0 or higher
- Composer
Install via Composer
composer require nomanur/api-starter-kit
Quick Setup
Run the installation command to set up everything automatically:
php artisan api-starter-kit:install --sanctum --migrations
This command will:
- Publish the configuration file
- Install Laravel Sanctum for authentication
- Publish database migrations
- Configure exception handling
- Register middleware
- Create helper functions
Tip: The --sanctum flag is recommended for modern API authentication. Use --migrations to automatically publish required database migrations.
Manual Setup
If you prefer manual setup, follow these steps:
-
Publish the configuration file
bash
php artisan vendor:publish --tag=api-starter-kit-config -
Add the service provider to
config/app.phpOnly needed if not auto-discovered:
php'providers' => [ // ... LaravelApi\StarterKit\ApiStarterKitServiceProvider::class, ], -
Register middleware in
bootstrap/app.phpphp->withMiddleware(function ($middleware) { $middleware->alias([ 'api.auth' => \LaravelApi\StarterKit\Http\Middleware\ApiAuthenticate::class, 'api.rate_limit' => \LaravelApi\StarterKit\Http\Middleware\ApiRateLimit::class, 'api.cors' => \LaravelApi\StarterKit\Http\Middleware\ApiCors::class, ]); })
๐ Usage
Creating Your First API Resource
The easiest way to create a complete API resource is using the artisan command:
php artisan make:api-resource Post
This will create:
- Model:
app/Models/Post.php - Controller:
app/Http/Controllers/Api/PostsController.php - Transformer:
app/Transformers/PostTransformer.php - Routes: Added to
routes/api.php
You can also specify custom names:
php artisan make:api-resource Post \
--model=Article \
--controller=ArticlesController \
--transformer=ArticleTransformer
To create a migration along with the API resource:
php artisan make:api-resource Post --migration
This will also create a migration file in database/migrations/ with a basic table structure (id and timestamps).
API Response Format
All API responses follow a standardized format:
{
"data": {
"id": 1,
"title": "My Post",
"content": "Post content here",
"created_at": "2024-01-01T00:00:00+00:00"
},
"message": "Post retrieved successfully"
}
{
"error": "Validation failed",
"errors": {
"title": ["The title field is required."],
"content": ["The content field must be at least 10 characters."]
}
}
{
"data": [...],
"message": "Posts retrieved successfully",
"meta": {
"current_page": 1,
"last_page": 5,
"per_page": 15,
"total": 75,
"from": 1,
"to": 15
},
"links": {
"self": "http://example.com/api/v1/posts?page=1",
"first": "http://example.com/api/v1/posts?page=1",
"last": "http://example.com/api/v1/posts?page=5",
"next": "http://example.com/api/v1/posts?page=2",
"prev": null
}
}
Using the Base Controller
Extend the ApiController in your controllers to get all the helper methods:
namespace App\Http\Controllers\User;
use App\Http\Controllers\ApiController;
use App\Models\User;
use App\Transformers\UserTransformer;
use Illuminate\Http\Request;
class UserController extends ApiController
{
public function __construct()
{
$this->middleware('transform.input:'.UserTransformer::class)->only(['store', 'update']);
}
public function index()
{
$users = User::all();
return $this->showAll($users);
}
public function show(User $user)
{
return $this->showOne($user);
}
public function store(Request $request)
{
$rules = [
'name' => 'required',
'email' => 'required|email|unique:users',
'password' => 'required|min:6|confirmed',
];
$this->validate($request, $rules);
$data = $request->except('password_confirmation');
$data['password'] = bcrypt($request->password);
$user = User::create($data);
return $this->showOne($user, 201);
}
public function destroy(User $user)
{
$user->delete();
return $this->showOne($user);
}
}
Available Controller Methods: showOne(), showAll(), successResponse(), errorResponse(), showMessage(), and more.
Using Transformers
Transformers provide a clean way to format your API responses:
namespace App\Transformers;
use App\Models\Post;
use LaravelApi\StarterKit\Transformers\BaseTransformer;
class PostTransformer extends BaseTransformer
{
public function transform(Post $post): array
{
return [
'id' => $post->id,
'title' => $post->title,
'content' => $post->content,
'author' => $post->author?->name,
'published' => $post->published_at?->toIso8601String(),
'created_at' => $post->created_at->toIso8601String(),
'updated_at' => $post->updated_at->toIso8601String(),
];
}
/**
* Map transformed attributes to original attributes.
*/
public static function originalAttribute(string $index): ?string
{
$attributes = [
'id' => 'id',
'title' => 'title',
'content' => 'content',
'author' => 'author',
'published' => 'published_at',
'created_at' => 'created_at',
'updated_at' => 'updated_at',
];
return $attributes[$index] ?? null;
}
/**
* Map original attributes to transformed attributes.
*/
public static function transformedAttribute(string $index): ?string
{
$attributes = [
'id' => 'id',
'title' => 'title',
'content' => 'content',
'author' => 'author',
'published_at' => 'published',
'created_at' => 'created_at',
'updated_at' => 'updated_at',
];
return $attributes[$index] ?? null;
}
}
Using the Model
Extend ApiModel for automatic transformer support:
namespace App\Models;
use LaravelApi\StarterKit\Models\ApiModel;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class Post extends ApiModel
{
use HasFactory;
public static $transformer = \App\Transformers\PostTransformer::class;
protected $fillable = ['title', 'content', 'published_at'];
protected $casts = [
'published_at' => 'datetime',
];
}
API Routes
Define your API routes in routes/api.php:
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\Api\PostsController;
// Public routes
Route::get('/posts', [PostsController::class, 'index']);
Route::get('/posts/{post}', [PostsController::class, 'show']);
// Protected routes
Route::middleware('api.auth')->group(function () {
Route::post('/posts', [PostsController::class, 'store']);
Route::put('/posts/{post}', [PostsController::class, 'update']);
Route::delete('/posts/{post}', [PostsController::class, 'destroy']);
});
๐ Authentication
Using Sanctum (Recommended)
Install Sanctum with the installer:
php artisan api-starter-kit:install --sanctum
Protect routes with middleware:
Route::middleware('api.auth')->group(function () {
Route::get('/user', function (Request $request) {
return $request->user();
});
});
Authenticate users via tokens:
curl -H "Authorization: Bearer YOUR_TOKEN" \
http://example.com/api/v1/user
๐ก๏ธ Middleware
The package includes three middleware classes:
| Middleware | Alias | Description |
|---|---|---|
ApiAuthenticate |
api.auth |
Handles API authentication |
ApiRateLimit |
api.rate_limit |
Rate limiting for API endpoints |
ApiCors |
api.cors |
CORS headers for cross-origin requests |
Apply them to routes:
Route::middleware(['api.auth', 'api.rate_limit'])->group(function () {
// Protected and rate-limited routes
});
๐ฏ Query Parameters
The API supports various query parameters for filtering and pagination:
| Parameter | Type | Default | Description |
|---|---|---|---|
per_page |
integer | 15 | Items per page (max: 100) |
page |
integer | 1 | Page number |
sort_by |
string | id | Field to sort by |
desc |
boolean | false | Sort in descending order |
Example request:
GET /api/v1/posts?per_page=10&page=2&sort_by=created_at&desc=true
๐ Exception Handling
All exceptions are automatically caught and returned as JSON:
| Exception | HTTP Code | Description |
|---|---|---|
ValidationException |
422 | Validation errors |
ModelNotFoundException |
404 | Resource not found |
AuthenticationException |
401 | Unauthenticated |
AuthorizationException |
403 | Unauthorized |
NotFoundHttpException |
404 | Route not found |
MethodNotAllowedHttpException |
405 | Invalid HTTP method |
QueryException |
409/500 | Database errors |
๐ฆ Helper Functions
The package provides helper functions for quick API responses:
// Success response
api_response($data, 'Success message', 200);
// Error response
api_error('Error message', 400, $errors);
// Paginated response
api_paginated($paginator, 'Success message', 200);
โ๏ธ Configuration
Publish the configuration file to customize settings:
php artisan vendor:publish --tag=api-starter-kit-config
Configuration options in config/api-starter-kit.php:
| Key | Default | Description |
|---|---|---|
prefix |
api |
API URL prefix |
version |
v1 |
API version |
rate_limit |
array | Rate limiting settings |
auth |
array | Authentication driver configuration |
response |
array | Response format keys |
cache |
array | Caching settings |
exceptions |
array | Exception handling settings |
validation |
array | Validation error format |
๐ง Advanced Usage
Custom Response Keys
Configure response keys in config/api-starter-kit.php:
'response' => [
'success_key' => 'data',
'message_key' => 'message',
'error_key' => 'error',
'meta_key' => 'meta',
'links_key' => 'links',
],
Enable Caching
Enable response caching in config:
'cache' => [
'enabled' => true,
'ttl' => 60, // minutes
],
Custom Rate Limits
Configure rate limiting:
'rate_limit' => [
'enabled' => true,
'max_attempts' => 60,
'decay_minutes' => 1,
],
Health Check Endpoint
The package includes a health check endpoint:
GET /health
{
"status": "ok",
"timestamp": "2024-01-01T00:00:00+00:00",
"version": "v1"
}
๐งช Testing
Run the package tests:
composer test
๐ค Contributing
We welcome contributions! Please see our Contributing Guide for details on how to get started.
Security: If you discover any security related issues, please email nomanurrahman@gmail.com instead of using the issue tracker.
๐ Support
If you find this package helpful, please โญ star it on GitHub!
For questions and support:
- GitHub Issues: Open an issue
- Email: nomanurrahman@gmail.com
- Documentation: You're reading it now!
Credits: Created by nomanur rahman and all contributors. Licensed under MIT.