PHPackages                             perfumer/microservices - 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. [Utility &amp; Helpers](/categories/utility)
4. /
5. perfumer/microservices

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

perfumer/microservices
======================

Set of classes for dealing with Perfumer microservices

v5.6.0(1y ago)015.1kPHP

Since Dec 28Pushed 3mo ago1 watchersCompare

[ Source](https://github.com/perfumer/microservices)[ Packagist](https://packagist.org/packages/perfumer/microservices)[ Docs](https://github.com/perfumer/microservices)[ RSS](/packages/perfumer-microservices/feed)WikiDiscussions release Synced 1mo ago

READMEChangelog (10)Dependencies (4)Versions (67)Used By (0)

What is it
----------

[](#what-is-it)

This is library to request Perfumerlabs microservices. Currently following microservices are supported:

- [Box](https://github.com/perfumerlabs/box)
- [Delivery](https://github.com/perfumerlabs/delivery)
- [Email](https://github.com/perfumerlabs/email)
- [ES](https://github.com/perfumerlabs/es)
- [Feed](https://github.com/perfumerlabs/feed)
- [OTP](https://github.com/perfumerlabs/otp)
- [Ncanode](https://github.com/perfumerlabs/ncanode)

All classes are autogenerated based on annotations.

### Fast example

[](#fast-example)

```
use Perfumer\Microservices\Forms\Forms;
use Perfumer\Microservices\Forms\Request\Modules\GetModulesRequest;

/** @var Forms $service */
$service = $container->get('microservices.forms');

$request = new GetModulesRequest();

$response = $service->getModules($request);

var_dump($response->modules);
```

### HTTP transactions

[](#http-transactions)

Library supports HTTP transactions. Mechanism is very simple. You connect storage provider. Then write transaction, and after `commit` method all http-requests in transaction are stored to that storage.

If a request is failed, then its data is persisted in the storage. Then you can retry requests in the daemon or cron job.

Transaction example:

```
use Perfumer\Microservices\Transaction\Transaction;
use Perfumer\Microservices\Transaction\TransactionProvider\PropelProvider;
use Perfumer\Microservices\Forms\Request\Module\CreateModuleRequest;

/** @var Forms $service */
$service = $container->get('microservices.forms');

// You can add your own providers
// Currently only PropelProvider is here
$transaction = new Transaction(new PropelProvider());

$request1       = new CreateModuleRequest();
$request1->name = 'foo';

$transaction->add(
    $service,
    $request1,
    function (Forms $service, $request1) {
        return $sed->createModule($request1);
    }
);

$request2       = new CreateModuleRequest();
$request2->name = 'bar';

$transaction->add(
    $service,
    $request2,
    function (Forms $service, $request2) {
        return $sed->createModule($request2);
    }
);

$transaction->commit();
```

Example of daemon worker to resend requests we use:

```
while (true) {
    $transaction_service = new Transaction(new PropelProvider());

    $transaction_request = TransactionRequestQuery::create()
        ->filterByUpdatedAt((new \DateTime())->modify('-1 minute'), Criteria::LESS_EQUAL)
        ->orderByUpdatedAt()
        ->findOne();

    if ($transaction_request) {
        $http_request = new HttpRequest();
        $http_request->url = $transaction_request->getUrl();
        $http_request->method = $transaction_request->getMethod();
        $http_request->timeout = $transaction_request->getTimeout();
        $http_request->json = $transaction_request->getJson();
        $http_request->headers = $transaction_request->getHeaders();

        try {
            $response = $transaction_service->sendHttpRequest($http_request);

            if (in_array($response->getStatusCode(), [200, 201])) {
                $transaction_request->delete();
            }
        } catch (\Throwable $e) {

        }

        if (!$transaction_request->isDeleted()) {
            $transaction_request->setUpdatedAt(new \DateTime());
            $transaction_request->save();
        }
    } else {
        sleep(5);
    }
}
```

### Request debugging

[](#request-debugging)

If `_debug=true` is provided to Request class, then Microservice during requesting sets `debug=true` option to Guzzle client. If it is enabled Guzzle prints some information about request to stdout.

```
use Perfumer\Microservices\Microservice;
use Perfumer\Microservices\Request;

$request = new Request();
$request->_request_method = 'post';
$request->_request_url = '/my-url';
$request->_debug = true;
$request->setBody(['foo' => 'bar']);

$microservice = new Microservice([
    'host' => 'https://example.com'
]);

$microservice->request($request);
```

### Request catching

[](#request-catching)

Library supports also any request catching servers for more convenient debugging. Request catching servers print requests as-is when they come. There are many free online request catching services in the google search.

Any microservice class allows `request_catcher_host` parameter in constructor options. If it is defined, and `_catch=true` provided to Request class, then microservice class also sends special request to that host. The request contains full request and response details in the body.

```
use Perfumer\Microservices\Microservice;
use Perfumer\Microservices\Request;

$request = new Request();
$request->_request_method = 'post';
$request->_request_url = '/my-url';
$request->_catch = true;
$request->setBody(['foo' => 'bar']);

$microservice = new Microservice([
    'host' => 'https://example.com',
    'request_catcher_host' => 'https://request-catcher-server.com'
]);

// HTTP request details as-is are sent to `https://request-catcher-server.com` also
$microservice->request($request);
```

### How to write annotations for HTTP methods

[](#how-to-write-annotations-for-http-methods)

Say, we have a Crm service and want to generate annotation for `GET /user` request. We open `src/Contract/Crm.php` and add class annotation like this:

```
@RequestModel(microservice="crm", model="user", action="get", submodel="User", url="/user", fields={"id"}, response_fields={"user"}, request_method="get")
```

To execute generation launch `php generate.php`. This annotation after generation creates a number of things:

1. Base request class at `generated/src/Crm/Request/User/GetUserRequest.php`
2. Empty request class at `src/Crm/Request/User/GetUserRequest.php`
3. Base response class at `generated/src/Crm/Response/User/GetUserResponse.php`
4. Empty response class at `src/Crm/Response/User/GetUserResponse.php`
5. Base class at `generated/src/Crm/Crm.php` and/or method `getUser` in the class
6. Empty class at `src/Crm/Crm.php` if this is missing.

As you notice, request class path is generated by the next scheme:

```
src/{{microservice}}/Request/{{model}}/{{action}}{{submodule}}Request.php

```

Same as Response class:

```
src/{{microservice}}/Response/{{model}}/{{action}}{{submodule}}Response.php

```

Where `microservice`, `model`, `action` and `submodule` are annotation properties. Also there are parameters to set:

- `url` means which URL will be requested. By default equal to model value.
- `request_method` means HTTP-method to request with.
- `fields` - array of parameters to set to json body of the request.
- `response_fields` - array of parameters to get from response body.

For convenience, there a number of predefined annotations, which set some of parameters by themselves. For example:

```
@GetModel(microservice="crm", model="user", fields={"id"})
```

is short equivalent of the full annotation above.

Contributing
============

[](#contributing)

Feel free to make any pull requests.

###  Health Score

44

—

FairBetter than 92% of packages

Maintenance61

Regular maintenance activity

Popularity23

Limited adoption so far

Community7

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

Recently: every ~116 days

Total

63

Last Release

633d ago

Major Versions

v1.4.6 → v2.0.02021-11-26

v2.2.0 → v3.0.02022-02-28

v3.8.0 → v4.0.02022-05-19

v4.6.7 → v5.0.02022-12-27

### Community

Maintainers

![](https://www.gravatar.com/avatar/00041adfb08223ce8c9b22b92a98c0c4b5a39fbb3da1323bdca14a7887ceb603?d=identicon)[blumfontein](/maintainers/blumfontein)

---

Top Contributors

[![blumfontein](https://avatars.githubusercontent.com/u/2392350?v=4)](https://github.com/blumfontein "blumfontein (9 commits)")

### Embed Badge

![Health badge](/badges/perfumer-microservices/health.svg)

```
[![Health](https://phpackages.com/badges/perfumer-microservices/health.svg)](https://phpackages.com/packages/perfumer-microservices)
```

###  Alternatives

[grumpydictator/firefly-iii

Firefly III: a personal finances manager.

22.8k69.3k](/packages/grumpydictator-firefly-iii)[shlinkio/shlink

A self-hosted and PHP-based URL shortener application with CLI and REST interfaces

4.8k4.3k](/packages/shlinkio-shlink)[getdkan/dkan

DKAN Open Data Catalog

385135.4k2](/packages/getdkan-dkan)[firefly-iii/data-importer

Firefly III Data Import Tool.

7545.8k](/packages/firefly-iii-data-importer)[ralphjsmit/laravel-helpers

A package containing handy helpers for your Laravel-application.

13704.6k2](/packages/ralphjsmit-laravel-helpers)[aedart/athenaeum

Athenaeum is a mono repository; a collection of various PHP packages

245.2k](/packages/aedart-athenaeum)

PHPackages © 2026

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