โจ 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.
Postman Export
Export API routes as a Postman Collection v2.1 with one command.
๐ฆ 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.phpImport the middleware namespaces at the top of your
bootstrap/app.php:phpuse LaravelApi\StarterKit\Http\Middleware\ApiAuthenticate; use LaravelApi\StarterKit\Http\Middleware\ApiCors; use LaravelApi\StarterKit\Http\Middleware\ApiRateLimit;Then register them inside the
withMiddlewareconfiguration:php->withMiddleware(function (Middleware $middleware) { $middleware->alias([ 'api.auth' => ApiAuthenticate::class, 'api.rate_limit' => ApiRateLimit::class, 'api.cors' => 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 |
Middleware Registration
To use these middleware in your application, you must import their namespaces and register them in bootstrap/app.php:
use LaravelApi\StarterKit\Http\Middleware\ApiAuthenticate;
use LaravelApi\StarterKit\Http\Middleware\ApiCors;
use LaravelApi\StarterKit\Http\Middleware\ApiRateLimit;
// Inside the configure block:
$middleware->alias([
'api.auth' => ApiAuthenticate::class,
'api.rate_limit' => ApiRateLimit::class,
'api.cors' => ApiCors::class,
]);
Applying Middleware
Once registered, you can apply them to your routes using their aliases:
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);
๐ฎ Postman Collection Export
Export all your registered API routes as a Postman Collection v2.1 JSON file with a single command. The exported collection can be imported directly into Postman for API testing and documentation.
Basic Usage
php artisan api:export
Alias: You can also use php artisan api:export-postman
Command Options
| Option | Description | Default |
|---|---|---|
--output= |
Custom output file path | storage/app/postman_collection.json |
--name= |
Collection name | App name from config |
--bearer= |
Default Bearer token for authenticated routes | {{auth_token}} (Postman variable) |
--base-url= |
Base URL override | {{base_url}} (Postman variable) |
--group-by= |
Grouping strategy: prefix or middleware |
prefix |
--include= |
Regex pattern to include only matching routes | All routes |
--exclude= |
Regex pattern to exclude matching routes | None |
--force |
Overwrite existing file without confirmation | Prompts user |
Examples
Export with a custom collection name and output path:
php artisan api:export --name="My API v2" --output=docs/api.json
Pre-fill Bearer token for authenticated routes:
php artisan api:export --bearer="your-token-here"
Group routes by middleware instead of URL prefix:
php artisan api:export --group-by=middleware
Filter routes with include/exclude patterns:
# Only export user and post routes
php artisan api:export --include="users|posts"
# Exclude health check and debug routes
php artisan api:export --exclude="health|debug"
# Combine both
php artisan api:export --include="api/v1" --exclude="health"
What Gets Exported
The command automatically handles the following for each route:
- Folder Organization: Routes are grouped into folders by URL prefix (e.g., all
/api/users/*routes in a "Users" folder) - Readable Names: Human-readable item names generated from route names or URI patterns (e.g.,
GET /api/users/{id}โ "Get User") - Path Variables: Laravel
{param}syntax is converted to Postman:paramformat with descriptions - Auth Detection: Routes with auth middleware (
auth:sanctum,auth:api,auth,api.auth) automatically get Bearer token auth - Request Bodies:
POST,PUT, andPATCHrequests include a JSON body template - Default Headers:
Accept: application/jsonandContent-Type: application/jsonon every request - Postman Variables:
{{base_url}}and{{auth_token}}variables for easy environment switching
Configuration
Customize the export behavior in config/api-starter-kit.php:
'postman' => [
'collection_name' => env('API_POSTMAN_COLLECTION_NAME', null),
'base_url' => env('API_POSTMAN_BASE_URL', '{{base_url}}'),
'auth_middleware' => ['auth:sanctum', 'auth:api', 'auth', 'api.auth'],
'headers' => [
'Accept' => 'application/json',
'Content-Type' => 'application/json',
],
'structured' => true,
'output_path' => 'postman_collection.json',
],
| Config Key | Description | Default |
|---|---|---|
collection_name |
Name of the Postman collection | App name |
base_url |
Base URL for all requests (supports Postman variables) | {{base_url}} |
auth_middleware |
Middleware names that indicate authenticated routes | ['auth:sanctum', 'auth:api', 'auth', 'api.auth'] |
headers |
Default headers added to every request | Accept + Content-Type as JSON |
structured |
Whether to organize routes into folders | true |
output_path |
Default output path relative to storage/app/ |
postman_collection.json |
Output Summary
After export, the command displays a formatted summary table of all exported routes:
๐ฆ Exporting Postman Collection...
โ
Postman Collection exported successfully!
+--------+---------------------+------------------+-------------------+
| Method | URI | Name | Middleware |
+--------+---------------------+------------------+-------------------+
| GET | api/health | โ | โ |
| GET | api/users | users.index | auth:sanctum |
| POST | api/users | users.store | auth:sanctum |
| GET | api/users/{user} | users.show | auth:sanctum |
| PUT | api/users/{user} | users.update | auth:sanctum |
| DELETE | api/users/{user} | users.destroy | auth:sanctum |
+--------+---------------------+------------------+-------------------+
๐ Collection: My API Collection
๐ File: /path/to/storage/app/postman_collection.json
๐ข Routes exported: 6
๐ฆ File size: 4.52 KB
Tip: Set up Postman environment variables for base_url and auth_token to easily switch between development, staging, and production environments.
โ๏ธ 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.