PHPackages                             gabylis/api-foundation - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [HTTP &amp; Networking](/categories/http)
4. /
5. gabylis/api-foundation

ActiveLibrary[HTTP &amp; Networking](/categories/http)

gabylis/api-foundation
======================

Opinionated Laravel API base: structured JSON responses, PHP 8 OpenAPI attributes scaffold, and Artisan generator for documented controllers.

v1.0.0(1mo ago)01↓50%MITPHPPHP ^8.1

Since Jun 16Pushed 1mo agoCompare

[ Source](https://github.com/Gabylis/api-foundation)[ Packagist](https://packagist.org/packages/gabylis/api-foundation)[ RSS](/packages/gabylis-api-foundation/feed)WikiDiscussions main Synced 2w ago

READMEChangelog (1)Dependencies (8)Versions (2)Used By (0)

gabylis/api-foundation
======================

[](#gabylisapi-foundation)

Opinionated Laravel API base package: structured JSON responses, PHP 8 OpenAPI attribute scaffolding, and an Artisan generator for documented controllers.

Built from real production patterns on Laravel + l5-swagger projects.

---

Requirements
------------

[](#requirements)

- PHP 8.1+
- Laravel 10, 11, or 12
- `darkaonline/l5-swagger` ^8.5

---

Installation
------------

[](#installation)

### 1. Install the package

[](#1-install-the-package)

```
composer require gabylis/api-foundation
```

### 2. Install and publish l5-swagger

[](#2-install-and-publish-l5-swagger)

```
composer require darkaonline/l5-swagger
php artisan vendor:publish --provider "L5Swagger\L5SwaggerServiceProvider"
```

### 3. Publish the OpenAPI info file

[](#3-publish-the-openapi-info-file)

```
php artisan vendor:publish --tag=api-foundation-openapi
```

This creates `app/OpenApi/OpenApiInfo.php` — edit it to set your API title, version, server URL, and security scheme:

```
#[OA\Info(
    title: 'My API',
    version: '1.0.0',
    description: 'My API description',
    contact: new OA\Contact(email: 'dev@mycompany.com')
)]
#[OA\Server(url: '/api', description: 'Local')]
#[OA\SecurityScheme(
    securityScheme: 'sanctum',
    type: 'http',
    scheme: 'bearer'
)]
class OpenApiInfo {}
```

### 4. Configure l5-swagger scanning

[](#4-configure-l5-swagger-scanning)

In `config/l5-swagger.php`, set the `annotations` path inside `documentations.default.paths`:

```
'annotations' => [
    base_path('app'),
],
```

> **Note:** You only need to scan `app/` — the published `OpenApiInfo.php` lives there. Do **not** add `vendor/gabylis/api-foundation/src` to the annotations paths, as the package no longer contains any OpenAPI annotations in the vendor folder.

### 5. Generate docs

[](#5-generate-docs)

```
php artisan l5-swagger:generate
```

Open `http://localhost:8000/api/documentation`.

---

What's included
---------------

[](#whats-included)

### `OpenApiInfo.php` (published to `app/OpenApi/`)

[](#openapiinfophp-published-to-appopenapi)

Global OpenAPI metadata — edit freely after publishing. Re-generate docs after any change:

```
php artisan l5-swagger:generate
```

### `ApiBaseController`

[](#apibasecontroller)

Base controller with the `ApiResponse` trait. All your API controllers extend this:

```
use Gabylis\ApiFoundation\Controllers\ApiBaseController;
use OpenApi\Attributes as OA;

#[OA\Tag(name: 'Products', description: 'Product management')]
class ProductApiController extends ApiBaseController
{
    #[OA\Get(
        path: '/products',
        operationId: 'get-products',
        summary: 'List all products',
        tags: ['Products'],
        security: [['sanctum' => []]],
        responses: [
            new OA\Response(response: 200, description: 'Products retrieved successfully'),
        ]
    )]
    public function index(): JsonResponse
    {
        $products = Product::paginate(15);
        return $this->sendPaginatedResponse($products, 'Products retrieved', ProductResource::class);
    }

    public function show(int $id): JsonResponse
    {
        $product = Product::findOrFail($id);
        return $this->sendResponse(new ProductResource($product), 'Product retrieved');
    }

    public function destroy(int $id): JsonResponse
    {
        Product::findOrFail($id)->delete();
        return $this->sendSuccess('Product deleted');
    }
}
```

### `ApiFormRequest`

[](#apiformrequest)

Base form request that always returns JSON on validation failure — no more 302 redirects from APIs:

```
use Gabylis\ApiFoundation\Requests\ApiFormRequest;

class StoreProductRequest extends ApiFormRequest
{
    public function authorize(): bool { return true; }

    public function rules(): array
    {
        return [
            'name'  => 'required|string|max:255',
            'price' => 'required|numeric|min:0',
        ];
    }
}
```

Validation error response (always JSON, status 422):

```
{
    "success": false,
    "status": "failed",
    "message": "The name field is required. The price field is required.",
    "data": {
        "name": ["The name field is required."],
        "price": ["The price field is required."]
    }
}
```

### `make:api-controller` command

[](#makeapi-controller-command)

Generates a fully documented controller with PHP 8 `#[OA\...]` attributes for all CRUD methods:

```
php artisan make:api-controller ProductApiController
php artisan make:api-controller ProductApiController --resource=products --tag="Products"
```

Options:

OptionDescription`--resource`Route resource name (e.g. `products`). Defaults to snake\_case of class name.`--tag`OpenAPI tag label shown in Swagger UI.`--namespace`Override default namespace (`App\Http\Controllers\Api`).`--path`Override output path (`app/Http/Controllers/Api`).`--force`Overwrite existing file.Then add the route and regenerate:

```
# routes/api.php
Route::apiResource('products', ProductApiController::class);

php artisan l5-swagger:generate
```

---

Response envelope
-----------------

[](#response-envelope)

**Success:**

```
{
    "success": true,
    "status": "success",
    "message": "Products retrieved successfully",
    "data": [...]
}
```

**Paginated:**

```
{
    "success": true,
    "status": "success",
    "message": "Products retrieved successfully",
    "data": [...],
    "meta": {
        "per_page": 15,
        "current_page": 1,
        "from": 1,
        "to": 15,
        "last_page": 4,
        "total": 60,
        "next_page_url": "...",
        "previous_page_url": null,
        "path": "...",
        "links": {...}
    }
}
```

**Error:**

```
{
    "success": false,
    "status": "failed",
    "message": "Product not found"
}
```

---

Available methods
-----------------

[](#available-methods)

MethodDescription`sendResponse($data, $message, $status = 200)`Standard success response`sendPaginatedResponse($paginator, $message, $resourceClass = null)`Paginated response with meta`sendError($message, $data = [], $status = 404)`Error response`sendSuccess($message, $status = 200)`Success with message only, no data---

Full setup checklist
--------------------

[](#full-setup-checklist)

```
# 1. Install packages
composer require gabylis/api-foundation darkaonline/l5-swagger

# 2. Publish l5-swagger config
php artisan vendor:publish --provider "L5Swagger\L5SwaggerServiceProvider"

# 3. Publish OpenAPI info file
php artisan vendor:publish --tag=api-foundation-openapi
# → Edit app/OpenApi/OpenApiInfo.php

# 4. Set annotations path in config/l5-swagger.php
# 'annotations' => [ base_path('app') ]

# 5. Generate a documented controller
php artisan make:api-controller ProductApiController --resource=products --tag="Products"

# 6. Add route
# Route::apiResource('products', ProductApiController::class);

# 7. Generate docs
php artisan l5-swagger:generate

# 8. Open http://localhost:8000/api/documentation
```

---

Publishing the stub
-------------------

[](#publishing-the-stub)

To customise the controller generator template:

```
php artisan vendor:publish --tag=api-foundation-stubs
```

This creates `stubs/api-foundation/api-controller.stub` — edit it and the generator will use your version instead of the default.

---

Running tests
-------------

[](#running-tests)

```
composer install
./vendor/bin/pest
```

---

License
-------

[](#license)

MIT

###  Health Score

36

—

LowBetter than 79% of packages

Maintenance90

Actively maintained with recent releases

Popularity1

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity42

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

45d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/96ceb6621776cd0e3c8893b11ffeabcc27c3efa570ce45996912d821174c4f0b?d=identicon)[Gabylis](/maintainers/Gabylis)

---

Top Contributors

[![Gabylis](https://avatars.githubusercontent.com/u/2280335?v=4)](https://github.com/Gabylis "Gabylis (3 commits)")

---

Tags

apilaravelrestswaggeropenapi

###  Code Quality

TestsPest

### Embed Badge

![Health badge](/badges/gabylis-api-foundation/health.svg)

```
[![Health](https://phpackages.com/badges/gabylis-api-foundation/health.svg)](https://phpackages.com/packages/gabylis-api-foundation)
```

###  Alternatives

[api-platform/laravel

API Platform support for Laravel

58174.6k17](/packages/api-platform-laravel)[psalm/plugin-laravel

Psalm plugin for Laravel

3345.3M348](/packages/psalm-plugin-laravel)[laravel/mcp

Rapidly build MCP servers for your Laravel applications.

78622.3M193](/packages/laravel-mcp)[forjedio/inertia-table

Backend-driven dynamic tables for Laravel + Inertia.js

272.0k](/packages/forjedio-inertia-table)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
