PHPackages                             frootbox/rest-api - 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. frootbox/rest-api

ActiveLibrary[Framework](/categories/framework)

frootbox/rest-api
=================

Frootbox REST API Framework

0.7(2d ago)0642GPL-3.0-or-laterPHPPHP &gt;=8.3

Since Sep 22Pushed 2d agoCompare

[ Source](https://github.com/Frootbox/RestApi)[ Packagist](https://packagist.org/packages/frootbox/rest-api)[ RSS](/packages/frootbox-rest-api/feed)WikiDiscussions main Synced today

READMEChangelogDependencies (17)Versions (20)Used By (0)

Frootbox REST API
=================

[](#frootbox-rest-api)

A lightweight, attribute-based REST API framework for PHP.

This package provides a simple way to build versioned REST APIs with support for multiple authentication methods like API keys, Bearer tokens, Basic Auth, and custom client credentials.

---

✨ Features
----------

[](#-features)

- Attribute-based routing (OpenAPI compatible)
- API versioning via namespace (`V1`, `V2`, ...)
- Multiple authentication methods:
    - API Key
    - Bearer (JWT)
    - Basic Auth
    - Client credentials
- Dependency Injection support (PHP-DI)
- Automatic route discovery
- Named route parameters (`{id}`, `{int:id}`)
- JSON and `application/x-www-form-urlencoded` request body parsing
- JSON response handling with optional response headers/status codes

---

📦 Installation
--------------

[](#-installation)

```
composer require frootbox/restapi
```

---

🚀 Getting Started
-----------------

[](#-getting-started)

### 1. Create a Server instance

[](#1-create-a-server-instance)

```
use Frootbox\\RestApi\\Server;
use DI\\Container;

$container = new Container();

$server = new Server(
    clientRepository: $clientRepository, // implements ClientRepositoryInterface
    baseUriRegex: '#^/api/v(?P[0-9]+)(?P/.*)$#',
    controllerDirectory: __DIR__ . '/Controller',
    namespace: 'App\\\\Controller',
    container: $container,
    hashKey: 'your-secret-key'
);

$server->execute();
```

---

📁 Controller Structure
----------------------

[](#-controller-structure)

Controllers must follow a versioned namespace structure:

```
src/
└── Controller/
    └── V1/
        └── UserController.php
```

---

🧩 Example Controller
--------------------

[](#-example-controller)

```
namespace App\\Controller\\V1;

use OpenApi\\Attributes as OA;
use Frootbox\\RestApi\\Attribute\\Auth;
use Frootbox\\RestApi\\Attribute\\ApiKey;
use Frootbox\\RestApi\\Response\\Payload;

class UserController
{
    #[OA\\Get(path: '/users/{int:id}')]
    #[Auth(type: new ApiKey())]
    public function getUser(int $id): Payload
    {
        return new Payload([
            'id' => $id,
            'name' => 'John Doe'
        ]);
    }
}
```

---

🔐 Authentication
----------------

[](#-authentication)

You can define one or multiple authentication methods per endpoint:

```
#[Auth(type: new ApiKey())]
#[Auth(type: new Bearer())]
```

### Supported Auth Methods

[](#supported-auth-methods)

#### API Key

[](#api-key)

Send via header:

```
x-api-key: your-api-key
```

---

#### Bearer Token (JWT)

[](#bearer-token-jwt)

```
Authorization: Bearer
```

---

#### Basic Auth

[](#basic-auth)

```
Authorization: Basic base64(clientId:clientSecret)
```

---

#### Client Credentials (Basic, form body, or legacy query)

[](#client-credentials-basic-form-body-or-legacy-query)

```
Authorization: Basic base64(clientId:clientSecret)
```

For OAuth-compatible token endpoints, client credentials can also be sent in an `application/x-www-form-urlencoded` request body as `client_id` and `client_secret`. Query string credentials are still supported as a legacy fallback and can be disabled through the `Server` constructor:

```
$server = new Server(
    // ...
    allowClientCredentialsInQuery: false
);
```

---

Request Payloads
----------------

[](#request-payloads)

`Frootbox\RestApi\Payload` supports JSON request bodies and `application/x-www-form-urlencoded` request bodies. Existing JSON endpoints keep working as before, while OAuth token endpoints can follow the OAuth standard:

```
POST /oauth/token
Authorization: Basic base64(clientId:clientSecret)
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token&refresh_token=...
```

---

🧠 Client Validation
-------------------

[](#-client-validation)

You must provide a repository implementing:

```
Frootbox\\RestApi\\Interface\\ClientRepositoryInterface
```

Example:

```
class ClientRepository implements ClientRepositoryInterface
{
    public function validate(string $clientId, string $clientSecret): void
    {
        if ($clientId !== 'test' || $clientSecret !== 'secret') {
            throw new \\Exception('Invalid client credentials');
        }
    }

    public function validateApiKey(string $apiKey): void
    {
        if ($apiKey !== 'abc123') {
            throw new \\Exception('Invalid API key');
        }
    }
}
```

---

🔄 Versioning
------------

[](#-versioning)

API version is extracted from the URL:

```
/api/v1/users/1
```

Your controllers must match the version namespace:

```
namespace App\\Controller\\V1;
```

---

🧾 Route Parameters
------------------

[](#-route-parameters)

### Integer parameter

[](#integer-parameter)

```
/users/{int:id}
```

### String parameter

[](#string-parameter)

```
/users/{slug}
```

### ULID parameter

[](#ulid-parameter)

```
/users/{ulid:id}
```

### OpenAPI parameter pattern

[](#openapi-parameter-pattern)

```
#[OA\Get(path: '/users/{id}')]
#[OA\Parameter(
    name: 'id',
    in: 'path',
    required: true,
    schema: new OA\Schema(type: 'string', pattern: '^[0-9A-HJKMNP-TV-Z]{26}$'),
)]
```

Static routes are matched before dynamic routes, so `/users/search` is preferred over `/users/{id}` regardless of reflection order.

Parameters are automatically injected into the method.

---

📤 Responses
-----------

[](#-responses)

All responses must return:

```
Frootbox\\RestApi\\Response\\Payload
```

Example:

```
return new Payload([
    'success' => true
]);
```

---

⚙️ Dependency Injection
-----------------------

[](#️-dependency-injection)

Controllers are resolved via the provided DI container:

```
$container->call([$controller, $method]);
```

You can inject services directly into controller methods:

```
public function getUser(UserService $service, int $id)
```

---

🔧 Hooks
-------

[](#-hooks)

### Token decoding hook

[](#token-decoding-hook)

```
$server = new Server(..., onDecodeToken: function ($token) {
    // custom logic
});
```

### Client validation hook

[](#client-validation-hook)

```
$server = new Server(..., onValidateClient: function ($clientId) {
    // custom logic
});
```

---

⚠️ Important Notes
------------------

[](#️-important-notes)

- Always use HTTPS when transmitting credentials
- API keys should be treated like passwords
- Bearer tokens are validated using HS256
- Route matching is case-insensitive

---

📄 License
---------

[](#-license)

MIT """

###  Health Score

47

—

FairBetter than 93% of packages

Maintenance99

Actively maintained with recent releases

Popularity17

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity53

Maturing project, gaining track record

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

Recently: every ~14 days

Total

19

Last Release

2d ago

PHP version history (2 changes)0.1.0PHP &gt;=8.1

0.2.0PHP &gt;=8.3

### Community

Maintainers

![](https://www.gravatar.com/avatar/fcec2f1b7299cf187eff1364cf8d442431845a14e202900c2756929f5ff36432?d=identicon)[82912759](/maintainers/82912759)

---

Top Contributors

[![JnHbbBrnng](https://avatars.githubusercontent.com/u/45029139?v=4)](https://github.com/JnHbbBrnng "JnHbbBrnng (25 commits)")

### Embed Badge

![Health badge](/badges/frootbox-rest-api/health.svg)

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

###  Alternatives

[laravel/socialite

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

5.7k108.5M885](/packages/laravel-socialite)[matomo/matomo

Matomo is the leading Free/Libre open analytics platform

21.7k38.9k](/packages/matomo-matomo)[shopware/platform

The Shopware e-commerce core

3.4k1.5M3](/packages/shopware-platform)[typo3/cms

TYPO3 CMS is a free open source Content Management Framework initially created by Kasper Skaarhoj and licensed under GNU/GPL.

1.2k1.9M122](/packages/typo3-cms)[shopware/core

Shopware platform is the core for all Shopware ecommerce products.

585.6M574](/packages/shopware-core)[oro/platform

Business Application Platform (BAP)

645143.5k115](/packages/oro-platform)

PHPackages © 2026

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