Giter Site home page Giter Site logo

laravel-sieve's Introduction

UKFast Logo

Laravel Sieve

A library to handle filtering and sorting for your APIs

Filters like /pets?name:in=Snoopy,Hobbes will be applied to your query builder instance and only results matching that criteria will return

Installation

First, use composer to require the package as below:

composer require ukfast/laravel-sieve

Then all we need to do is to register the service provider in the providers key in ``config/app.php`:

UKFast\Sieve\SieveServiceProvider::class,

Usage

Sieve uses an expressive API to configure these filters:

<?php

class Pet extends Model implements Searchable
{
    public function sieve(Sieve $sieve)
    {
        $sieve->configure(fn ($filter) => [
           'name' => $filter->string(),
           'breed' => $filter->enum(['Beagle', 'Tiger']),
        ]);
    }
}
<?php

class PetController extends Controller
{
    public function index()
    {
        return Pets::query()->search()->paginate();
    }
}

Filters

Filters are done in the query parameters with the format property:operator=term, for example

  • name:eq=Bob - WHERE name = 'Bob'
  • age:lt=20 - WHERE age < 10
  • employed:eq=true - WHERE employed = 1

By default, if no operator is specified, it will default to eq so name=Bob will expand to name:eq=Bob

Sorting

Sieve will also allow consumers of your API to specify sort order. You can do this by sort=property:direction

  • sort=age:asc
  • sort=id:desc

You can set a default sort using the setDefaultSort on theSieve class.

$sieve->setDefaultSort('name', 'asc')

Available Filters

String

The basic filter. Ideal for textual data, implements eq, neq, in, and nin

<?php
$filter->string()

Numeric

Ideal for numerical data, on top of the basic operators, it also provides lt (less than) and gt (greater than)

<?php
$filter->numeric()

Enum

Same as the string filter but with extra validation. Will throw an exception if the user gives an invalid value

<?php
$filter->enum(['HR', 'RnD'])

Boolean

Only provides eq and neq. Also takes two arguments to specify what your true and false values are in the DB

<?php
$filter->boolean() // defaults to 1 and 0

Date

Provides the same operations as numeric

<?php
$filter->date(),

You can get type hinting for these filters by specifying FilterBuilder when using the configure method

<?php
$sieve->configure(fn (FilterBuilder $filter) [
    'name' => $filter->string(),
]);

Relationships

You can filter on relationships using the for method on the filter builder

<?php
$sieve->configure(fn ($filter) => [
    'owner_name' => $filter->for('owner.name')->string()
])

You can also use the for method if your API properties don't match column names in the database, for example

<?php
$sieve->configure(fn ($filter) => [
    'date_created' => $filter->for('created_at')->date()
])

Wrapping Filters

You can easily wrap all the available filters to decorate their behaviour. A good example of this is if your API has some kind of computed property

A very simple example might be you have a price property that's stored in pence in the DB, but displayed as pounds in the API (not necessarily good practice, but works for the example)

We can still filter on this by setting up a wrapper that will modify the consumers query before passing it to the filter:

<?php

class PenceFilter implements WrapsFilter
{
    protected $filter;

    public function setFilter($filter)
    {
        $this->filter = $filter;
    }

    public function modifyQuery($query, SearchTerm $search)
    {
        $pence = $search->term() * 100;
         // will do a better API for making new search terms later
        $newTerm = new SearchTerm($search->property(), $search->operator(), $search->column(), $pence);

        $this->filter->modifyQuery($query, $search);
    }

    public function operators()
    {
        return $this->filter->operators();
    }
}

This can be used by doing the following:

$sieve->configure(fn ($filter) => [
    'price' => $filter->wrap(new PenceFilter)->numeric(),
])

Now when the user searches for price:eq=1.50 the database query will instead be WHERE price = 150

It's worth noting that wrap can be called multiple times and the builder will repeatedly re-wrap

Contributing

We welcome contributions to this package that will be beneficial to the community.

You can reach out to our open-source team via [email protected] who will get back to you as soon as possible.

Please refer to our CONTRIBUTING file for more information.

Security

If you think you have identified a security vulnerability, please contact our team via [email protected] who will get back to you as soon as possible, rather than using the issue tracker.

Licence

This project is licenced under the MIT Licence (MIT). Please see the Licence file for more information.

laravel-sieve's People

Contributors

gman98ish avatar phily245 avatar rbibby avatar rslsystems avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.