bibrokhim / http-clients
Http clients for microservices
Requires
- php: ^8.2
- guzzlehttp/psr7: ^2.0
- illuminate/http: ^10|^11|^12|^13
- illuminate/support: ^10|^11|^12|^13
Requires (Dev)
None
Suggests
None
Provides
None
Conflicts
None
Replaces
None
- dev-main
- 2.0.0
- 1.15.0
- 1.14.1
- 1.14.0
- 1.13.1
- 1.13.0
- 1.12.0
- 1.11.0
- 1.10.2
- 1.10.1
- v1.10.0
- 1.9.0
- 1.8.9
- 1.8.8
- 1.8.7
- 1.8.6
- 1.8.5
- 1.8.4
- 1.8.3
- 1.8.2
- 1.8.1
- 1.8.0
- 1.7.7
- 1.7.6
- 1.7.5
- 1.7.4
- 1.7.3
- 1.7.2
- 1.7.1
- 1.7.0
- 1.6.36
- 1.6.35
- 1.6.34
- 1.6.33
- 1.6.32
- 1.6.31
- 1.6.30
- 1.6.29
- 1.6.28
- 1.6.27
- 1.6.26
- 1.6.25
- 1.6.24
- 1.6.23
- 1.6.22
- 1.6.21
- 1.6.20
- 1.6.19
- 1.6.18
- 1.6.17
- 1.6.16
- 1.6.15
- 1.6.14
- 1.6.13
- 1.6.12
- 1.6.11
- 1.6.10
- 1.6.9
- 1.6.8
- 1.6.7
- 1.6.6
- 1.6.5
- 1.6.4
- 1.6.3
- 1.6.2
- 1.6.1
- 1.6.0
- 1.5.3
- 1.5.2
- 1.5.1
- 1.5.0
- 1.4.12
- 1.4.11
- 1.4.10
- 1.4.9
- 1.4.8
- 1.4.7
- 1.4.6
- 1.4.5
- 1.4.4
- 1.4.3
- 1.4.2
- 1.4.1
- 1.4.0
- 1.3.5
- 1.3.4
- 1.3.3
- 1.3.2
- 1.3.1
- 1.3.0
- 1.2.9
- 1.2.8
- 1.2.7
- 1.2.6
- 1.2.5
- 1.2.4
- 1.2.3
- 1.2.2
- 1.2.1
- 1.2.0
- 1.1.0
- 1.0.9
- 1.0.8
- 1.0.7
- 1.0.6
- 1.0.5
- 1.0.4
- 1.0.3
- 1.0.2
- 1.0.1
- 1.0.0
- dev-feature/simplfiy-site-categories-client
This package is auto-updated.
Last update: 2026-09-10 11:46:06 UTC
README
Typed HTTP clients for the internal microservices (CRM, Products, SMS, Firebase, Media, Helpdesk, OneC, ApiGateway, Rating, ServiceCRM, PsSap, Epamarket, Pos, PollwonProducts, PollwonSite). Installed as a dependency of the consuming Laravel applications; it is not run standalone.
composer require bibrokhim/http-clients
Every client is bound in HttpClientsServiceProvider, reading config/config.php
under the http_clients key. Setting HTTP_CLIENT_CACHE=true swaps the clients
that have a cache decorator (Products, PollwonProducts, CRM) for their
*CacheClient variant.
Pollwon Product Service — site categories
GET {POLLWON_PRODUCTS_BASE_URL}/v1/site/categories backs the public storefront
category tree.
use Bibrokhim\HttpClients\Clients\PollwonProducts\PollwonProductsClientInterface; public function index(PollwonProductsClientInterface $client, Request $request) { $categories = $client->siteCategories( $request->query('parent_id'), // null for the root level $request->getPreferredLanguage(['uz', 'ru', 'en']), ); return response()->json($categories->payload, $categories->status) ->withHeaders(array_filter([ 'Content-Language' => $categories->contentLanguage, 'Retry-After' => $categories->retryAfter, ])); }
The contract
public function siteCategories(?string $parentId, ?string $language = null): SiteCategoriesResponse;
$parentId— onlynullmeans the root level. Any other string, an empty one included, is sent downstream asparent_idand the product service rules on it. An empty string is never promoted to a root lookup.$language— optional.null, empty and anything outsideuz/ru/enall normalise touz, and the result is sent asAccept-Language. This is request-side only.
SiteCategoriesResponse holds the downstream answer as it arrived:
| Property | Notes |
|---|---|
status |
Original upstream status code. |
payload |
Decoded JSON body — null when the body was not JSON. |
contentLanguage |
Content-Language verbatim, null when the upstream sent none. |
retryAfter |
Retry-After verbatim — delta-seconds or an HTTP-date. |
Nothing is normalised or defaulted on the way back: a Content-Language: en-US
is returned as en-US, and a header the upstream never sent stays null rather
than being filled in with the requested language. successful(), clientError()
and serverError() classify the status; cacheable() is true only for a 200
with a decoded body.
404, 422 and 429 are returned, not thrown, so the caller can proxy the
original status, body and headers. 5xx throws ServerErrorException and
connection failures keep the package's standard behaviour, both by way of the
usual BaseClient rules.
Caching
With HTTP_CLIENT_CACHE=true the container binds PollwonProductsCacheClient,
which caches under:
pollwon-products.site-categories.v1.{language}.{root|parent_id}
One key per level per locale, so root and each parent stay independent; root is
used for a null parent only, and an empty-string parent gets its own key. Only a
200 is stored — 404, 422, 429 and a non-JSON body are served to the caller but
never cached.
A cold key is filled behind Cache::lock(): the holder re-checks the cache once
it has the lock, so a caller that waited reads the entry the holder wrote instead
of issuing its own request. If the cache store is unreachable the client bypasses
the cache and serves a single fresh response rather than failing; if the lock
itself times out it raises a 503 ServerErrorException rather than adding a
second concurrent request to a service that is already busy.
| Env var | Default | Purpose |
|---|---|---|
POLLWON_PRODUCTS_BASE_URL |
— | Service base URL, ending /api. |
POLLWON_SITE_CATEGORIES_CACHE_TTL |
300 |
Cache lifetime, seconds. |
POLLWON_PRODUCTS_SITE_CATEGORIES_CACHE_TTL is the pre-release name for the TTL
and is still read as a fallback; new deployments should set
POLLWON_SITE_CATEGORIES_CACHE_TTL.
Cached entries expire on the TTL alone — the package has no knowledge of product
service category events, so a change to a category's active, title,
position or parent becomes visible only once the entry lapses. Shorten the
TTL if that window is too wide.
Development
composer install composer test # PHPUnit vendor/bin/pint --dirty composer audit --locked
The suite runs on a minimal Illuminate container (tests/TestApplication.php)
rather than a full framework install, so the package's production dependency
footprint stays small. tests/helpers.php supplies the app(), config() and
now() helpers a host Laravel application would otherwise provide.