PHPackages                             tomhart/laravel-restful-controller - 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. [Framework](/categories/framework)
4. /
5. tomhart/laravel-restful-controller

ActiveLibrary[Framework](/categories/framework)

tomhart/laravel-restful-controller
==================================

Laravel Restful Controller

1.6.6(5y ago)029[4 PRs](https://github.com/TomHart/laravel-restful-controller/pulls)MITPHPPHP ^7.2

Since Jan 9Pushed 3y ago1 watchersCompare

[ Source](https://github.com/TomHart/laravel-restful-controller)[ Packagist](https://packagist.org/packages/tomhart/laravel-restful-controller)[ Docs](https://github.com/)[ RSS](/packages/tomhart-laravel-restful-controller/feed)WikiDiscussions master Synced yesterday

READMEChangelog (10)Dependencies (9)Versions (28)Used By (0)

Laravel Restful Controller
==========================

[](#laravel-restful-controller)

[![Build Status](https://camo.githubusercontent.com/52293f0dde55f4032b6c0e6463b2611ee9042be17cd3089cf09cefc16b99bd99/68747470733a2f2f7472617669732d63692e636f6d2f546f6d486172742f6c61726176656c2d7265737466756c2d636f6e74726f6c6c65722e7376673f6272616e63683d6d6173746572)](https://travis-ci.com/TomHart/laravel-restful-controller)[![codecov](https://camo.githubusercontent.com/a7f48e1e91006285be26c7421d5a784059d99b324c3f9c34c81d6d1d88cc77e9/68747470733a2f2f636f6465636f762e696f2f67682f546f6d486172742f6c61726176656c2d7265737466756c2d636f6e74726f6c6c65722f6272616e63682f6d61737465722f67726170682f62616467652e737667)](https://codecov.io/gh/TomHart/laravel-restful-controller)[![Scrutinizer Code Quality](https://camo.githubusercontent.com/3eb0a92329910f526ed3cfd1d3d6ca8dc9429d0b9baa6ef8f436639fe8c8658b/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f546f6d486172742f6c61726176656c2d7265737466756c2d636f6e74726f6c6c65722f6261646765732f7175616c6974792d73636f72652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/TomHart/laravel-restful-controller/?branch=master)[![GitHub release (latest by date)](https://camo.githubusercontent.com/91d948a00d0cd481f8b04fde6d8665c8c7748cb0a214bdc9f39aefd2606c732a/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f72656c656173652f546f6d486172742f6c61726176656c2d7265737466756c2d636f6e74726f6c6c65723f636f6c6f723d677265656e)](https://camo.githubusercontent.com/91d948a00d0cd481f8b04fde6d8665c8c7748cb0a214bdc9f39aefd2606c732a/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f72656c656173652f546f6d486172742f6c61726176656c2d7265737466756c2d636f6e74726f6c6c65723f636f6c6f723d677265656e)[![License: GPL v3](https://camo.githubusercontent.com/48bf9b56d44f38db53ce21294cf0b9487d0a3734ab3ba1fe4c69858ae20db2c1/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d47504c76332d626c75652e737667)](https://www.gnu.org/licenses/gpl-3.0)

This library adds an `AbstractRestfulController` to to be basic heavy lifting of a CRUD controller.

- [Installation](#installation)
- [Usage](#usage)
    - [Relationships](#relationships)
        - [Loading Relationships](#loading-relationships)
        - [Accessing Relationships](#accessing-relationships)
    - [Restricting Access to Models](#restricting-access-to-models)
        - [Index page](#index-page)
        - [Show, Update, and Destroy Pages](#show-update-and-destroy-pages)
    - [Manipulating models before saving or updating](#manipulating-models-before-saving-or-updating)
    - [Pagination](#pagination)
    - [Filtering](#filtering)
    - [HasLinks](#haslinks)
    - [Builder](#builder)

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

[](#installation)

You can install this package via composer using this command:

`composer require tomhart/laravel-restful-controller`

Usage
-----

[](#usage)

- Create a controller extending from this, and implement the method `getModelClass`

```
use TomHart\Restful\AbstractRestfulController;

class BlogController extends AbstractRestfulController
{
    /**
     * What Model class to search for entities.
     * @return string
     */
    protected function getModelClass(): string
    {
        return Blog::class;
    }
}
```

- If you want it to render views for index, show, or store, add a `$views` property

```
    /**
     * The views to render.
     * @var array
     */
    protected $views = [
        'index' => 'blog/index',
        'show' => 'blog/show',
        'store' => 'blog/store'
    ];
```

If `$views` is empty, the specified view doesn't exist, or the `Accept` header is `application/json`, then JSON is returned

- Define a resource route

```
Route::resource('blogs', 'BlogController');
```

Note this also would define a `blogs.show.extra`, and `blogs.show.options` route which will be explained later.

Example response for: `/blogs/1`

```
{
    "id": 1,
    "title":  "My Blog Post",
    "content":  "TitleSome Content"
}
```

### Relationships

[](#relationships)

#### Loading Relationships

[](#loading-relationships)

The show route can return your models relationships. If you send a `X-Load-Relationship` header, with a comma separated value list of headers to load. See the `testRelationshipsCanBeReturned` test for an example.

Example response for: `/blogs/1` with `X-Load-Relationship: comments`

```
{
    "id": 1,
    "title":  "My Blog Post",
    "content":  "TitleSome Content",
    "comments": [
        {
            "id": 1,
            "comment": "Great post!"
        },
        {
            "id": 2,
            "comment": "I enjoyed reading this"
        }
    ]
}
```

#### Accessing Relationships

[](#accessing-relationships)

You can drill into a relationship using the `.show.extra` route mentioned above. If the first `comment` had an author and you wanted to see, via the blog resources, you can call `/blogs/1/comments[0]/author`

```
{
    "id": 1,
    "name": "Joe Bloggs"
}
```

You can dynamically build the route using

```
route('blogs.show.extra', [
    'blog' => 1,
    'extra' => 'comments[0]/author'
]);
```

### Restricting Access to Models

[](#restricting-access-to-models)

You'll most likely want to restrict access to certain models, e.g. only load the logged in users posts. To do that, there's a few methods you can overwrite.

#### Index Page

[](#index-page)

In order to restrict the models returned by the index route, e.g. a paginated list of many models, overwrite the `createModelQueryBuilder` method.

#### Show, Update, and Destroy Pages

[](#show-update-and-destroy-pages)

In order to restrict which indiviual models can be shown, updated, or deleted, overwrite the `findModel` method.

### Manipulating models before saving or updating

[](#manipulating-models-before-saving-or-updating)

If you want to manipulate the model before they are saved, or updated, e.g. setting the user\_id to the current logged in user, override the `saveModel` method.

### Pagination

[](#pagination)

By default the `index` route, and any relationships it's trying to load will be paginated if possible.

Example response for: `/blogs`

```
{
   "total": 50,
   "per_page": 15,
   "current_page": 1,
   "last_page": 4,
   "first_page_url": "http://laravel.app?page=1",
   "last_page_url": "http://laravel.app?page=4",
   "next_page_url": "http://laravel.app?page=2",
   "prev_page_url": null,
   "path": "http://laravel.app",
   "from": 1,
   "to": 15,
   "data":[
        {
            "id": 1
        },
        {
            "id": 2
        }
   ]
}
```

### Filtering

[](#filtering)

You can filter the `index` route via a query string, e.g. `?name=test`.

### HasLinks

[](#haslinks)

This library also provides `HasLinks` interface, and a `HasLinksTrait` to provide a default implementation. If you apply those to your models, the responses will contain a `_links` key to help your consumers navigate around and use your API.

Example `_links` for `/blogs/1`:

```
{
    "id": 1,
    "title": "My Blog",
    "content": "See some _links!",
    "_links": {
        "index": {
            "method":  "get",
            "href": {
                "relative": "/blogs/",
                "absolute": "https://api.example.com/blogs/"
            }
        },
        "create": {
            "method":  "get",
            "href": {
                "relative": "/blogs/",
                "absolute": "https://api.example.com/blogs/"
            }
        },
        "store": {
            "method":  "post",
            "href": {
                "relative": "/blogs/",
                "absolute": "https://api.example.com/blogs/"
            }
        },
        "show": {
            "method":  "get",
            "href": {
                "relative": "/blogs/1",
                "absolute": "https://api.example.com/blogs/1"
            }
        },
        "update": {
            "method":  "put",
            "href": {
                "relative": "/blogs/1",
                "absolute": "https://api.example.com/blogs/1"
            }
        },
        "destroy": {
            "method":  "delete",
            "href": {
                "relative": "/blogs/1",
                "absolute": "https://api.example.com/blogs/1"
            }
        }
    }
}
```

The `.options` route mentioned earlier will simply return the `index`, `create`, and `store` `_links` for the resource so you can query the endpoint and get the URLs needing to interfacing with the API.

If you send `{"id": X}`, it'll also build the `show`, `update`, and `delete` routes with the ID supplied.

### Builder

[](#builder)

This library also includes a `Builder` class to interface with the API from a consumer view. It supports the standard `get`, `insert`, `update`, and `delete` methods.

Example:

```
use TomHart\Restful\Builder;

$models = Builder::model(MyModel::class)->where('name', 'test')->get(); // Collection

$modelWasInserted = Builder::model(MyModel::class)->insert(['name' => 'test']); //bool

$modelWasUpdated = Builder::model(MyModel::class)->update(1, ['name' => 'test']); //bool

$modelWasDeleted = Builder::model(MyModel::class)->delete(1); //bool
```

To use it with your model simply add `implements Restful`, and use the trait `InteractsWithRest`

###  Health Score

27

—

LowBetter than 49% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity7

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity62

Established project with proven stability

 Bus Factor1

Top contributor holds 83% 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 ~10 days

Recently: every ~41 days

Total

17

Last Release

2143d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/1374434?v=4)[Tom Hart](/maintainers/TomHart)[@TomHart](https://github.com/TomHart)

---

Top Contributors

[![tom-hart-sky-uk](https://avatars.githubusercontent.com/u/219799917?v=4)](https://github.com/tom-hart-sky-uk "tom-hart-sky-uk (44 commits)")[![TomHart](https://avatars.githubusercontent.com/u/1374434?v=4)](https://github.com/TomHart "TomHart (8 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (1 commits)")

---

Tags

laravelcontrollerrestfultomhart

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP\_CodeSniffer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/tomhart-laravel-restful-controller/health.svg)

```
[![Health](https://phpackages.com/badges/tomhart-laravel-restful-controller/health.svg)](https://phpackages.com/packages/tomhart-laravel-restful-controller)
```

###  Alternatives

[laravel/cashier

Laravel Cashier provides an expressive, fluent interface to Stripe's subscription billing services.

2.5k25.9M107](/packages/laravel-cashier)[laravel/boost

Laravel Boost accelerates AI-assisted development by providing the essential context and structure that AI needs to generate high-quality, Laravel-specific code.

3.4k10.6M274](/packages/laravel-boost)[laravel/socialite

Laravel wrapper around OAuth 1 &amp; OAuth 2 libraries.

5.7k96.9M674](/packages/laravel-socialite)[laravel/pulse

Laravel Pulse is a real-time application performance monitoring tool and dashboard for your Laravel application.

1.7k12.1M99](/packages/laravel-pulse)[laravel/cashier-paddle

Cashier Paddle provides an expressive, fluent interface to Paddle's subscription billing services.

264778.4k3](/packages/laravel-cashier-paddle)[laravel/dusk

Laravel Dusk provides simple end-to-end testing and browser automation.

1.9k36.7M259](/packages/laravel-dusk)

PHPackages © 2026

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