PHPackages                             antoi/restify-bundle - 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. antoi/restify-bundle

ActiveSymfony-bundle[API Development](/categories/api)

antoi/restify-bundle
====================

Reusable Symfony bundle providing abstract REST CRUD services, entity hydration, and pick-based serialization.

v0.0.2(2mo ago)01MITPHPPHP &gt;=8.2

Since May 5Pushed 2mo agoCompare

[ Source](https://github.com/antoine1003/restify-bundle)[ Packagist](https://packagist.org/packages/antoi/restify-bundle)[ RSS](/packages/antoi-restify-bundle/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (9)Versions (3)Used By (0)

RestifyBundle
=============

[](#restifybundle)

A reusable Symfony bundle providing a complete REST CRUD stack: abstract service, controller, repository, automatic entity hydration, and pick-based response enrichment.

Compatible with **Symfony 6.4, 7.x, and 8.x** — requires PHP 8.2+.

---

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

[](#installation)

```
composer require antoi/restify-bundle
```

If you are not using Symfony Flex, register the bundle manually:

```
// config/bundles.php
return [
    Antoi\RestifyBundle\RestifyBundle::class => ['all' => true],
];
```

---

Full wiring example (User resource)
-----------------------------------

[](#full-wiring-example-user-resource)

### 1. Repository

[](#1-repository)

```
use Antoi\RestifyBundle\Repository\AbstractRestRepository;

class UserRepository extends AbstractRestRepository
{
    public function __construct(ManagerRegistry $registry)
    {
        parent::__construct($registry, User::class);
    }

    // Only these fields may be used as query-param filters
    protected function getFilterableFields(): array
    {
        return ['name', 'email', 'status', 'createdAt'];
    }

    // Eager-load these relations on every list query
    protected function getDefaultJoins(): array
    {
        return ['role'];
    }
}
```

### 2. Service

[](#2-service)

```
use Antoi\RestifyBundle\Service\AbstractRestService;

class UserService extends AbstractRestService
{
    protected function getEntityClass(): string { return User::class; }

    protected function getWritableFields(): array
    {
        return ['name', 'email', 'role', 'status'];
    }
}
```

Wire in `config/services.yaml` (needed because `AbstractRestService` takes a typed `AbstractRestRepository`):

```
App\Service\UserService:
  arguments:
    $repository: '@App\Repository\UserRepository'
```

### 3. Controller

[](#3-controller)

```
use Antoi\RestifyBundle\Controller\AbstractRestController;

#[Route('/api/users')]
class UserController extends AbstractRestController
{
    public function __construct(
        SerializerInterface $serializer,
        ValidatorInterface  $validator,
        PickResolver        $pickResolver,
        UserService         $service,
    ) {
        parent::__construct($serializer, $validator, $pickResolver, $service);
    }

    protected function getReadGroups(): array  { return ['user:read']; }
    protected function getListGroups(): array  { return ['user:list']; }
}
```

That's it. Six endpoints are registered automatically.

---

Endpoints
---------

[](#endpoints)

MethodPathActionDescription`GET``/``list()`Paginated, filterable list`GET``/{id}``show()`Single resource`POST``/``create()`Create + validate + persist`PUT``/{id}``update()`Full replace + validate + persist`PATCH``/{id}``patch()`Partial update + validate + save`DELETE``/{id}``delete()`Remove---

Query parameters
----------------

[](#query-parameters)

### Pagination &amp; sorting

[](#pagination--sorting)

```
GET /api/users?page=2&limit=10&sort=name,-createdAt

```

- `sort=name` → `ORDER BY name ASC`
- `sort=-createdAt` → `ORDER BY createdAt DESC`
- Multiple fields: `sort=name,-createdAt`

### Filtering

[](#filtering)

Any query param not in `[page, limit, sort, pick]` is forwarded to the repository as a filter.

```
GET /api/users?status=active&createdAt_gte=2024-01-01&name_like=john

```

Supported operators (append as suffix):

SuffixSQL equivalent*(none)*`= :value``_gte``>= :value``_gt``> :value``_lte``getIp()`
- `lastLogin.ip` → `$user->getLastLogin()->getIp()` (deep traversal)
- `roles.name` → `[$role->getName(), ...]` for each role in the collection

---

Response shapes
---------------

[](#response-shapes)

### Single resource

[](#single-resource)

```
{
  "success": true,
  "data": { "id": 1, "name": "John" }
}
```

### Paginated list

[](#paginated-list)

```
{
  "success": true,
  "data": [ ... ],
  "meta": { "total": 42, "page": 1, "limit": 20, "pages": 3 }
}
```

### Validation error (422)

[](#validation-error-422)

```
{
  "success": false,
  "message": "Validation failed.",
  "errors": {
    "email": ["This value is not a valid email address."]
  }
}
```

### Not found (404)

[](#not-found-404)

```
{ "success": false, "message": "User with ID \"99\" was not found." }
```

> Wire `InvalidPayloadException` (400) and `ResourceNotFoundException` (404) to your API error listener to produce these shapes automatically.

---

Components reference
--------------------

[](#components-reference)

ClassNamespaceDescription`AbstractRestRepository``…\Repository`Paginator, dynamic filters, operator suffixes`AbstractRestService``…\Service`Decode → filter fields → hydrate → persist`AbstractRestController``…\Controller`Full CRUD actions, serialization, pick merging`EntityHydrator``…\Service`Scalar + datetime + ManyToOne + ManyToMany`PickResolver``…\Service`Dot-notation deep property resolver`ApiResponse``…\DTO``{ success, data, message }` envelope`PaginatedResponse``…\DTO``{ success, data, meta }` envelope`InvalidPayloadException``…\Exception`400 — bad JSON or wrong field type`ResourceNotFoundException``…\Exception`404 — entity not found

###  Health Score

33

—

LowBetter than 72% of packages

Maintenance84

Actively maintained with recent releases

Popularity1

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity37

Early-stage or recently created project

 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 ~0 days

Total

2

Last Release

80d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/15017551?v=4)[Antoine DAUTRY](/maintainers/antoine1003)[@antoine1003](https://github.com/antoine1003)

---

Top Contributors

[![antoine1003](https://avatars.githubusercontent.com/u/15017551?v=4)](https://github.com/antoine1003 "antoine1003 (5 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/antoi-restify-bundle/health.svg)

```
[![Health](https://phpackages.com/badges/antoi-restify-bundle/health.svg)](https://phpackages.com/packages/antoi-restify-bundle)
```

###  Alternatives

[easycorp/easyadmin-bundle

Admin generator for Symfony applications

4.3k17.9M400](/packages/easycorp-easyadmin-bundle)[sylius/sylius

E-Commerce platform for PHP, based on Symfony framework.

8.5k5.9M754](/packages/sylius-sylius)[2lenet/crudit-bundle

The easy like Crud'it Bundle.

1616.4k14](/packages/2lenet-crudit-bundle)[open-dxp/opendxp

Content &amp; Product Management Framework (CMS/PIM)

9421.6k64](/packages/open-dxp-opendxp)[rcsofttech/audit-trail-bundle

Enterprise-grade, high-performance Symfony audit trail bundle. Automatically track Doctrine entity changes with split-phase architecture, multiple transports (HTTP, Queue, Doctrine), and sensitive data masking.

1189.8k](/packages/rcsofttech-audit-trail-bundle)[pimcore/pimcore

Content &amp; Product Management Framework (CMS/PIM/E-Commerce)

3.8k3.8M511](/packages/pimcore-pimcore)

PHPackages © 2026

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