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

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

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

Apply them to routes:

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);

โš™๏ธ 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.