PHPackages                             mleczek/laravel-rest - 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. mleczek/laravel-rest

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

mleczek/laravel-rest
====================

Laravel package with a set of helpful tools for building REST API.

v1.2.2(5y ago)5592[1 PRs](https://github.com/mleczek/laravel-rest/pulls)MITPHPCI passing

Since Jan 2Pushed 3mo ago1 watchersCompare

[ Source](https://github.com/mleczek/laravel-rest)[ Packagist](https://packagist.org/packages/mleczek/laravel-rest)[ Docs](https://github.com/mleczek/laravel-rest)[ RSS](/packages/mleczek-laravel-rest/feed)WikiDiscussions master Synced 2mo ago

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

Laravel REST Package
====================

[](#laravel-rest-package)

[![Latest Stable Version](https://camo.githubusercontent.com/e48a4eb1ecd607482c6febc96e2264e030d9376e254a251b5868d64e2175fa92/68747470733a2f2f706f7365722e707567782e6f72672f6d6c65637a656b2f6c61726176656c2d726573742f762f737461626c65)](https://packagist.org/packages/mleczek/laravel-rest)[![Build Status](https://camo.githubusercontent.com/d86f3195fadf9f668e5173f55712b83d02e93aeb9cc97ca173ca10b681267cd1/68747470733a2f2f7472617669732d63692e6f72672f6d6c65637a656b2f6c61726176656c2d726573742e737667)](https://travis-ci.org/mleczek/laravel-rest)[![License](https://camo.githubusercontent.com/ae5e537435ca26dbb8022202b6b093f1765ea8f811d758d1e1797db6bcf7161b/68747470733a2f2f706f7365722e707567782e6f72672f6d6c65637a656b2f6c61726176656c2d726573742f6c6963656e7365)](https://packagist.org/packages/mleczek/laravel-rest)

Laravel package with a set of tools helpful for building REST API.

- [Installation](#installation)
- [Configuration](#configuration)
- [Usage](#basic-usage)
    - [Query params](#query-params)
        - [With](#with)
        - [Offset](#offset)
        - [Limit](#limit)
        - [Fields](#fields)
        - [Sort](#sort)
        - [Filter](#filter)
    - [Responses](#responses)
        - [Item](#item)
        - [Collection](#collection)
        - [Accepted](#accepted)
        - [No Content](#no-content)
        - [Created](#created)
        - [Updated](#updated)
        - [Patched](#patched)
        - [Deleted](#deleted)
- [Tips and tricks](#tips-and-tricks)
    - [Default Context](#default-context)
- [Contributing](#contributing)
- [License](#license)

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

[](#installation)

To install this package you will need:

- Laravel 5.3+
- PHP 5.6.4+

Require this package with composer:

```
composer require mleczek/laravel-rest

```

In `config/app.php` add the `RestServiceProvider`:

```
'providers' => [
    Mleczek\Rest\RestServiceProvider::class,
]
```

Configuration
-------------

[](#configuration)

Publish the package configuration and `ContextServiceProvider`:

```
php artisan vendor:publish --provider="Mleczek\Rest\RestServiceProvider"

```

This command will create 2 files for you:

- `config/rest.php`
- `app/Providers/ContextServiceProvider.php`

Register new local copy of the `ContextServiceProvider` in the `config/app.php` file:

```
'providers' => [
    App\Providers\ContextServiceProvider::class,
]
```

Usage
-----

[](#usage)

### Query params

[](#query-params)

Supplied by the client. They control the format of the response most often by narrowing result.

#### With

[](#with)

Include related data in response:

```
users?with=messages,permissions

```

In the background the library will attach related models using Eloquent defined relations, which is quite similar to calling `$quer->with(['messages', 'permissions'])`.

By default all relations are disabled, which means that you have to explicitly define which relations can be used in API call. You can set up this in the previously published `ContextServiceProvider`:

```
$with = [
    User::class => 'messages',
    Message::class => ['author', 'recipient'],
]
```

If you'd like to do some policy checks then you can define context class. In this class you can create methods which name is equal to the relation name. Whenever you try to access this relation the new instance of this class will be created and the result of the method will determine if the relation can be used or not.

```
class UserWithContext
{
    public function messages()
    {
        return Auth::check() && Auth::user()->is_root;
    }
}
```

Of course you have to register that context in the `ContextServiceProvider`:

```
$with = [
    User::class => UserWithContext::class,
]
```

Now if someone without root access call the `with=messages` then nothing will happen. If you'd like you can throw 401 or 403 response code from the context class.

In `UserWithContext` class and other context classes you can inject your dependencies in the constructor, because class is resolved using service container.

#### Offset

[](#offset)

Skip *n* first items:

```
users?offset=3

```

You can use this as well for the related data:

```
users?with=messages&offset=3,messages.5

```

#### Limit

[](#limit)

Limit results to *n* items:

```
users?limit=5

```

You can use this as well for the related data:

```
users?with=messages&limit=messages.1

```

#### Fields

[](#fields)

Get only specified fields:

```
users?fields=first_name,last_name

```

You can use this as well for the related data:

```
users?with=messages&fields=first_name,last_name,messages.id

```

If you specify fields only for the primary model then all fields will be retrieved for the related one:

```
users?with=messages&fields=first_name,last_name

```

Above example will return `first_name`, `last_name` and all columns for the messages model (eq. `id`, `author_id`, `recipient_id`, `content`). This helps in finding a sub-optimal query - if you don't want any field from the related model then just simply remove redundant values from the `with`query param.

#### Sort

[](#sort)

Return results in specified order:

```
users?sort=score,last_name_desc

```

You can use this as well for the related data:

```
users?with=messages&sort=messages.latest

```

By default no sort methods are available, which means that you have to explicitly define sort that can be used for specific model. You can set up this in the previously published `ContextServiceProvider`:

```
$sort = [
    Message::class => MessageSortContext::class,
]
```

Then you have to create context class. Sort name will be converted to method name using camelCase style (eq. `last_name_desc` will call `lastNameDesc` method). As a first argument you will receive the `Illuminate\Database\Query\Builder`.

```
class MessageSortContext
{
    public function latest($query)
    {
        $query->latest();
    }
}
```

Now you can sort messages using `latest` method in any context:

```
users?with=messages&sort=messages.latest
messages?with=author&sort=latest

```

In `MessageSortContext` class and other context classes you can inject your dependencies in the constructor, because class is resolved using service container.

#### Filter

[](#filter)

Put constraint on request:

```
users?filter=score_above:30,last_name_in:[Smith,Bloggs]

```

Unlike `sort` param the `filter` query param can also accept arguments:

```
users?filter=without_args
users?filter=one_arg:5
users?filter=special_chars:"O'X\" []],,"
users?filter=two_or_more_args:[12,"Lorem lipsum"]

```

You can use this as well for the related data:

```
users?with=messages&filter=messages.recipient_id:5

```

By default no filter methods are available, which means that you have to explicitly define filters that can be used for specific model. You can set up this in the previously published `ContextServiceProvider`:

```
$filter = [
    User::class => UserFilterContext::class,
]
```

Then you have to create context class. Filter name will be converted to method name using camelCase style (eq. `last_name_in` will call `lastNameIn` method). As a first argument you will receive the `Illuminate\Database\Query\Builder`.

```
class UserFilterContext
{
    public function scoreAbove($query, $value)
    {
        // Validation of the $value argument...

        $query->where('score', '>', $value);
    }
}
```

Now you can filter users using `scoreAbove` method in any context:

```
users?filter=score_above:15
groups?with=users&filter=users.score_above:5

```

In `UserFilterContext` class and other context classes you can inject your dependencies in the constructor, because class is resolved using service container.

### Responses

[](#responses)

Library extends the `Response` class using some helpful macros.

#### Item

[](#item)

```
response()->item($query);
```

Response single model item with response code `200 OK`:

```
return response()->item(User::query());
```

This macro will use the `fields` and `with` query param.

This is not recommended to use `with`, `select` and `addSelect` on the `$query`parameter passed to the method. After all if you would like to do this the behavior it is as follows:

- if someone pass the same relation name in `with` query param the one you created will be overridden
- if someone pass the `fields` query parameter then only fields specified in this parameter will be returned

Often you will need to do some operations using retrieved model, in this case use `rest()` helper funtion:

```
public function show()
{
    $user = rest()->item(User::query());
    $this->authorize('show', $user); // bad usage, see below solution

    return response()->item($user);
}
```

The above example has one major defect, the second argument passed to the `authorize` can contain only fields specified in the `fields` query param. The better solution is to retrieve the whole model, call `authorize` method and then apply the query param transformations:

```
public function show()
{
    $user = User::first();
    $this->authorize('show', $user);

    return response()->item($user);
}
```

Summarizing, the `response()->item()` macro can accept the `Illuminate\Database\Eloquent\Model` or `Illuminate\Database\Eloquent\Builder` object.

#### Collection

[](#collection)

```
response()->collection($query);
```

Response collection of models with response code `206 Partial Content`:

```
return response()->collection(User::query());
```

This macro will use the `fields`, `sort`, `filter`, `offset`, `limit`and `with` query param. Again, using `orderBy`, `select`, `addSelect`, `limit/take`, `offset/skip` methods on the `$query` argument is not recommended, but fell free to add some constraints using `where` method.

```
return response()->collection(User::where('is_root', false));
```

If you will need to make some operations before returning response you can use `rest()` helper function:

```
public function show()
{
    $users = rest()->collection(User::query());
    // Some operations goes here...
    // $users->count  - number of retrieved models [0,limit]
    // $users->limit  - max number of retrieved models
    // $users->offset - number of skipped models
    // $users->data   - retrieved models

    return response()->collections($users);
}
```

#### Accepted

[](#accepted)

```
response()->accepted();
```

Empty response with status code `202 Accepted`.

#### No Content

[](#no-content)

```
response()->noContent();
```

Empty response with status code `204 No Content`.

#### Created

[](#created)

```
response()->created($model[, $location]);
```

Response created model with status code `201 Created`. If `$location` is specified then appropriate `Location` header will be added to the response.

#### Updated

[](#updated)

```
response()->updated([$model]);
```

Response updated model (if provided) with status code `200 OK`.

#### Patched

[](#patched)

```
response()->patched([$model]);
```

Response part of updated model (if provided) with status code `200 OK`.

#### Deleted

[](#deleted)

```
response()->deleted();
```

Empty response with status code `204 No Content`.

Tips and tricks
---------------

[](#tips-and-tricks)

### Default Context

[](#default-context)

By default library implements 2 context classes:

```
protected $sort = [
    // Your context classes...
    User::class => \Mleczek\Rest\Context\DefaultSortContext::class,
];

protected $filter = [
    // Your context classes...
    User::class => \Mleczek\Rest\Context\DefaultFilterContext::class,
];
```

These context can be used with any class and allow sorting and filtering using fillable attributes. Example usage for the default User model:

```
// ?filter=:
users?filter=email:"rest@example.com"
users?filter=password:some_string // side effect

// ?sort= or ?sort=_desc
users?sort=name,email_desc
users?sort=name_desc

```

**It's recommended to use only for the dev purposes**. In future releases implementation will change in order to prevent accidental security vulnerabilities (like the above one with password column). Any ideas are welcome.

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

[](#contributing)

Thank you for considering contributing! If you would like to fix a bug or propose a new feature, you can submit a Pull Request.

License
-------

[](#license)

The library is licensed under the [MIT license](http://opensource.org/licenses/MIT).

###  Health Score

39

—

LowBetter than 86% of packages

Maintenance54

Moderate activity, may be stable

Popularity14

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity68

Established project with proven stability

 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

Every ~266 days

Recently: every ~325 days

Total

6

Last Release

2083d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/143e31568d2a8cef787b416fd2b5f10b78d28cb141ffe049c197d7fb31dc911c?d=identicon)[mleczek](/maintainers/mleczek)

---

Top Contributors

[![mleczek](https://avatars.githubusercontent.com/u/15350415?v=4)](https://github.com/mleczek "mleczek (20 commits)")

---

Tags

apilaravelphprestapilaravelrest

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/mleczek-laravel-rest/health.svg)

```
[![Health](https://phpackages.com/badges/mleczek-laravel-rest/health.svg)](https://phpackages.com/packages/mleczek-laravel-rest)
```

###  Alternatives

[api-platform/laravel

API Platform support for Laravel

59126.4k6](/packages/api-platform-laravel)[marcelgwerder/laravel-api-handler

Package providing helper functions for a Laravel REST-API

16092.6k](/packages/marcelgwerder-laravel-api-handler)[bjerke/api-query-builder

A query builder for Laravel that parses the request and uses Eloquent ORM to query database

267.7k1](/packages/bjerke-api-query-builder)[dragon-code/laravel-http-logger

Logging incoming HTTP requests

319.8k3](/packages/dragon-code-laravel-http-logger)[bjerke/laravel-bread

A boilerplate package for BREAD operations through REST API in Laravel

115.2k](/packages/bjerke-laravel-bread)[laragear/api-manager

Manage multiple REST servers to make requests in few lines and fluently.

161.8k](/packages/laragear-api-manager)

PHPackages © 2026

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