Nette rozšíření a znovupoužitelný klient pro REST API ABRA Flexi.
- PHP 8.2+
- Nette DI
- contributte/guzzlette
- guzzlehttp/guzzle
composer require acme/nette-abra-flexiZaregistrujte rozšíření do config.neon:
extensions:
guzzle: Contributte\Guzzlette\DI\GuzzleExtension
abraFlexi: Acme\AbraFlexi\DI\FlexiExtension
abraFlexi:
baseUrl: https://demo.flexibee.eu
company: demo-company
username: demo-user
password: demo-password
timeout: 10.0
guzzle:
headers:
Accept: application/jsonFlexiExtension si přes Contributte\Guzzlette\ClientFactory vytváří vlastního dedikovaného Guzzle klienta, takže transport vždy používá klienta založeného na Guzzlette, který je zaregistrovaný v DI kontejneru, bez ohledu na alias rozšíření.
Pokud potřebujete více firem, není nutné registrovat desítky extension aliasů. Stačí jedna extension a pojmenované connection profily:
extensions:
guzzle: Contributte\Guzzlette\DI\GuzzleExtension
abraFlexi: Acme\AbraFlexi\DI\FlexiExtension
abraFlexi:
baseUrl: https://demo.flexibee.eu
username: demo-user
password: demo-password
timeout: 10.0
connections:
sales: company-sales
warehouse:
company: company-warehouse
timeout: 20.0
defaultConnection: salesPak můžete:
- injektovat
Acme\AbraFlexi\Client\FlexiClientprodefaultConnection - injektovat
Acme\AbraFlexi\Client\FlexiClientFactorya volat$factory->createNamed('warehouse') - nebo vytvářet klienty dynamicky přes
$factory->create('company-code')
Pokud vám víc vyhovuje původní model, stále můžete zaregistrovat více instancí FlexiExtension pod různými aliasy. Ten zůstává podporovaný.
Knihovna je rozdělená do samostatných vrstev:
Config/FlexiConfig- validovaná konfigurace připojeníEndpoint/EndpointBuilder- skládání URL/endpointů pro firemní a agendové cestyHttp/HttpTransportInterface+Http/GuzzleHttpTransport- HTTP transport nad dedikovaným klientem vytvořeným přes GuzzletteResponse/ResponseParser- parsování JSON/XML, normalizace kořenewinstroma detekce chybových payloadů APIClient/FlexiClient- veřejné API proGET/POST/PUT/DELETEnad Flexi.jsonnebo.xmlendpointyException/*- sjednocená hierarchie výjimek pro chyby transportu/API/parsingDI/FlexiExtension- Nette rozšíření, které zapojuje všechny služby z NEON konfigurace
Vstříkněte Acme\AbraFlexi\Client\FlexiClient do své služby:
<?php
declare(strict_types=1);
namespace App\Model;
use Acme\AbraFlexi\Client\FlexiClient;
final readonly class InvoiceSync
{
public function __construct(
private FlexiClient $flexiClient,
) {
}
public function loadInvoice(string $id): array
{
return $this->flexiClient->get('faktura-vydana', $id);
}
}Pro více firem za běhu injektujte raději továrnu:
<?php
declare(strict_types=1);
namespace App\Model;
use Acme\AbraFlexi\Client\FlexiClientFactory;
final readonly class CompanySync
{
public function __construct(
private FlexiClientFactory $flexiClientFactory,
) {
}
public function loadInvoice(string $company, string $id): array
{
return $this->flexiClientFactory
->create($company)
->get('faktura-vydana', $id);
}
}Podporované metody:
get(string $agenda, ?string $recordId = null, array $query = [])post(string $agenda, array|string $payload, array $query = [])put(string $agenda, string $recordId, array|string $payload, array $query = [])delete(string $agenda, string $recordId, array $query = [])
Příklad s parametry dotazu a payloadem:
$list = $flexiClient->get('adresar', null, ['limit' => 20, 'detail' => 'full']);
$created = $flexiClient->post('adresar', [
'kod' => 'CUST-001',
'nazev' => 'Acme s.r.o.',
]);Pole se automaticky zabalí do tvaru Flexi JSON dokumentu:
{"winstrom":{"adresar":{"kod":"CUST-001","nazev":"Acme s.r.o."}}}Odpovědi se normalizují na vnitřní payload dokumentu, takže Flexi odpověď jako {"winstrom":{"@version":"1.0","adresar":[...]}} se vrátí jako ['@version' => '1.0', 'adresar' => [...]].
Pokud potřebujete volat XML endpoint, předejte surový XML řetězec. Klient přepne URL požadavku na .xml a odešle Accept/Content-Type: application/xml.
Klient používá vlastní výjimky:
FlexiException- základní výjimkaHttpException- chyby transportu/stavového kódu (statusCode,responseBody)ApiErrorException- aplikační chyba vrácená v payloadu APIParseException- neplatný nebo neočekávaný formát odpovědi
GuzzleHttpTransport podporuje volitelný Psr\Log\LoggerInterface.
- Logují se události požadavků, odpovědí i chyb
- Citlivé hodnoty se před zalogováním maskují, včetně payloadů požadavků/odpovědí a citlivých hlaviček (
auth,password,authorization,token, ...)
Spuštění testů v Dockeru (PHP 8.2):
docker compose run --rm app composer test -- --no-coverageReálný integrační test proti API spouštějte jen při explicitním povolení:
ABRA_FLEXI_RUN_INTEGRATION=1 composer test:integrationVýchozí hodnoty míří na veřejnou demo instanci Flexi:
ABRA_FLEXI_BASE_URL=https://demo.flexibee.eu:5434ABRA_FLEXI_COMPANY=demoABRA_FLEXI_USERNAME=winstromABRA_FLEXI_PASSWORD=winstromABRA_FLEXI_TIMEOUT=10
Aktuální stav:
- Jednotkové testy pro builder endpointů
- Jednotkové testy pro parser odpovědí
- Jednotkové testy pro HTTP transport (včetně maskovaného logování)
- Jednotkové testy pro hlavního klienta
- Kompilační test DI rozšíření
- Volitelný integrační test pokrývající reálný scénář create/read/update/delete proti ABRA Flexi API