Перейти до вмісту

Витягнення відповіді

MirApi може витягувати конкретні поля з відповідей upstream і реструктурувати JSON — або зробити редирект до URL знайденого у тілі відповіді — без жодних змін у коді додатку.

Два заголовки керують трансформацією відповіді:

  • X-Extract-Redirect — Знайти URL у тілі відповіді і зробити редирект на нього (302 Found)
  • X-Extract-Map — Витягнути та перейменувати поля з тіла відповіді у новий JSON-об’єкт

Витягує URL з тіла відповіді upstream через JSONPath (або ланцюжок fallback через ||) і повертає 302 Found редирект.

При успішній відповіді від upstream (статус-код 2xx) проксі аналізує тіло відповіді. Він шукає значення за вказаним JSONPath. Якщо значення знайдено, проксі перериває стандартну передачу відповіді клієнту та повертає HTTP-редирект 302 Found на отриманий URL.

  • Підтримка ланцюжків альтернатив (fallback): Вираз підтримує логічне або ||. Наприклад, X-Extract-Redirect: $.url || $.checkoutUrl || $.data.payment_link. Проксі перевірить кожен шлях по черзі й перенаправить на перший, що поверне непусте значення.
  • Автоматичне приведення типів: Якщо знайдений вузол є не рядком, а наприклад числом чи логічним значенням, він буде автоматично конвертований у рядок.
  • Спрацьовує тільки при 2xx: Якщо upstream повернув помилку (наприклад 400 або 500), редирект не виконується, щоб клієнт міг побачити оригінальну помилку.

Особливості синтаксису

Section titled “Особливості синтаксису”
МожливістьДеталі
Префікс $.Необов’язковий — додається автоматично, якщо відсутній
Нотація масиву []Підтримується — витягує URL редиректу з елементів масиву
Terminal window
# Upstream повертає: {"session_id": "cs_123", "url": "https://checkout.stripe.com/pay/cs_123"}
curl -X POST https://proxy.mirapi.io/ \
-H "X-MirApi-Key: $MIRAPI_KEY" \
-H "X-Target-URL: https://api.stripe.com/v1/checkout/sessions" \
-H "X-Identity-Key: Bearer sk_live_..." \
-H "X-Extract-Redirect: url" \
-d '{"mode": "payment", "line_items": [...]}'
# $. додається автоматично — еквівалентно X-Extract-Redirect: $.url
# → 302 Found
# → Location: https://checkout.stripe.com/pay/cs_123

Різні платіжні провайдери використовують різні назви поля для checkout URL. Використовуйте || щоб спробувати кілька шляхів по порядку. Префікс $. є необов’язковим для кожного виразу:

Terminal window
# Працює з Stripe, Adyen, PayU та іншими провайдерами
curl -X POST https://proxy.mirapi.io/ \
-H "X-MirApi-Key: $MIRAPI_KEY" \
-H "X-Target-URL: https://api.payment-provider.com/sessions" \
-H "X-Extract-Redirect: url || checkoutUrl || data.payment_link || redirect_url" \
-d '{"amount": 9900, "currency": "usd"}'
# MirApi пробує кожен шлях по порядку — перше ненульове значення перемагає
# → 302 Found з знайденою URL
# Універсальний платіжний редирект через каскадний маршрут
curl -X POST https://proxy.mirapi.io/ \
-H "X-MirApi-Key: $MIRAPI_KEY" \
-H "X-Route-Key: payment-cascade" \
-H "X-Extract-Redirect: url || checkoutUrl || data.payment_link" \
-d '{"amount": 9900, "currency": "usd"}'

Використовуйте [] для витягнення URL редиректу з елементів всередині масиву:

Terminal window
# Upstream повертає: {"data": {"orders": [{"id": "ord_1", "checkout_url": "https://pay.example.com/ord_1"}]}}
curl -X POST https://proxy.mirapi.io/ \
-H "X-MirApi-Key: $MIRAPI_KEY" \
-H "X-Target-URL: https://api.provider.com/checkout" \
-H "X-Extract-Redirect: data.orders[].checkout_url" \
-d '{"order_ref": "ord_1"}'
# → 302 Found
# → Location: https://pay.example.com/ord_1

Маппінг відповіді розбирає JSON upstream, витягує поля через JSONPath і формує новий JSON-запит для клієнта. Повертаються лише ті поля, які явно зазначені в правилах — всі інші видаляються (принцип білого списку).

Він перехоплює JSON-відповідь upstream-сервера і трансформує її структуру перед тим, як віддати клієнту.

  • Множинний мапінг через кому: Можна перейменовувати кілька полів одночасно.
    • Приклад: X-Extract-Map: $.id=>charge_id, $.status=>state
  • Створення вкладених структур: Цільовий ключ (targetKey) підтримує крапкову нотацію для генерації вкладених об’єктів JSON.
    • Приклад: $.id=>data.charge.id згенерує {"data": {"charge": {"id": "..."}}}.
  • Робота з масивами/списками: Можна трансформувати цілі масиви об’єктів за допомогою порожніх дужок [].
    • Приклад: provider_data.orders[].order_id=>data.orders[].order
  • Шаблонізація значень (Value Interpolation): Ви можете форматувати вихідні значення, підставляючи їх у текстовий шаблон за допомогою синтаксису target_key(Шаблон {value}). Також підтримується підстановка сусідніх полів з контексту JSON.
    • Приклад (Value Interpolation): provider_data.order_id=>data.order_text(Order #{value}) перетворить ID 123 на {"data":{"order_text":"Order #123"}}.
    • Приклад крос-полевого шаблону: status=>status_text(Order {order_id} is {value}) підставить значення поля order_id з того самого рівня вкладеності.
  • Single Field Fallback (без =>): Якщо передати просто JSONPath без вказівки нового імені (наприклад, X-Extract-Map: $.status), то проксі поверне JSON із цим значенням у стандартному ключі extracted.
    • Приклад: {"extracted": "success"}.

Джерело (ліва сторона) та ціль (права сторона) => використовують єдиний синтаксис:

МожливістьДеталі
Префікс $. для джерелаНеобов’язковий — додається автоматично, якщо відсутній
Масиви на джереліВикористовуйте [] замість JSONPath wildcard [*]
Вкладені ключі ціліПідтримується dot-notation (наприклад, data.order)
Кілька запитів до масивуОб’єднуються в єдиний масив за індексом елементу
Шаблон значення {value}Форматує витягнуте значення у рядковий шаблон
Міжпольовий шаблон {field_name}Інтерполює інші поля з того ж елементу масиву у вихідний результат

A. Плоске витягнення та маппінг

Section titled “A. Плоске витягнення та маппінг”

Витягує поле і мапує на новий плоский ключ. Префікс $. є необов’язковим:

Terminal window
curl https://proxy.mirapi.io/ \
-H "X-MirApi-Key: $MIRAPI_KEY" \
-H "X-Target-URL: https://api.provider.com/orders" \
-H "X-Extract-Map: provider_data.order_id=>order_id"
# Upstream: {"provider_data": {"order_id": 353454876}}
# Повертає: {"order_id": "353454876"}
# Витягнути IP-адресу викликача
curl https://proxy.mirapi.io/ \
-H "X-MirApi-Key: $MIRAPI_KEY" \
-H "X-Target-URL: https://httpbin.org/get" \
-H "X-Extract-Map: $.origin"
# Повертає: {"extracted": "93.123.45.67"}

B. Генерація вкладеної структури

Section titled “B. Генерація вкладеної структури”

Створює вкладені JSON-структури в виході для клієнта використовуючи dot-notation з правого боку:

Terminal window
curl -X POST https://proxy.mirapi.io/ \
-H "X-MirApi-Key: $MIRAPI_KEY" \
-H "X-Target-URL: https://api.provider.com/orders" \
-H "X-Extract-Map: provider_data.order_id=>data.order" \
-d '{"ref": "ord_999"}'
# Upstream: {"provider_data": {"order_id": 353454876}}
# Повертає: {"data": {"order": "353454876"}}
# Нормалізація відповіді Stripe
curl -X POST https://proxy.mirapi.io/ \
-H "X-MirApi-Key: $MIRAPI_KEY" \
-H "X-Target-URL: https://api.stripe.com/v1/charges" \
-H "X-Identity-Key: Bearer sk_live_..." \
-H "X-Extract-Map: $.id=>charge_id, $.status=>payment_status, $.amount=>amount_cents, $.created=>created_at" \
-d '{"amount": 2000, "currency": "usd", "source": "tok_visa"}'
# Повертає: {"charge_id": "ch_3Pz9...", "payment_status": "succeeded", "amount_cents": 2000, "created_at": 1748130000}

Витягує масиви з upstream і розміщує їх під кастомними ключами. [] для перебору кожного елементу:

Terminal window
curl -X POST https://proxy.mirapi.io/ \
-H "X-MirApi-Key: $MIRAPI_KEY" \
-H "X-Target-URL: https://api.provider.com/orders" \
-H "X-Extract-Map: provider_data.orders[].order_id=>data.orders[].order" \
-d '{"customer": "cus_123"}'
# Upstream: {"provider_data": {"orders": [{"order_id": 111}, {"order_id": 222}]}}
# Повертає: {"data": {"orders": [{"order": "111"}, {"order": "222"}]}}

D. Об’єднання кількох полів масиву

Section titled “D. Об’єднання кількох полів масиву”

Кілька правил з однаковим шляхом масиву об’єднуються в єдиний масив за індексом елементу:

Terminal window
curl -X POST https://proxy.mirapi.io/ \
-H "X-MirApi-Key: $MIRAPI_KEY" \
-H "X-Target-URL: https://api.provider.com/orders" \
-H "X-Extract-Map: provider_data.orders[].order_id=>data.orders[].order, provider_data.orders[].amount=>data.orders[].sum" \
-d '{"customer": "cus_123"}'
# Upstream: {"provider_data": {"orders": [{"order_id": 111, "amount": 100}, {"order_id": 222, "amount": 200}]}}
# Повертає: {"data": {"orders": [{"order": "111", "sum": "100"}, {"order": "222", "sum": "200"}]}}
# Нормалізація AI-провайдера
curl -X POST https://proxy.mirapi.io/ \
-H "X-MirApi-Key: $MIRAPI_KEY" \
-H "X-Route-Key: ai-providers" \
-H "X-Extract-Map: $.choices[0].message.content=>text, $.model=>model_used" \
-d '{"model": "gpt-4o", "messages": [{"role": "user", "content": "Привіт"}]}'
# Повертає: {"text": "Привіт! Чим можу допомогти?", "model_used": "gpt-4o"}

E. Шаблони значень та міжпольові шаблони у масивах

Section titled “E. Шаблони значень та міжпольові шаблони у масивах”

Додайте шаблонний рядок у дужках після назви ключа-цілі. {value} — пластина для витягнутого поля, {field_name} — посилання на будь-яке сусіднє поле в межах того ж елементу масиву:

Terminal window
curl -X POST https://proxy.mirapi.io/ \
-H "X-MirApi-Key: $MIRAPI_KEY" \
-H "X-Target-URL: https://api.provider.com/orders" \
-H "X-Extract-Map: provider_data.orders[].order_id=>data.orders[].order_id, provider_data.orders[].status=>data.orders[].status_text(Order {order_id} is {value})" \
-d '{"customer": "cus_123"}'
# Upstream: {"provider_data": {"orders": [
# {"order_id": 111, "status": "success"},
# {"order_id": 222, "status": "fail"}
# ]}}
# Повертає: {"data": {"orders": [
# {"order_id": "111", "status_text": "Order 111 is success"},
# {"order_id": "222", "status_text": "Order 222 is fail"}
# ]}}

Правила пластин шаблону:

  • {value} — витягнуте значення джерельного поля
  • {field_name} — будь-яке сусіднє поле, вже змапповане до того ж елементу масиву
ЗаголовокВикористовується коли…Відповідь
X-Extract-RedirectUpstream повертає URL для редиректу302 Found з заголовком Location
X-Extract-MapПотрібна обрізана/перейменована JSON відповідь200 OK з трансформованим JSON-тілом