CAT
/Skills
SkillsMCPMarketplacesDigestToolsAdvertise

This week in Claude

Every Monday: Claude Code, Agent SDK, MCP, and the Anthropic platform moves worth your time.

Skills by Category
Frontend DevelopmentBackend & APIsTesting & QASecurityDevOps & CI/CDGit & Pull RequestsDocumentationCode Review & QualityAI & Agent BuildingSkill Development
MCP Servers by Category
Sales & MarketingWeb & Browser AutomationDatabasesAI & LLM ToolsCloud & InfrastructureCommunication & MessagingDeveloper ToolsDesign & CreativeDocuments & KnowledgeSearch & Web Crawling
Marketplaces by Category
AI Agents & OrchestrationLLM IntegrationDevelopment ToolsFrontend & UIBackend & APIsDatabasesTesting & Code QualityDevOps & CloudSecurity & ComplianceGit & Version Control

Cross AI Tools

Discover Claude Code plugins, extensions, and tools. Automatically updated directory of Anthropic Claude AI marketplaces with development tools, productivity plugins, and integrations.

Resources

  • Browse Skills
  • Browse MCP Servers
  • Browse Marketplaces
  • Plugins Reference

Community

  • About
  • Tools
  • Feedback
  • Privacy Policy
  • Advertise

Built for the Claude Code community with Claude Code by @mertduzgun

Independent project, not affiliated with Anthropic

Laravel Api

juststeveking/laravel-api-skill
176 installs24 stars
Summary

This is Steve's opinionated take on building Laravel REST APIs with strict architectural boundaries. Everything is stateless, explicitly typed, and organized by resource. You get invokable controllers, form request DTOs with payload methods, single-purpose Action classes, and ULID-based models. Routes are versioned with HTTP Sunset headers baked in. The code quality section is aggressive about PSR-12, no nested ternaries, and preserving exact behavior during refactors. If you want a prescriptive pattern that eliminates decision fatigue on API structure, this locks you into a defensible convention. Good for teams that need consistency or solo devs tired of reinventing routing organization.

Install to Claude Code

npx -y skills add juststeveking/laravel-api-skill --skill laravel-api --agent claude-code

Installs into .claude/skills of the current project.

CodeRabbit
CodeRabbit
AI writes the code. CodeRabbit catches the slop.
Try For Free →
Keep your Mac awake
Keep your Mac awake
Keep your Mac awake while Claude Code and 40+ AI agents run. Sleeps when they're idle.
One time payment $9 →
Context.devContext.dev
Context.dev
Integrate web data into your AI product. One API to scrape website & brand data.
Get API Key Now →
Make your agent a DeFi expert
Make your agent a DeFi expert
Agent, run crypto. Access onchain data & trade routes via 1inch.
Install now →
Make money from your Skills
Make money from your Skills
On Capafy, your Skill runs online 24/7 as an agent product, and you get paid every time someone uses it.
Start earning →
AppSignal
AppSignal
Monitor with ease. Code with confidence.
Start Free Trial →
CodeRabbit
CodeRabbit
AI writes the code. CodeRabbit catches the slop.
Try For Free →
Keep your Mac awake
Keep your Mac awake
Keep your Mac awake while Claude Code and 40+ AI agents run. Sleeps when they're idle.
One time payment $9 →
Context.devContext.dev
Context.dev
Integrate web data into your AI product. One API to scrape website & brand data.
Get API Key Now →
Make your agent a DeFi expert
Make your agent a DeFi expert
Agent, run crypto. Access onchain data & trade routes via 1inch.
Install now →
Make money from your Skills
Make money from your Skills
On Capafy, your Skill runs online 24/7 as an agent product, and you get paid every time someone uses it.
Start earning →
AppSignal
AppSignal
Monitor with ease. Code with confidence.
Start Free Trial →
Files
SKILL.mdView on GitHub

Laravel API - Steve's Architecture

Build Laravel REST APIs with clean, stateless, resource-scoped architecture.

Quick Start

When user requests a Laravel API, follow this workflow:

  1. Understand requirements - What resources? What operations? Authentication needed?
  2. Initialize project structure - Set up routing, remove frontend bloat
  3. Build first resource - Complete CRUD to establish pattern
  4. Add authentication - JWT via PHP Open Source Saver
  5. Iterate on remaining resources - Follow established pattern

Core Architecture Principles

Read references/architecture.md for comprehensive details. Key principles:

  1. Stateless by design - No hidden dependencies, explicit data flow
  2. Boundary-first - Clear separation of HTTP, business logic, data layers
  3. Resource-scoped - Routes, controllers organized by resource
  4. Version discipline - Namespace-based versioning, HTTP Sunset headers

Code Quality Standards

All code must follow Laravel best practices and PSR-12 standards:

  1. Preserve Functionality - Refactorings change HOW code works, never WHAT it does
  2. Explicit Over Implicit - Prefer clear, readable code over clever shortcuts
  3. Type Declarations - Always use return types on methods, parameter types where beneficial
  4. Avoid Nested Ternaries - Use match expressions, switch, or if/else for clarity
  5. Consistent Naming - Follow PSR-12 and Laravel conventions strictly
  6. Proper Namespacing - Organize imports logically, use full type hints

When reviewing or refactoring code:

  • Focus on clarity and maintainability over cleverness
  • Simplify complex nested logic into readable structures
  • Extract magic values into named constants or config
  • Remove unnecessary complexity while preserving exact behavior

Project Structure

routes/api/
  routes.php              # Main entry point, version grouping
  tasks.php               # All task routes, all versions
  projects.php            # All project routes, all versions

app/Http/
  Controllers/{Resource}/V1/
    StoreController.php   # Always invokable
    IndexController.php
    ShowController.php
  Requests/{Resource}/V1/
    StoreTaskRequest.php  # Validation + payload() method
  Payloads/{Resource}/
    StoreTaskPayload.php  # Simple DTOs with toArray()
  Responses/
    JsonDataResponse.php  # Implements Responsable
    JsonErrorResponse.php
  Middleware/
    HttpSunset.php

app/Actions/{Resource}/
  CreateTask.php          # Single-purpose business logic

app/Services/             # Only when logic too complex for Actions

app/Models/
  Task.php                # HasUlids trait, simple data access

Building a New Resource Endpoint

Step 1: Model

Always use ULIDs. Keep models simple - data access only.

<?php

declare(strict_types=1);

namespace App\Models;

use Illuminate\Database\Eloquent\Concerns\HasUlids;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

final class Task extends Model
{
    use HasFactory;
    use HasUlids;
    
    protected $fillable = [
        'title',
        'description',
        'status',
        'project_id',
    ];

    protected $casts = [
        'created_at' => 'datetime',
        'updated_at' => 'datetime',
    ];

    public function project(): BelongsTo
    {
        return $this->belongsTo(Project::class);
    }
}

Step 2: Routes

Create resource route file at routes/api/{resource}.php:

use App\Http\Controllers\Tasks\V1;

Route::middleware(['auth:api'])->group(function () {
    Route::get('/tasks', V1\IndexController::class);
    Route::post('/tasks', V1\StoreController::class);
    Route::get('/tasks/{task}', V1\ShowController::class);
    Route::patch('/tasks/{task}', V1\UpdateController::class);
    Route::delete('/tasks/{task}', V1\DestroyController::class);
});

Include in routes/api/routes.php:

Route::prefix('v1')->group(function () {
    require __DIR__ . '/tasks.php';
});

Step 3: DTO (Payload)

Create at app/Http/Payloads/{Resource}/{Operation}Payload.php:

<?php

declare(strict_types=1);

namespace App\Http\Payloads\Tasks;

final readonly class StoreTaskPayload
{
    public function __construct(
        public string $title,
        public ?string $description,
        public string $status,
        public string $projectId,
    ) {}

    public function toArray(): array
    {
        return [
            'title' => $this->title,
            'description' => $this->description,
            'status' => $this->status,
            'project_id' => $this->projectId,
        ];
    }
}

Step 4: Form Request

Create at app/Http/Requests/{Resource}/V1/{Operation}Request.php:

<?php

declare(strict_types=1);

namespace App\Http\Requests\Tasks\V1;

use App\Http\Payloads\Tasks\StoreTaskPayload;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;

final class StoreTaskRequest extends FormRequest
{
    public function authorize(): bool
    {
        return true;
    }

    public function rules(): array
    {
        return [
            'title' => ['required', 'string', 'max:255'],
            'description' => ['nullable', 'string', 'max:1000'],
            'status' => ['required', Rule::in(['pending', 'in_progress', 'completed'])],
            'project_id' => ['required', 'string', 'exists:projects,id'],
        ];
    }

    public function payload(): StoreTaskPayload
    {
        return new StoreTaskPayload(
            title: $this->string('title')->toString(),
            description: $this->string('description')->toString(),
            status: $this->string('status')->toString(),
            projectId: $this->string('project_id')->toString(),
        );
    }
}

Step 5: Action

Create at app/Actions/{Resource}/{Operation}.php:

<?php

declare(strict_types=1);

namespace App\Actions\Tasks;

use App\Http\Payloads\Tasks\StoreTaskPayload;
use App\Models\Task;

final readonly class CreateTask
{
    public function handle(StoreTaskPayload $payload): Task
    {
        return Task::create($payload->toArray());
    }
}

Step 6: Controller

Create invokable controller at app/Http/Controllers/{Resource}/V1/{Operation}Controller.php:

<?php

declare(strict_types=1);

namespace App\Http\Controllers\Tasks\V1;

use App\Actions\Tasks\CreateTask;
use App\Http\Requests\Tasks\V1\StoreTaskRequest;
use App\Http\Responses\JsonDataResponse;
use Illuminate\Http\JsonResponse;

final readonly class StoreController
{
    public function __construct(
        private CreateTask $createTask,
    ) {}

    public function __invoke(StoreTaskRequest $request): JsonResponse
    {
        $task = $this->createTask->handle(
            payload: $request->payload(),
        );

        return new JsonDataResponse(
            data: $task,
            status: 201,
        );
    }
}

Response Format

Standard format for all responses:

Success:

{
    "data": {...},
    "meta": {...}
}

Error (Problem+JSON):

{
    "type": "about:blank",
    "title": "Validation Failed",
    "status": 422,
    "detail": "The given data was invalid",
    "errors": {...}
}

Query Building

Use Spatie Query Builder for filtering, sorting, includes:

use Spatie\QueryBuilder\QueryBuilder;

$tasks = QueryBuilder::for(Task::class)
    ->allowedFilters(['status', 'priority'])
    ->allowedSorts(['created_at', 'due_date'])
    ->allowedIncludes(['project', 'assignee'])
    ->paginate();

Versioning Endpoints

When creating V2:

  1. Create V2 namespace: App\Http\Controllers\Tasks\V2\
  2. Add V2 route group in resource file
  3. Add Sunset middleware to V1 routes:
Route::middleware(['auth:api', 'http.sunset:2025-12-31'])->group(function () {
    // V1 routes
});

Authentication Setup

Use PHP Open Source Saver JWT package:

composer require php-open-source-saver/jwt-auth
php artisan vendor:publish --provider="PHPOpenSourceSaver\JWTAuth\Providers\LaravelServiceProvider"
php artisan jwt:secret

Configure in config/auth.php:

'guards' => [
    'api' => [
        'driver' => 'jwt',
        'provider' => 'users',
    ],
],

Essential Setup

Add to app/Providers/AppServiceProvider.php:

use Illuminate\Database\Eloquent\Model;

public function boot(): void
{
    Model::shouldBeStrict(); // Prevent N+1 queries
}

Register HttpSunset middleware in app/Http/Kernel.php:

protected $middlewareAliases = [
    'http.sunset' => \App\Http\Middleware\HttpSunset::class,
];

Anti-Patterns to Avoid

  • Using auto-increment IDs instead of ULIDs
  • Business logic in models
  • Multiple actions per controller
  • Accessing request data directly in controllers/actions
  • Hidden query scopes
  • Service classes when an Action would suffice
  • Breaking changes without versioning
  • Inconsistent response formats
  • Nested ternary operators (use match expressions instead)
  • Missing type declarations on methods and parameters
  • Overly compact "clever" code that sacrifices readability

Code Review & Refactoring

When reviewing or refactoring Laravel API code, apply these principles:

Simplification Checklist

  1. Preserve Functionality - Ensure refactorings don't change behavior
  2. Check Type Safety - Add missing return types and parameter types
  3. Simplify Logic - Replace nested ternaries with match expressions
  4. Extract Complexity - Move complex conditions into named methods
  5. Verify Standards - Ensure PSR-12 compliance with declare(strict_types=1)
  6. Improve Naming - Use descriptive names that reveal intent

Match Expression Pattern

Replace nested ternaries with match for clarity:

// ❌ Avoid: Nested ternary
$status = $task->completed_at 
    ? ($task->verified ? 'verified' : 'completed')
    : ($task->started_at ? 'in_progress' : 'pending');

// ✅ Prefer: Match expression
$status = match (true) {
    $task->completed_at && $task->verified => 'verified',
    $task->completed_at => 'completed',
    $task->started_at => 'in_progress',
    default => 'pending',
};

References

  • architecture.md - Comprehensive architectural patterns and principles
  • code-examples.md - Complete working examples for every component
  • code-quality.md - Laravel best practices, refactoring patterns, and PSR-12 standards

Templates

Template files in assets/templates/ for quick scaffolding:

  • Controller.php
  • FormRequest.php
  • Payload.php
  • Action.php
  • Model.php
Featured
CodeRabbit
CodeRabbit
AI writes the code. CodeRabbit catches the slop.
Try For Free →
Keep your Mac awake
Keep your Mac awake
Keep your Mac awake while Claude Code and 40+ AI agents run. Sleeps when they're idle.
One time payment $9 →
Context.devContext.dev
Context.dev
Integrate web data into your AI product. One API to scrape website & brand data.
Get API Key Now →
Make your agent a DeFi expert
Make your agent a DeFi expert
Agent, run crypto. Access onchain data & trade routes via 1inch.
Install now →
Make money from your Skills
Make money from your Skills
On Capafy, your Skill runs online 24/7 as an agent product, and you get paid every time someone uses it.
Start earning →
AppSignal
AppSignal
Monitor with ease. Code with confidence.
Start Free Trial →
Categories
Backend & APIsPHP & Laravel
First SeenJun 3, 2026
View on GitHub

Recommended

More Backend & APIs →
connecting-lambda-to-api-gateway

aws/agent-toolkit-for-aws

connecting lambda to api gateway
934
772
prisma-database-setup

prisma/skills

Step-by-step configuration guides for Prisma ORM across PostgreSQL, MySQL, SQLite, MongoDB, SQL Server, CockroachDB, and Prisma Postgres.
10.8k
39
firebase-auth-basics

firebase/agent-skills

Guide for setting up and using Firebase Authentication. Use this skill when the user's app requires user sign-in, user management, or secure data access using auth rules.
70.8k
348
api-gateway-configurator

Dexploarer/hyper-forge

Configure and manage API gateways including Kong, Tyk, AWS API Gateway, and Apigee. Activates when users need help setting up API gateways, rate limiting, authentication, request transformation, or API management.
5
api-gateway

itsmostafa/aws-agent-skills

AWS API Gateway for REST and HTTP API management. Use when creating APIs, configuring integrations, setting up authorization, managing stages, implementing rate limiting, or troubleshooting API issues.
1.1k
prisma-client-api

prisma/skills

Complete Prisma Client API reference for model queries, CRUD operations, filtering, relations, and transactions.
10.1k
39