โœจ 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

bash
composer require nomanur/api-starter-kit

Quick Setup

Run the installation command to set up everything automatically:

bash
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:

  1. Publish the configuration file
    bash
    php artisan vendor:publish --tag=api-starter-kit-config
  2. Add the service provider to config/app.php

    Only needed if not auto-discovered:

    php
    'providers' => [
        // ...
        LaravelApi\StarterKit\ApiStarterKitServiceProvider::class,
    ],
  3. Register middleware in bootstrap/app.php

    Import the middleware namespaces at the top of your bootstrap/app.php:

    php
    use LaravelApi\StarterKit\Http\Middleware\ApiAuthenticate;
    use LaravelApi\StarterKit\Http\Middleware\ApiCors;
    use LaravelApi\StarterKit\Http\Middleware\ApiRateLimit;

    Then register them inside the withMiddleware configuration:

    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:

bash
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:

bash
php artisan make:api-resource Post \
    --model=Article \
    --controller=ArticlesController \
    --transformer=ArticleTransformer

To create a migration along with the API resource:

bash
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:

โœ… Success Response (200)
{
    "data": {
        "id": 1,
        "title": "My Post",
        "content": "Post content here",
        "created_at": "2024-01-01T00:00:00+00:00"
    },
    "message": "Post retrieved successfully"
}
โŒ Error Response (422)
{
    "error": "Validation failed",
    "errors": {
        "title": ["The title field is required."],
        "content": ["The content field must be at least 10 characters."]
    }
}
๐Ÿ“„ Paginated Response (200)
{
    "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:

php
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:

php
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:

php
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:

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:

bash
php artisan api-starter-kit:install --sanctum

Protect routes with middleware:

php
Route::middleware('api.auth')->group(function () {
    Route::get('/user', function (Request $request) {
        return $request->user();
    });
});

Authenticate users via tokens:

bash
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:

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:

routes/api.php
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:

bash
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:

php
// 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

bash
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:

bash
php artisan api:export --name="My API v2" --output=docs/api.json

Pre-fill Bearer token for authenticated routes:

bash
php artisan api:export --bearer="your-token-here"

Group routes by middleware instead of URL prefix:

bash
php artisan api:export --group-by=middleware

Filter routes with include/exclude patterns:

bash
# 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 :param format with descriptions
  • Auth Detection: Routes with auth middleware (auth:sanctum, auth:api, auth, api.auth) automatically get Bearer token auth
  • Request Bodies: POST, PUT, and PATCH requests include a JSON body template
  • Default Headers: Accept: application/json and Content-Type: application/json on 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:

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:

terminal
๐Ÿ“ฆ 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:

bash
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:

php
'response' => [
    'success_key' => 'data',
    'message_key' => 'message',
    'error_key' => 'error',
    'meta_key' => 'meta',
    'links_key' => 'links',
],

Enable Caching

Enable response caching in config:

php
'cache' => [
    'enabled' => true,
    'ttl' => 60, // minutes
],

Custom Rate Limits

Configure rate limiting:

php
'rate_limit' => [
    'enabled' => true,
    'max_attempts' => 60,
    'decay_minutes' => 1,
],

Health Check Endpoint

The package includes a health check endpoint:

bash
GET /health
Response
{
    "status": "ok",
    "timestamp": "2024-01-01T00:00:00+00:00",
    "version": "v1"
}

๐Ÿงช Testing

Run the package tests:

bash
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:

โค๏ธ

Credits: Created by nomanur rahman and all contributors. Licensed under MIT.