Skip to content

Príklad: synchronizácia katalógu

Kompletný scenár, ako dostať katalóg z vlastného systému do Metty: nočný full sync, priebežné zmeny počas dňa a kontrola výsledku.

Nočný full sync

Full sync nahrá celý katalóg a odstráni všetko, čo v ňom už nie je. Je to jediná operácia, ktorá dokáže zmazať produkty bez toho, aby ste ich museli vymenovať.

php
use Metty\Client\Catalog\CatalogProduct;
use Metty\Client\Exception\SyncIncompleteException;
use Metty\Client\MettyClient;

$client = MettyClient::create(secretKey: getenv('METTY_SECRET_KEY'));

function catalog(PDO $database): Generator
{
    $statement = $database->query('SELECT * FROM product WHERE active = 1');

    while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
        yield CatalogProduct::create(
            id: $row['sku'],
            name: $row['name'],
            url: 'https://eshop.sk/produkt/' . $row['slug'],
            price: (float) $row['price'],
            listPrice: $row['price_before'] === null ? null : (float) $row['price_before'],
            currency: 'EUR',
            inStock: $row['stock'] > 0,
            brand: $row['brand'],
            category: $row['category_path'],
            description: $row['description'],
            image: $row['image_url'],
            params: json_decode($row['attributes'], true) ?? [],
        );
    }
}

try {
    $outcome = $client->catalog()->synchronize(catalog($database));

    printf("Sync %s: %d ponechaných, %d odstránených\n",
        $outcome['sync_id'],
        $outcome['commit']['kept'],
        $outcome['commit']['removed'],
    );
} catch (SyncIncompleteException $exception) {
    foreach ($exception->result->failures() as $failure) {
        fprintf(STDERR, "%s: %s\n", $failure->id, $failure->error);
    }

    exit(1);
}
bash
#!/usr/bin/env bash
set -euo pipefail

AUTH="Authorization: Bearer $METTY_SECRET_KEY"
BASE="https://catalog.api.metty.eu"

SYNC=$(curl -sf -X POST "$BASE/catalog/syncs" -H "$AUTH" | jq -r .sync_id)

for batch in batches/*.json; do
  curl -sf -X PUT "$BASE/catalog/products?sync=$SYNC" \
    -H "$AUTH" -H 'Content-Type: application/json' \
    --data-binary "@$batch" \
  | jq -e '[.results[] | select(.status != "ok")] | length == 0' > /dev/null \
  || { echo "Dávka $batch obsahuje chyby, sync $SYNC sa necommituje"; exit 1; }
done

curl -sf -X POST "$BASE/catalog/syncs/$SYNC/commit" -H "$AUTH" | jq

Kľúčové je poradie: commit až po overení všetkých dávok. Keby sa polovica katalógu nenahrala a sync by sa aj tak commitol, produkty, ktoré neprešli, by z e-shopu zmizli. PHP klient túto poistku aplikuje sám a v takom prípade vyhodí SyncIncompleteException s otvoreným syncId, ktorý sa dá dokončiť neskôr.

Ak katalóg zámerne zmenšujete o viac než polovicu, server commit odmietne s 409 generation_incomplete. Vedomé potvrdenie je force:

php
$client->catalog()->synchronize($products, force: true);

Priebežné zmeny počas dňa

Zmeny cien a dostupnosti neposielajte cez full sync — stačí PATCH s poľami, ktoré sa naozaj zmenili.

php
use Metty\Client\Catalog\CatalogProduct;

$result = $client->catalog()->patch([
    new CatalogProduct('sku-1', ['price' => 99.9, 'list_price' => 129.9]),
    new CatalogProduct('sku-2', ['in_stock' => false]),
    new CatalogProduct('sku-3', ['list_price' => null]),
]);

foreach ($result->failures() as $failure) {
    error_log(sprintf('%s: %s — %s', $failure->id, $failure->error, $failure->message));
}
bash
curl -sf -X PATCH https://catalog.api.metty.eu/catalog/products \
  -H "Authorization: Bearer $METTY_SECRET_KEY" \
  -H 'Content-Type: application/json' \
  -d '[
    { "id": "sku-1", "price": 99.9, "list_price": 129.9 },
    { "id": "sku-2", "in_stock": false },
    { "id": "sku-3", "list_price": null }
  ]'

Explicitné null pole vymaže, vynechané pole ponechá pôvodnú hodnotu. V PHP klientovi preto pre mazanie použite konštruktor CatalogProduct s mapou polí, nie továrničku create(), ktorá hodnoty null vynecháva.

Nové produkty a produkty s prepísaným celým obsahom posielajte cez replace(), respektíve PUT. Vyradené produkty odstránite jednou dávkou:

php
$client->catalog()->delete(['sku-9', 'sku-10']);

Kontrola stavu

Export vráti presne to, čo Metty eviduje, v rovnakom tvare, aký prijíma PUT:

php
$byId = [];
foreach ($client->catalog()->export() as $product) {
    $byId[$product['id']] = $product;
}

printf("V Metty je %d produktov\n", count($byId));

Porovnanie exportu s vlastnou databázou je najrýchlejší spôsob, ako odhaliť produkty, ktoré do Metty nikdy nedorazili.

Odporúčaná prevádzka

intervaloperácia
raz denne, mimo špičkyfull sync celého katalógu
každých pár minútPATCH cien a dostupnosti
pri publikovaní produktuPUT jedného produktu
pri vyradení produktuDELETE
týždenneporovnanie exportu s vlastnou databázou

Limit pre /catalog/* je 120 požiadaviek za minútu, pričom za každých 256 KB tela sa započíta ďalšia. Nočný sync katalógu s desiatkami tisíc produktov sa doň bez problémov zmestí; podrobnosti sú v sekcii Chyby a limity.

Dokumentácia Metty