PHPackages                             singlequote/laravel-api-resource - 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. [API Development](/categories/api)
4. /
5. singlequote/laravel-api-resource

ActiveLibrary[API Development](/categories/api)

singlequote/laravel-api-resource
================================

2.2.17(2mo ago)61.5k2[1 PRs](https://github.com/singlequote/laravel-api-resource/pulls)MITPHP

Since Mar 21Pushed 2mo ago1 watchersCompare

[ Source](https://github.com/singlequote/laravel-api-resource)[ Packagist](https://packagist.org/packages/singlequote/laravel-api-resource)[ Docs](https://github.com/singlequote/laravel-api-resource)[ RSS](/packages/singlequote-laravel-api-resource/feed)WikiDiscussions main Synced 2w ago

READMEChangelog (10)Dependencies (4)Versions (83)Used By (0)

Laravel API Resource
====================

[](#laravel-api-resource)

[![Latest Version on Packagist](https://camo.githubusercontent.com/e4fa81d0bd676e7d879a488a509079e1d52267f83fe130285487e306473f3826/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f73696e676c6571756f74652f6c61726176656c2d6170692d7265736f757263652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/singlequote/laravel-api-resource)[![Total Downloads](https://camo.githubusercontent.com/43e4bb92956171d73c8d1b8c60757f2f34feea68e7e32182520a3d9266c32ea8/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f73696e676c6571756f74652f6c61726176656c2d6170692d7265736f757263652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/singlequote/laravel-api-resource)

A practical Laravel package designed to streamline API development by automating resource generation and providing a powerful, out-of-the-box filtering system.

This package accelerates your workflow with two core features:

1. **Rapid Scaffolding**: Use the `php artisan make:api-resource` command to intelligently generate a full set of API files (Controller, Actions, Requests, and Resource) from your existing models. Features:

    - Complete Scaffolding: Generates Controller, FormRequests, Actions, and API Resources.
    - Smart Relation Detection: Automatically distinguishes between "Single" relations (e.g., HasOne, BelongsTo) and "Collection" relations (e.g., HasMany, BelongsToMany).
    - Database Driven Validation: Generates validation rules based on your database columns (types, nullable, max length, etc.).
    - Advanced Overwriting: Supports force overwriting and selective generation.

    Route Suggestions: Provides the correct API route definition upon completion.
2. **Powerful Filtering**: Equip your API endpoints with a comprehensive set of filters from the moment you install it. Sort, search, and filter resources with ease without any initial setup.

---

Table of Contents
-----------------

[](#table-of-contents)

- [Installation &amp; Setup](#installation--setup)
- [Usage](#usage)
    - [1. Generating a Full API Resource](#1-generating-a-full-api-resource)
    - [2. Using the API Filters](#2-using-the-api-filters)
    - [3. Customizing the Resource Response](#3-customizing-the-resource-response)
- [API Filtering Reference](#api-filtering-reference)
    - [limit](#limit)
    - [search](#search)
    - [where](#where)
    - [whereIn / whereNotIn](#wherein--wherenotin)
    - [whereNull / whereNotNull](#wherenull--wherenotnull)
    - [has / doesntHave](#has--doesnothave)
    - [whereRelation](#whererelation)
    - [with](#with)
    - [withCount](#withcount)
    - [select](#select)
    - [orderBy / orderByDesc](#orderby--orderbydesc)
    - [Custom Orderable Columns](#custom-orderable-columns)
- [Contributing](#contributing)
- [Postcardware](#postcardware)
- [Credits](#credits)
- [License](#license)

---

Installation &amp; Setup
------------------------

[](#installation--setup)

**1. Install the package via Composer:**

```
composer require singlequote/laravel-api-resource
```

**2. (Optional) Publish Files:**

You can publish the configuration and stub files to customize the package's behavior and generated file templates.

Publish the config file:

```
php artisan vendor:publish --tag=laravel-api-resource-config
```

Publish the stub files:

```
php artisan vendor:publish --tag=laravel-api-resource-stubs
```

---

Usage
-----

[](#usage)

### 1. Generating a Full API Resource

[](#1-generating-a-full-api-resource)

Use the `make:api-resource` Artisan command to generate all the necessary files for a model's API endpoint.

```
php artisan make:api-resource User
```

### Command Options

[](#command-options)

The command supports several options to customize the generation process:

OptionDescription`--force`Overwrite existing files without asking for confirmation. Useful for CI/CD or quick regeneration.`--only`Generate only specific parts. Comma separated. Available: `controller`, `actions`, `requests`, `resource`.`--except`Exclude specific parts from generation. Comma separated.`--module`Specify a module name if you are using a modular application structure.**Example:**

```
php artisan make:api-resource User --force
```

```
php artisan make:api-resource User --only=resource,controller
```

```
php artisan make:api-resource User --except=requests
```

Supported Relations
-------------------

[](#supported-relations)

The generator recognizes a wide range of Eloquent relationships and generates the appropriate code (e.g., new UserResource vs UserResource::collection):

**Single Relations (Returns Object):**

- HasOne
- MorphOne
- BelongsTo
- MorphTo
- HasOneThrough

**Collection Relations (Returns Array):**

- HasMany
- BelongsToMany
- MorphToMany
- MorphMany
- HasManyThrough
- MorphedByMany

Controlling Generation
----------------------

[](#controlling-generation)

You can control which relations are included in the generated API using the `#[SkipApiGeneration]` attribute on your model methods. This attribute accepts an array of scopes to skip:

- `SkipApiGeneration::ALL` (default): Skips generation for everything.
- `SkipApiGeneration::ACTIONS`: Skips generation in Store/Update actions (making the relation read-only).
- `SkipApiGeneration::REQUESTS`: Skips validation rules in Requests.
- `SkipApiGeneration::RESOURCE`: Skips inclusion in the API Resource.

**Example**

```
use SingleQuote\LaravelApiResource\Attributes\SkipApiGeneration;

class User extends Model
{
    // Completely ignore this relation
    #[SkipApiGeneration]
    public function company()
    {
        return $this->belongsTo(Company::class);
    }

    // Read-only: visible in resource, but not updateable via API
    #[SkipApiGeneration([SkipApiGeneration::ACTIONS, SkipApiGeneration::REQUESTS])]
    public function logs()
    {
        return $this->hasMany(Log::class);
    }
}
```

This single command creates the following file structure, ready for you to add your business logic:

```
App/Http/Controllers
└── Api/UserController.php

App/Actions/Users
├── DeleteUserAction.php
├── IndexUserAction.php
├── ShowUserAction.php
├── StoreUserAction.php
└── UpdateUserAction.php

App/Http/Requests/Users
├── IndexUserRequest.php
├── ShowUserRequest.php
├── StoreUserRequest.php
└── UpdateUserRequest.php

App/Http/Resources
└── UserResource.php

```

Finally, add the generated route to your `routes/api.php` file:

```
use App\Http\Controllers\Api\UserController;

Route::apiResource('users', UserController::class);
```

### 2. Using the API Filters

[](#2-using-the-api-filters)

To enable the powerful filtering capabilities, simply add the `HasApi` trait to your model.

```
use Illuminate\Database\Eloquent\Model;
use SingleQuote\LaravelApiResource\Traits\HasApi;

class User extends Model
{
    use HasApi;

    // ...
}
```

You can now use a wide range of query parameters to filter your API results directly from the URL. See the [API Filtering Reference](#api-filtering-reference) below for a full list of available methods.

### 3. Customizing the Resource Response

[](#3-customizing-the-resource-response)

The package provides helpers to easily customize your JSON response. For instance, you can use the `ApiPolicyService` to automatically include the results of your model's policies.

In your `UserResource.php`:

```
use SingleQuote\LaravelApiResource\Service\ApiPolicyService;
use Illuminate\Http\Request;

public function toArray(Request $request): array
{
    return [
        'id' => $this->id,
        'name' => $this->name,
        // ...
        'policies' => ApiPolicyService::defaults($this->resource, ['sendInvite']),
    ];
}
```

---

API Filtering Reference
-----------------------

[](#api-filtering-reference)

All examples use the [Ziggy](https://github.com/tighten/ziggy) package for clean URL generation. A manual URL example is provided for reference.

HelperValue TypeDescription`limit``number`Sets the number of results per page.`search``array`Searches specified columns for a query.`where``array`Adds a "where" clause to the query.`orWhere``array`Adds an "or where" clause.`whereJsonContains``array`Queries a relationship with a `where` condition.`whereJsonDoesntContain``array`Queries a json column with a `whereIn` condition.`whereIn``array`Filters by a column's value within an array.`whereNotIn``array`Filters by a column's value not in an array.`whereNull``string`Finds records where a column is NULL.`whereNotNull``string`Finds records where a column is not NULL.`has``array`Filters based on the existence of a relationship.`doesntHave``array`Filters based on the absence of a relationship.`whereRelation``array`Queries a relationship with a `where` condition.`with``array`Eager loads relationships.`withCount``array`Counts the results of a given relationship.`select``array`Selects specific columns to return.`orderBy``string`Sorts the results in ascending order.`orderByDesc``string`Sorts the results in descending order.### limit

[](#limit)

The default limit is `1000`. You can change this in the config file or override it per request.

```
axios.get(route('api.users.index', { limit: 100 }));
// GET /api/users?limit=100
```

### search

[](#search)

Search for a query within specified columns. Use `*` to search all fillable columns.

```
axios.get(route('api.users.index', {
    search: {
        fields: ['name', 'email'],
        query: "john"
    }
}));
// GET /api/users?search[fields][0]=name&search[fields][1]=email&search[query]=john
```

### where

[](#where)

Add "where" clauses. You can also provide an operator (`gt`, `lt`, `sw`, etc.).

OperatorShorthandstartsWith`sw`endsWith`ew`notContains`nin`contains`in`equals`eq`notEqual`neq`greater`gt`greaterEquals`gte`lesser`lt`lesserEquals`lte````
axios.get(route('api.users.index', {
    where: {
        date_of_birth: { gt: "1995-01-31" }
    }
}));
// GET /api/users?where[date_of_birth][gt]=1995-01-31
```

### whereJsonContains / whereJsonDoesntContain

[](#wherejsoncontains--wherejsondoesntcontain)

Verifies that a column's value is (or is not) within a given array.

```
axios.get(route('api.users.index', {
    whereJsonContains: { data->language: ['en', 'nl'] }
}));
// GET /api/users?whereJsonContains[data->language][0]=en&whereJsonContains[data->language][1]=nl
```

### whereIn / whereNotIn

[](#wherein--wherenotin)

Verifies that a column's value is (or is not) within a given array.

```
axios.get(route('api.users.index', {
    whereIn: { role: ['admin', 'employee'] }
}));
// GET /api/users?whereIn[role][0]=admin&whereIn[role][1]=employee
```

### whereNull / whereNotNull

[](#wherenull--wherenotnull)

Verifies that a column's value is `NULL` or not `NULL`.

```
axios.get(route('api.users.index', { whereNull: "email_verified_at" }));
// GET /api/users?whereNull=email_verified_at
```

### has / doesntHave

[](#has--doesnthave)

Limit results based on the existence of a relationship. You can also add nested conditions.

```
axios.get(route('api.users.index', {
    has: {
        roles: {
            whereIn: { id: [1, 2] }
        }
    }
}));
// GET /api/users?has[roles][whereIn][id][0]=1&has[roles][whereIn][id][1]=2
```

### whereRelation

[](#whererelation)

Query for a relationship's existence with a simple `where` condition.

```
axios.get(route('api.users.index', {
    whereRelation: {
        roles: { name: 'admin' }
    }
}));
// GET /api/users?whereRelation[roles][name]=admin
```

### with

[](#with)

Eager load relationships to avoid N+1 query problems.

```
axios.get(route('api.users.index', {
    with: {
        roles: {
            select: ['id', 'name']
        }
    }
}));
// GET /api/users?with[roles][select][0]=id&with[roles][select][1]=name
```

### withCount

[](#withcount)

Count the number of results from a relationship without loading them.

```
axios.get(route('api.users.index', { withCount: ['posts'] }));
// GET /api/users?withCount[0]=posts
```

**Note:** To include the count in your response, you must manually add the `posts_count` attribute to your resource's `toArray` method.

```
// In app/Http/Resources/UserResource.php
public function toArray(Request $request): array
{
    return [
        // ... other attributes
        'posts_count' => $this->whenCounted('posts'),
    ];
}
```

### select

[](#select)

Specify which columns to retrieve to keep responses lean.

```
axios.get(route('api.users.index', { select: ['id', 'name'] }));
// GET /api/users?select[0]=id&select[1]=name
```

### orderBy / orderByDesc

[](#orderby--orderbydesc)

Sort the results by a given column, including columns on related models.

```
axios.get(route('api.users.index', { orderBy: 'roles.name' }));
// GET /api/users?orderBy=roles.name
```

### Custom Orderable Columns

[](#custom-orderable-columns)

To make custom columns (e.g., from `withCount` or `withSum`) sortable, add them to the `$apiOrderBy` property on your model.

```
// In your Product.php model
class Product extends Model
{
    public array $apiOrderBy = [
        'articles_sum_price', // From a withSum query
    ];
}
```

Now you can sort by this custom column: `GET /api/products?orderBy=articles_sum_price`

---

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details.

---

Postcardware
------------

[](#postcardware)

You're free to use this package, but if it makes it to your production environment, we highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using.

Our address is: Quotec, Traktieweg 8c 8304 BA, Emmeloord, Netherlands.

---

Credits
-------

[](#credits)

- [Wim Pruiksma](https://github.com/wimurk)
- [All Contributors](../../contributors)

---

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

48

—

FairBetter than 94% of packages

Maintenance84

Actively maintained with recent releases

Popularity26

Limited adoption so far

Community12

Small or concentrated contributor base

Maturity57

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 97.2% 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

Every ~9 days

Recently: every ~29 days

Total

80

Last Release

81d ago

Major Versions

1.1.18 → 2.0.02024-07-16

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/14072334?v=4)[Wimurk](/maintainers/wimurk)[@wimurk](https://github.com/wimurk)

---

Top Contributors

[![wimurk](https://avatars.githubusercontent.com/u/14072334?v=4)](https://github.com/wimurk "wimurk (176 commits)")[![hyoukax](https://avatars.githubusercontent.com/u/122445723?v=4)](https://github.com/hyoukax "hyoukax (4 commits)")[![maxquotec](https://avatars.githubusercontent.com/u/185365416?v=4)](https://github.com/maxquotec "maxquotec (1 commits)")

###  Code Quality

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/singlequote-laravel-api-resource/health.svg)

```
[![Health](https://phpackages.com/badges/singlequote-laravel-api-resource/health.svg)](https://phpackages.com/packages/singlequote-laravel-api-resource)
```

###  Alternatives

[exsyst/swagger

A php library to manipulate Swagger specifications

35816.3M7](/packages/exsyst-swagger)[hubspot/api-client

Hubspot API client

24015.5M18](/packages/hubspot-api-client)[botman/driver-telegram

Telegram driver for BotMan

93452.6k6](/packages/botman-driver-telegram)

PHPackages © 2026

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