PHPackages                             mdantas/express-request - 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. mdantas/express-request

ActiveCakephp-plugin

mdantas/express-request
=======================

ExpressRequest plugin for CakePHP

v2.1.9(3y ago)21191MITPHPPHP &gt;=7.4CI failing

Since Jul 15Pushed 3y ago2 watchersCompare

[ Source](https://github.com/lpj145/express-request)[ Packagist](https://packagist.org/packages/mdantas/express-request)[ RSS](/packages/mdantas-express-request/feed)WikiDiscussions master Synced 1w ago

READMEChangelog (2)Dependencies (2)Versions (14)Used By (0)

ExpressRequest plugin for CakePHP
=================================

[](#expressrequest-plugin-for-cakephp)

Something about package
-----------------------

[](#something-about-package)

This package help me a lot with query url, maybe it will help you, often when I try to make api's I tried to make complex url, complex querystring parameters and I felt frustrated, because something did not make sense. After poc's and poc's and good companion's help, I've come to this conclusion.

### How this package can help you

[](#how-this-package-can-help-you)

Instead of make more and more complex url query params or many endpoints, let's try to produce what really model can be to customers, goto code.

### Installation

[](#installation)

You can install this plugin into your CakePHP application using [composer](https://getcomposer.org).

The recommended way to install composer packages is:

```
composer require mdantas/express-request

```

Add plugin to our `Application.php`

```
public function bootstrap(): void
{
    //... other codes.
    $this->addPlugin('ExpressRequest');
}
```

### Express your filter's on model

[](#express-your-filters-on-model)

Our table object needed implement `ExpressRepositoryInterface`make new methods.

```
//Model/Table/DomainsTable.php
class DomainsTable extends Table implements ExpressRepositoryInterface {
    //...code...

    public function getFilterable(): FiltersCollection
    {
        return new FiltersCollection([
            new BooleanFilter('active'),
            new SearchFilter('name', SearchFilter::START_STRATEGY),
            new SearchDateFilter('created_at'),
            new NumberFilter('price'),
            new SearchInFilter('type')
        ]);
    }

    public function getSelectables(): array
    {
        return [
            'name',
            'created_at',
            'price',
            'type',
            'active'
        ];
    }
}
```

### Controller

[](#controller)

In `Controller/AppController.php` load component called: `ExpressRequest.ExpressParams`and now, add some code to our DomainsController.

```
//Controller/DomainsController.php

public function index()
{
    // The finder need to be a method what return a Cake\ORM\Query object.
    return $this
        ->responseJson(
            $this->ExpressRequest->search(
                $this->request,
                $this->Domains,
                'findDomainsByCompany', // Finder model method optional
                $companyId // Optional
            )
        );
}

public function anotherWay() {
   // We can make our filtering by request expressions
   $collection = $this->ExpressRequest->search(
                $this->request,
                $this->Domains
            );

   $query = $collection->getQuery();

   // And can implement our needed things above user api expressions.
   $query->where(['id' => 1]);
   return $this->responseJson($collection);
}

public function alternative()
{
    // Request and Model now is taked from controller.
    // Need status code
    // Return a ResponseInterface from psr with json data on body.
    return this->ExpressRequest->getResponse(200);
}
```

`*Of course, don't forget to add a route to this controller.`

```
//routes.php
$routes->scope('/', function (RouteBuilder $builder) {
    $builder->get('/domains', ['controller' => 'Domains', 'action' => 'index']);
}
```

### Request

[](#request)

Let's see how your `/domains` endpoint is now more friendly for the requests/resources.

Open in the browser: `http://localhost:8765/domains?price=140..3000&sort[price]=asc&type[not]=profit&size=1`

```
// http://localhost:8765/domains?price=140..3000&sort[price]=asc&type[not]=profit&size=1

{
  "data": [
    {
      "id": "dee7b40b-df70-33b7-90e0-1d13a4b13693",
      "name": "Azevedo e Pacheco",
      "company_id": "2130a414-828a-4ae3-a3a6-5f153fe25ad8",
      "city_id": 2507705,
      "created_at": "2010-02-12T21:18:44+00:00",
      "modified_at": null,
      "price": "291.600",
      "type": "purchase"
    }
  ],
  "meta": {
    "total": 103,
    "per_page": 1,
    "current_page": 1,
    "last_page": 103,
    "first_page_url": "http://localhost:8765/domains?price=140..3000&sort%5Bprice%5D=asc&type%5Bnot%5D=profit&size=1&page=1",
    "next_page_url": "http://localhost:8765/domains?price=140..3000&sort%5Bprice%5D=asc&type%5Bnot%5D=profit&size=1&page=2",
    "last_page_url": "http://localhost:8765/domains?price=140..3000&sort%5Bprice%5D=asc&type%5Bnot%5D=profit&size=1&page=103",
    "prev_page_url": null,
    "path": "http://localhost:8765/domains",
    "from": 1,
    "to": 1
  }
}
```

### Details

[](#details)

I've talked about this help me a lot, right? now, see how this stuff works.

Every requests is treat on `ExpressRequest.ExpressParams` this component try to understand what the request need and with help of model it reproduces a response, some operations or conditions by the users can be dangerous or simple introduces requests errors on application because the request is wrong, for this reason, model express to component what it can do, if it can't, nothing occur, and think, what if we try to search 'A' on boolean typed data? For this reason some typed filters are implemented.

### Select only fields.

[](#select-only-fields)

```
// localhost/domains?props=name,price,created_at - Select only this three fields.
```

### Sorting data

[](#sorting-data)

for each field, have two values: asc, desc.

```
// localhost/domains?sort[name]=asc
// localhost/domains?sort[name]=asc&sort[price]=desc
```

### Contained data

[](#contained-data)

Sometimes we need to retrieve data with relationship, of course, it's can be easily.

```
// http://localhost:8765/domains?nested=users,comments //Get data with relationship
```

Need to add complex or conditions to your related data, the simple awnser is: you can't, and you shouldn't try, if you need some complex related data see: [CakePHP docs](https://book.cakephp.org/4/en/orm/associations.html#using-association-finders)

### Filters

[](#filters)

Powerfully and secure filter's:

##### BooleanFilter

[](#booleanfilter)

Filter by boolean values ? like `'true', 'false', '1', '0'`

##### NumberFilter

[](#numberfilter)

can filter data by numbers with some helps.

```
// localhost/domains?price=100 - Exact by 100
// localhost/domains?price=100..200 - Between 100 and 200
// localhost/domains?price[lt|gt|lte|gte]=100 - filter less, great, less than or great than.
```

##### NullFilter

[](#nullfilter)

This filter simple execute is or is not null on query.

```
new SearchFilter('name')
// localhost/domains?name=null - WHERE name IS NULL
// localhost/domains?name[is]=null - WHERE name IS NULL
// localhost/domains?name[not]=null - WHERE name IS NOT NULL
```

##### SearchFilter

[](#searchfilter)

This filter have four methods of work:

```
class SearchFilter implements FilterTypeInterface
{
    use ProcessableFilterTrait;

    const PARTIAL_STRATEGY = 'partial';
    const START_STRATEGY = 'start';
    const END_STRATEGY = 'end';
    const EXACT_STRATEGY = 'exact';

    ...code
}
```

```
new SearchFilter('name') - Exact is default
// localhost/domains?name=marcos - Exact by marcos
new SearchFilter('name', SearchFilter::PARTIAL_STRATEGY)
// localhost/domains?name=marcos - add a %value% by like method.
new SearchFilter('name', SearchFilter::START_STRATEGY)
// localhost/domains?name=marcos - add a value% by like method.
new SearchFilter('name', SearchFilter::END_STRATEGY)
// localhost/domains?name=marcos - add a %value by like method.
```

##### SearchInFilter

[](#searchinfilter)

filter by value or group values.

```
// localhost/domains?name=marcos - name in('marcos')
// localhost/domains?name=marcos,github - name in('marcos', 'github')
// localhost/domains?name[not]=marcos,github - name not in('marcos', 'github')
```

##### SearchDateFilter

[](#searchdatefilter)

*2.0.1* is possible to use `[gte, gt, lt, lte]` operators.

```
// localhost/domains?created_at=2019 - by init of 2019 year.
// localhost/domains?created_at=2019-01 - by init of Jan/2019 year.
// localhost/domains?created_at=201903 - by init of Mar/2019 year.
// localhost/domains?created_at=2019-01-12 - by day 12 of Jan/2019 year.
// localhost/domains?created_at=20190315 - by day 15 of Mar/2019 year.
// localhost/domains?created_at[lte]=20190315 - search by operators: [lt, lte, gt, gte]
// localhost/domains?created_at[lte]=20190315&created_at[gte]=20190315 - search by operators: [lt, lte, gt, gte]
```

##### Custom Filter ?

[](#custom-filter-)

By implementing `FilterTypeInterface` and if you want `ProcessableFilterTrait`you can create a filter for what you need.

#### About Component

[](#about-component)

The component have a list of configurations values to work above query params, without `reserved` keys it try to filter content, if model accept it, url queries

```
[
    'pagination' => true,
    'maxSize' => 100, // Max number of per page.
    'size' => 20, // default numbers of items per page
    'ssl' => true, // generate routes with ssl by default,
    'cacheConfig' => 'default', // cache config
    'cache' => true, // Enable or disable cache
    'reserved' => [  // If you need to use one o more of this keywords, change to alias.
        'size' => 'size',
        'page' => 'page',
        'props' => 'props',
        'nested' => 'nested',
        'sort' => 'sort'
    ]
];
```

Change some configs...

```
//Controller/AppController.php
public function initialize()
{
    // ...code
    $this->loadComponent('ExpressRequest.ExpressRequest', [
        'ssl' => false,
        'maxSize' => 30,
        'reserved' => [
            'props' => 'fields'
        ]
    ]);
}
```

###  Health Score

29

—

LowBetter than 59% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity14

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity62

Established project with proven stability

 Bus Factor1

Top contributor holds 98.4% 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 ~60 days

Recently: every ~79 days

Total

13

Last Release

1409d ago

Major Versions

v1.9.9 → v2.02020-11-11

PHP version history (3 changes)v1.9.7PHP ^7.2

v2.1.0PHP ^7.4

v2.1.9PHP &gt;=7.4

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/11980109?v=4)[Marcos Dantas](/maintainers/lpj145)[@lpj145](https://github.com/lpj145)

---

Top Contributors

[![lpj145](https://avatars.githubusercontent.com/u/11980109?v=4)](https://github.com/lpj145 "lpj145 (61 commits)")[![rochamarcelo](https://avatars.githubusercontent.com/u/850748?v=4)](https://github.com/rochamarcelo "rochamarcelo (1 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/mdantas-express-request/health.svg)

```
[![Health](https://phpackages.com/badges/mdantas-express-request/health.svg)](https://phpackages.com/packages/mdantas-express-request)
```

###  Alternatives

[friendsofcake/cakepdf

CakePHP plugin for creating and/or rendering Pdfs, several Pdf engines supported.

3752.1M3](/packages/friendsofcake-cakepdf)[cakephp/bake

Bake plugin for CakePHP

11211.2M158](/packages/cakephp-bake)[dereuromark/cakephp-tools

A CakePHP plugin containing lots of useful and reusable tools

338920.1k32](/packages/dereuromark-cakephp-tools)[dereuromark/cakephp-queue

The Queue plugin for CakePHP provides deferred task execution.

308850.3k14](/packages/dereuromark-cakephp-queue)[dereuromark/cakephp-ide-helper

CakePHP IdeHelper Plugin to improve auto-completion

1862.1M27](/packages/dereuromark-cakephp-ide-helper)[dereuromark/cakephp-tinyauth

A CakePHP plugin to handle user authentication and authorization the easy way.

129228.6k10](/packages/dereuromark-cakephp-tinyauth)

PHPackages © 2026

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