Skip to content
PHP Laravel Backend API - HaloLight

PHP Laravel Backend API

HaloLight PHP enterprise-grade backend API service, built with Laravel 11 + PostgreSQL + Redis, providing a complete RESTful API.

API Documentation: https://halolight-api-php.h7ml.cn/docs

GitHub: https://github.com/halolight/halolight-api-php

Features

  • 🔐 JWT Dual Token - Access Token + Refresh Token, automatic renewal
  • 🛡️ RBAC Permissions - Role-based access control, wildcard matching
  • 📡 RESTful API - Standardized API design, OpenAPI documentation
  • 🗄️ Eloquent ORM - Elegant ActiveRecord database operations
  • Data Validation - Form Request parameter validation
  • 📊 Logging System - Request logging, error tracking
  • 🐳 Docker Support - Containerized deployment

Tech Stack

TechnologyVersionDescription
PHP8.2+Runtime
Laravel11.xWeb Framework
Eloquent11.xDatabase ORM
PostgreSQL16Data Storage
Redis7Cache/Queue
Form Request11.xData Validation
JWTtymon/jwt-authAuthentication
L5-Swagger8.xAPI Documentation

Quick Start

Requirements

  • PHP >= 8.2
  • Composer >= 2.0
  • PostgreSQL 16 (optional, defaults to SQLite)

Installation

bash
# Clone repository
git clone https://github.com/halolight/halolight-api-php.git
cd halolight-api-php

# Install dependencies
composer install

Environment Variables

bash
cp .env.example .env
env
# Database
DB_CONNECTION=pgsql
DB_HOST=localhost
DB_PORT=5432
DB_DATABASE=halolight
DB_USERNAME=postgres
DB_PASSWORD=your_password

# JWT Secret
JWT_SECRET=your-super-secret-key-min-32-chars
JWT_TTL=10080  # 7 days, in minutes

# Service Config
APP_PORT=8080
APP_ENV=development
APP_DEBUG=true

Database Initialization

bash
# Generate application key
php artisan key:generate

# Run migrations
php artisan migrate

# Seed data
php artisan db:seed

Start Service

bash
# Development mode
php artisan serve --port=8080

# Production mode
php artisan optimize
php artisan serve --port=8080 --env=production

Visit http://localhost:8080

Project Structure

halolight-api-php/
├── app/
│   ├── Http/
│   │   ├── Controllers/     # Controllers/Route handlers
│   │   ├── Middleware/      # Middleware
│   │   └── Requests/        # Request validation
│   ├── Services/            # Business logic layer
│   ├── Models/              # Data models
│   ├── Enums/               # Enum types
│   └── Providers/           # Service providers
├── database/
│   ├── migrations/          # Database migrations
│   └── seeders/             # Seed data
├── tests/                   # Test files
├── Dockerfile               # Docker configuration
├── docker-compose.yml
└── composer.json

API Modules

Authentication Endpoints

MethodPathDescriptionPermission
POST/api/auth/loginUser loginPublic
POST/api/auth/registerUser registrationPublic
POST/api/auth/refreshRefresh tokenPublic
POST/api/auth/logoutLogoutAuthenticated
POST/api/auth/forgot-passwordForgot passwordPublic
POST/api/auth/reset-passwordReset passwordPublic
GET/api/auth/meGet current userAuthenticated

User Management Endpoints

MethodPathDescriptionPermission
GET/api/usersGet user listusers:view
GET/api/users/:idGet user detailsusers:view
POST/api/usersCreate userusers:create
PUT/api/users/:idUpdate userusers:update
DELETE/api/users/:idDelete userusers:delete
GET/api/users/meGet current userAuthenticated
PATCH/api/users/:id/statusUpdate user statususers:update

Complete Endpoint List

Role Management (Roles) - 6 endpoints

MethodPathDescription
GET/api/rolesGet role list
GET/api/roles/:idGet role details
POST/api/rolesCreate role
PUT/api/roles/:idUpdate role
DELETE/api/roles/:idDelete role
POST/api/roles/:id/permissionsAssign permissions

Permission Management (Permissions) - 4 endpoints

MethodPathDescription
GET/api/permissionsGet permission list
GET/api/permissions/:idGet permission details
POST/api/permissionsCreate permission
DELETE/api/permissions/:idDelete permission

Team Management (Teams) - 7 endpoints

MethodPathDescription
GET/api/teamsGet team list
GET/api/teams/:idGet team details
POST/api/teamsCreate team
PUT/api/teams/:idUpdate team
DELETE/api/teams/:idDelete team
POST/api/teams/:id/membersAdd member
DELETE/api/teams/:id/members/:userIdRemove member

Document Management (Documents) - 9 endpoints

MethodPathDescription
GET/api/documentsGet document list
GET/api/documents/:idGet document details
POST/api/documentsCreate document
PUT/api/documents/:idUpdate document
DELETE/api/documents/:idDelete document
POST/api/documents/:id/shareShare document
GET/api/documents/:id/versionsGet version history
POST/api/documents/:id/restoreRestore version
POST/api/documents/:id/duplicateDuplicate document

File Management (Files) - 9 endpoints

MethodPathDescription
GET/api/filesGet file list
GET/api/files/:idGet file details
POST/api/files/uploadUpload file
PUT/api/files/:idUpdate file info
DELETE/api/files/:idDelete file
GET/api/files/:id/downloadDownload file
POST/api/files/:id/moveMove file
POST/api/files/:id/copyCopy file
GET/api/files/:id/previewPreview file

Folder Management (Folders) - 5 endpoints

MethodPathDescription
GET/api/foldersGet folder list
GET/api/folders/:idGet folder details
POST/api/foldersCreate folder
PUT/api/folders/:idUpdate folder
DELETE/api/folders/:idDelete folder

Message Management (Messages) - 5 endpoints

MethodPathDescription
GET/api/messagesGet message list
GET/api/messages/:idGet message details
POST/api/messagesSend message
PUT/api/messages/:id/readMark as read
DELETE/api/messages/:idDelete message

Notification Management (Notifications) - 5 endpoints

MethodPathDescription
GET/api/notificationsGet notification list
GET/api/notifications/:idGet notification details
PUT/api/notifications/:id/readMark as read
PUT/api/notifications/read-allMark all as read
DELETE/api/notifications/:idDelete notification

Calendar Management (Calendar) - 8 endpoints

MethodPathDescription
GET/api/calendar/eventsGet event list
GET/api/calendar/events/:idGet event details
POST/api/calendar/eventsCreate event
PUT/api/calendar/events/:idUpdate event
DELETE/api/calendar/events/:idDelete event
POST/api/calendar/events/:id/attendeesAdd attendee
DELETE/api/calendar/events/:id/attendees/:userIdRemove attendee
GET/api/calendar/availabilityCheck availability

Dashboard (Dashboard) - 9 endpoints

MethodPathDescription
GET/api/dashboard/statsStatistics data
GET/api/dashboard/visitsVisit trends
GET/api/dashboard/salesSales data
GET/api/dashboard/piePie chart data
GET/api/dashboard/tasksTodo tasks
GET/api/dashboard/calendarToday's schedule
GET/api/dashboard/notificationsLatest notifications
GET/api/dashboard/activityActivity log
GET/api/dashboard/overviewOverview data

Authentication

JWT Dual Token

Access Token:  7 days validity, for API requests
Refresh Token: 30 days validity, for refreshing Access Token

Request Header

http
Authorization: Bearer <access_token>

Refresh Flow

php
<?php

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class AuthController extends Controller
{
    public function refresh(Request $request)
    {
        $refreshToken = $request->input('refreshToken');

        // Validate Refresh Token
        try {
            auth()->setToken($refreshToken)->authenticate();

            // Generate new Access Token
            $newAccessToken = auth()->refresh();

            return response()->json([
                'accessToken' => $newAccessToken,
                'refreshToken' => $refreshToken, // Optional: can also generate new Refresh Token
                'expiresIn' => auth()->factory()->getTTL() * 60
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'error' => 'Invalid refresh token'
            ], 401);
        }
    }
}

Permission System

Role Definitions

RoleDescriptionPermissions
super_adminSuper Administrator* (all permissions)
adminAdministratorusers:*, documents:*, files:*, teams:*
userRegular Userdocuments:view, files:view, calendar:*
guestGuestdashboard:view

Permission Format

{resource}:{action}

Examples:
- users:view      # View users
- users:create    # Create user
- users:*         # All user operations
- *               # All permissions

Error Handling

Error Response Format

json
{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Request parameter validation failed",
    "details": [
      { "field": "email", "message": "Invalid email format" }
    ]
  }
}

Error Codes

StatusError CodeDescription
400VALIDATION_ERRORParameter validation failed
401UNAUTHORIZEDUnauthorized
403FORBIDDENNo permission
404NOT_FOUNDResource not found
409CONFLICTResource conflict
422UNPROCESSABLE_ENTITYUnprocessable entity
500INTERNAL_ERRORServer error

Common Commands

bash
# Development
php artisan serve --port=8080    # Start development server
php artisan tinker                # Enter REPL environment

# Build
php artisan optimize              # Optimize application
php artisan config:cache          # Cache configuration
php artisan route:cache           # Cache routes

# Testing
php artisan test                  # Run tests
php artisan test --coverage       # Run tests with coverage report

# Database
php artisan migrate               # Run migrations
php artisan migrate:fresh --seed  # Reset and seed data
php artisan db:seed               # Seed data

# Code quality
composer lint                     # Laravel Pint code style check
composer analyse                  # PHPStan static analysis

Deployment

Docker

bash
docker build -t halolight-api-php .
docker run -p 8080:8080 halolight-api-php

Docker Compose

bash
docker-compose up -d
yaml
# docker-compose.yml
version: '3.8'

services:
  app:
    build: .
    ports:
      - "8080:8080"
    environment:
      - APP_ENV=production
      - APP_DEBUG=false
      - DB_CONNECTION=pgsql
      - DB_HOST=db
      - DB_DATABASE=halolight
      - DB_USERNAME=${DB_USER}
      - DB_PASSWORD=${DB_PASSWORD}
      - REDIS_HOST=redis
      - JWT_SECRET=${JWT_SECRET}
    depends_on:
      - db
      - redis
    restart: unless-stopped

  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_DB: halolight
      POSTGRES_USER: ${DB_USER}
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    volumes:
      - postgres_data:/var/lib/postgresql/data
    restart: unless-stopped

  redis:
    image: redis:7-alpine
    volumes:
      - redis_data:/data
    restart: unless-stopped

volumes:
  postgres_data:
  redis_data:

Production Configuration

env
APP_ENV=production
APP_DEBUG=false
APP_URL=https://halolight-api-php.h7ml.cn

DB_CONNECTION=pgsql
DB_HOST=your-db-host
DB_DATABASE=halolight
DB_USERNAME=your-db-user
DB_PASSWORD=your-db-password

REDIS_HOST=your-redis-host
REDIS_PASSWORD=your-redis-password

JWT_SECRET=your-production-secret-min-32-chars
JWT_TTL=10080

CACHE_DRIVER=redis
SESSION_DRIVER=redis
QUEUE_CONNECTION=redis

Testing

Run Tests

bash
php artisan test
php artisan test --coverage

Test Example

php
<?php

namespace Tests\Feature;

use Tests\TestCase;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;

class AuthTest extends TestCase
{
    use RefreshDatabase;

    public function test_user_can_login_with_correct_credentials()
    {
        $user = User::factory()->create([
            'email' => 'test@example.com',
            'password' => bcrypt('password123')
        ]);

        $response = $this->postJson('/api/auth/login', [
            'email' => 'test@example.com',
            'password' => 'password123'
        ]);

        $response->assertStatus(200)
                 ->assertJsonStructure([
                     'accessToken',
                     'refreshToken',
                     'user'
                 ]);
    }

    public function test_user_cannot_login_with_incorrect_password()
    {
        $user = User::factory()->create([
            'email' => 'test@example.com',
            'password' => bcrypt('password123')
        ]);

        $response = $this->postJson('/api/auth/login', [
            'email' => 'test@example.com',
            'password' => 'wrong-password'
        ]);

        $response->assertStatus(401)
                 ->assertJson([
                     'error' => 'Unauthorized'
                 ]);
    }
}

Performance Metrics

Benchmark

MetricValueDescription
Request Throughput~1,500 QPSSingle core, using Swoole/Octane
Average Response Time~15msSimple query, PostgreSQL
Memory Usage~50MBSingle process, no cache
CPU Usage~40%High load, 4 cores

Observability

Logging System

php
<?php

use Illuminate\Support\Facades\Log;

// Configure log channels
// config/logging.php
return [
    'default' => env('LOG_CHANNEL', 'stack'),
    'channels' => [
        'stack' => [
            'driver' => 'stack',
            'channels' => ['single', 'daily'],
        ],
        'daily' => [
            'driver' => 'daily',
            'path' => storage_path('logs/laravel.log'),
            'level' => 'debug',
            'days' => 14,
        ],
    ],
];

// Use logging
Log::info('User logged in', ['user_id' => $user->id]);
Log::error('Payment failed', ['error' => $exception->getMessage()]);

Health Check

php
<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;

class HealthController extends Controller
{
    public function check()
    {
        $status = [
            'status' => 'healthy',
            'timestamp' => now()->toIso8601String(),
            'services' => []
        ];

        // Check database
        try {
            DB::connection()->getPdo();
            $status['services']['database'] = 'healthy';
        } catch (\Exception $e) {
            $status['status'] = 'unhealthy';
            $status['services']['database'] = 'unhealthy';
        }

        // Check Redis
        try {
            Redis::ping();
            $status['services']['redis'] = 'healthy';
        } catch (\Exception $e) {
            $status['status'] = 'unhealthy';
            $status['services']['redis'] = 'unhealthy';
        }

        return response()->json($status);
    }
}

Monitoring Metrics

php
<?php

namespace App\Http\Middleware;

use Illuminate\Support\Facades\Cache;

class MetricsMiddleware
{
    public function handle($request, $next)
    {
        $start = microtime(true);

        $response = $next($request);

        $duration = microtime(true) - $start;

        // Record request metrics
        Cache::increment('metrics:requests_total');
        Cache::increment("metrics:requests_{$response->status()}");

        // Record response time (can use Prometheus or other tools)
        $this->recordDuration($request->path(), $duration);

        return $response;
    }

    private function recordDuration($path, $duration)
    {
        // Implement metrics recording logic
    }
}

FAQ

Q: How to handle file uploads?

A: Laravel provides convenient file upload handling:

php
<?php

namespace App\Http\Controllers\Api\V1;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;

class FileController extends Controller
{
    public function upload(Request $request)
    {
        $request->validate([
            'file' => 'required|file|max:10240', // 10MB
        ]);

        $file = $request->file('file');
        $path = $file->store('uploads', 'public');

        return response()->json([
            'path' => Storage::url($path),
            'name' => $file->getClientOriginalName(),
            'size' => $file->getSize(),
            'mime' => $file->getMimeType()
        ]);
    }
}

Q: How to implement database transactions?

A: Use Laravel's DB facade or Eloquent models:

php
<?php

use Illuminate\Support\Facades\DB;
use App\Models\Order;
use App\Models\Payment;

// Method 1: DB facade
DB::transaction(function () {
    $order = Order::create([...]);
    $payment = Payment::create([
        'order_id' => $order->id,
        ...
    ]);
});

// Method 2: Manual control
DB::beginTransaction();
try {
    $order = Order::create([...]);
    $payment = Payment::create([...]);
    DB::commit();
} catch (\Exception $e) {
    DB::rollback();
    throw $e;
}

Development Tools

  • Laravel Idea - Laravel enhancement plugin for PhpStorm
  • Laravel Telescope - Local development debugging tool
  • Laravel Debugbar - Development environment performance analysis
  • PHPStan - Static analysis tool
  • Laravel Pint - Code style formatter

Backend Framework Comparison

FeatureLaravelNestJSFastAPISpring Boot
LanguagePHPTypeScriptPythonJava
ORMEloquentPrismaSQLAlchemyJPA
Performance⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
Learning Curve⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
Ecosystem⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
Development Speed⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐