इसे छोड़कर कंटेंट पर जाएं

मॉक सर्वर और स्थानीय परीक्षण

एकीकरण परीक्षण (Integration testing) अक्सर आधुनिक वेब अनुप्रयोगों के निर्माण के सबसे कठिन हिस्सों में से एक होता है। बाहरी सैंडबॉक्स (जैसे, Stripe, Razorpay, Braintree, Paytm) धीमे हो सकते हैं, दर-सीमित (rate-limited) हो सकते हैं, या उन्हें विशिष्ट विफलता स्थितियों (जैसे कि 503 Service Unavailable या उच्च विलंबता) में डालना कठिन होता है।

इस समस्या को हल करने के लिए, MirApi Gateway आपको सुरक्षित रूप से लचीले एकीकरण बनाने और विफलता मोड का परीक्षण करने में मदद करने के लिए mock.mirapi.io पर एक समर्पित, उच्च-प्रदर्शन मॉक वातावरण और स्टेटलेस परीक्षण उपयोगिताएँ प्रदान करता है।


1. MirApi मॉक सर्वर का परिचय (Introduction to MirApi Mock Server)

Section titled “1. MirApi मॉक सर्वर का परिचय (Introduction to MirApi Mock Server)”

MirApi मॉक सर्वर (https://mock.mirapi.io) को वास्तविक API कुंजियों, मर्चेंट खातों, या उत्पादन कोटा की आवश्यकता के बिना तीसरे पक्ष के भुगतान प्रदाताओं और API से प्रतिक्रियाओं का अनुकरण करने के लिए डिज़ाइन किया गया है।

  • सफलता और विफलता का अनुकरण: सत्यापित करें कि आपका एप्लिकेशन तब कैसा व्यवहार करता है जब अपस्ट्रीम API HTTP 500 Internal Server Error, 502 Bad Gateway, या 503 Service Unavailable स्थिति कोड लौटाते हैं।
  • विलंबता सिमुलेशन (delay पैरामीटर): HTTP क्लाइंट टाइमआउट, पुनः प्रयास लूप (retry loops), और सर्किट ब्रेकर संक्रमणों का परीक्षण करने के लिए कृत्रिम विलंब पेश करें।
  • लचीले क्रेडेंशियल: मॉक सर्वर क्रेडेंशियल ग्रुपिंग का समर्थन करता है। आप बहु-किरायेदार (multi-tenant) कॉन्फ़िगरेशन को सत्यापित करने के लिए SuperKey1, SuperKey2, या SuperKey3 जैसी प्रमाणीकरण कुंजियों का उपयोग कर सकते हैं।

2. OpenAPI विशिष्टता (OpenAPI Specification)

Section titled “2. OpenAPI विशिष्टता (OpenAPI Specification)”

मॉक सर्वर की पूरी API सतह को OpenAPI (Swagger) मानक का उपयोग करके प्रलेखित किया गया है।

  • 📄 सीधा OpenAPI विशिष्टता लिंक: https://mock.mirapi.io/openapi.yaml
  • 🛠️ इंटरैक्टिव स्वैगर संपादक: https://editor.swagger.io खोलें और अपने ब्राउज़र से सीधे परीक्षण अनुरोध भेजने के लिए हमारी विशिष्टता URL आयात करें।

3. स्टेटलेस वेबहुक परीक्षण (Stateless Webhooks Testing - Request Bin)

Section titled “3. स्टेटलेस वेबहुक परीक्षण (Stateless Webhooks Testing - Request Bin)”

स्थानीय स्तर पर एसिंक्रोनस वेबहुक (X-Webhook-Callback) का परीक्षण करने के लिए आमतौर पर Ngrok जैसे टूल के माध्यम से आपके स्थानीय सर्वर को सार्वजनिक इंटरनेट पर उजागर करने की आवश्यकता होती है, या सार्वजनिक अनुरोध बिन (जैसे, webhook.site) पर पेलोड भेजने की आवश्यकता होती है, जिससे संवेदनशील टोकन लीक होने का जोखिम हो सकता है।

MirApi स्थानीय विकास और स्वचालित CI/CD परीक्षण के दौरान वेबहुक कॉलबैक को कैप्चर, निरीक्षण और साफ़ करने के लिए एक निजी, स्टेटलेस, इन-मेमोरी Request Bin उपयोगिता प्रदान करता है।

वेबहुक निरीक्षण एंडपॉइंट:

Section titled “वेबहुक निरीक्षण एंडपॉइंट:”
  1. POST /webhooks/incoming?id=your-test-id
    प्रॉक्सी द्वारा भेजे गए किसी भी पेलोड को प्राप्त और संग्रहीत करता है। टकराव से बचने के लिए अपनी स्वयं की अनूठी your-test-id का उपयोग करें।
  2. GET /webhooks/inspect?id=your-test-id
    दिए गए ID के लिए कालानुक्रमिक क्रम में प्राप्त सभी वेबहुक पुनः प्राप्त करता है।
  3. POST /webhooks/clear?id=your-test-id
    दिए गए ID के लिए मेमोरी से सभी संग्रहीत वेबहुक साफ़ करता है।

4. PHP रीडायरेक्ट एकीकरण उदाहरण (PHP Redirect Integration Example)

Section titled “4. PHP रीडायरेक्ट एकीकरण उदाहरण (PHP Redirect Integration Example)”

प्रॉक्सी गेटवे की रीडायरेक्ट एक्सट्रैक्शन (X-Extract-Redirect) विशेषता आपको अपस्ट्रीम JSON प्रतिक्रिया (JSONPath सिंटैक्स का उपयोग करके) से एक चेकआउट या रीडायरेक्ट URL निकालने और तुरंत क्लाइंट को 302 Found रीडायरेक्ट जारी करने की अनुमति देती है।

नीचे मुख्य PHP cURL एकीकरण तर्क (पहली 50 पंक्तियाँ) दिया गया है। यदि आपको HTML UI और त्रुटि प्रबंधन के साथ पूरा तैयार PHP स्क्रिप्ट चाहिए, तो नीचे दिए गए सेक्शन को विस्तृत करें।

<?php
/**
* MirApi Proxy Gateway - Interactive PHP Redirect Extraction Example (Core Logic)
*
* Demonstrates the key cURL headers and 302/301 redirect extraction logic.
*/
// Check if the redirect action is triggered (GET parameter action=redirect)
if (isset($_GET['action']) && $_GET['action'] === 'redirect') {
$gatewayUrl = 'https://proxy.mirapi.io/'; // Proxy Gateway address
$apiKey = 'la_************************************************'; // Masked API Key (replace with your X-MirApi-Key)
$mockTargetUrl = 'https://mock.mirapi.io/echo/get/json'; // Target mock endpoint
$ch = curl_init($gatewayUrl);
$headers = [
'X-MirApi-Key: ' . $apiKey,
'X-Target-URL: ' . $mockTargetUrl,
// Instruct the proxy to extract $.urlResponse from mock response ("https://google.com") and return a 302 redirect
'X-Extract-Redirect: $.urlResponse',
'Content-Type: application/json'
];
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_HEADER => true, // Return headers in response to parse Location
CURLOPT_FOLLOWLOCATION => false, // Do not automatically follow redirects
CURLOPT_TIMEOUT => 10,
]);
$response = curl_exec($ch);
if ($response === false) {
die('cURL error: ' . curl_error($ch));
}
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$redirectUrl = '';
// Parse the Location header from proxy response
if ($httpCode === 302 || $httpCode === 301) {
$lines = explode("\r\n", $response);
foreach ($lines as $line) {
if (stripos($line, 'Location:') === 0) {
$redirectUrl = trim(substr($line, 9));
break;
}
}
}
// Perform final browser redirect if redirect URL was found
if (!empty($redirectUrl)) {
header("Location: " . $redirectUrl);
exit;
}
}
?>
पूरा PHP स्क्रिप्ट देखें (HTML UI और त्रुटि प्रबंधन सहित) / Expand Full PHP Script
<?php
/**
* MirApi Proxy Gateway - Interactive PHP Redirect Extraction Example
*
* This script combines a beautiful user interface with PHP cURL logic to test redirect extraction.
* You can open this file directly in your browser and click the button to run the test.
*/
// Check if the redirect action is triggered (GET parameter action=redirect)
if (isset($_GET['action']) && $_GET['action'] === 'redirect') {
$gatewayUrl = 'https://proxy.mirapi.io/'; // Proxy Gateway address
$apiKey = 'la_************************************************'; // Masked API Key (replace with your X-MirApi-Key)
$mockTargetUrl = 'https://mock.mirapi.io/echo/get/json'; // Target mock endpoint
$ch = curl_init($gatewayUrl);
$headers = [
'X-MirApi-Key: ' . $apiKey,
'X-Target-URL: ' . $mockTargetUrl,
// Instruct the proxy to extract $.urlResponse from mock response (which is "https://google.com") and return a 302 redirect
'X-Extract-Redirect: $.urlResponse',
'Content-Type: application/json'
];
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_HEADER => true, // Return headers in response to parse Location
CURLOPT_FOLLOWLOCATION => false, // Do not automatically follow redirects
CURLOPT_TIMEOUT => 10,
]);
$response = curl_exec($ch);
if ($response === false) {
die('cURL error: ' . curl_error($ch));
}
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$redirectUrl = '';
// Parse the Location header from proxy response
if ($httpCode === 302 || $httpCode === 301) {
$lines = explode("\r\n", $response);
foreach ($lines as $line) {
if (stripos($line, 'Location:') === 0) {
$redirectUrl = trim(substr($line, 9));
break;
}
}
}
// Perform final browser redirect if redirect URL was found
if (!empty($redirectUrl)) {
header("Location: " . $redirectUrl);
exit;
} else {
// Detailed error report page
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Redirect Error</title>
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700&display=swap" rel="stylesheet">
<style>
body { font-family: 'Plus Jakarta Sans', sans-serif; background: #020617; color: #f1f5f9; display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; padding: 20px; }
.card { background: rgba(30, 41, 59, 0.7); backdrop-filter: blur(16px); padding: 2.5rem; border-radius: 20px; max-width: 600px; border: 1px solid rgba(255, 255, 255, 0.08); box-shadow: 0 10px 30px -10px rgba(0,0,0,0.5); }
h1 { color: #f43f5e; font-size: 1.5rem; margin-top: 0; }
pre { background: #090d16; padding: 1.2rem; border-radius: 12px; overflow-x: auto; color: #38bdf8; font-family: monospace; font-size: 0.85rem; border: 1px solid rgba(255,255,255,0.05); }
.btn { display: inline-block; background: #3b82f6; color: white; padding: 0.8rem 1.8rem; border-radius: 10px; text-decoration: none; font-weight: 600; margin-top: 1rem; transition: background 0.2s; border: none; cursor: pointer; }
.btn:hover { background: #2563eb; }
</style>
</head>
<body>
<div class="card">
<h1>Redirect Extraction Failed</h1>
<p>Proxy returned status <strong><?php echo $httpCode; ?></strong> instead of the expected 302 Found.</p>
<p>This may indicate that the proxy server has not been updated to the latest binary version, or the target response could not be parsed successfully.</p>
<pre><?php echo htmlspecialchars($response); ?></pre>
<a href="php_redirect_example.php" class="btn">Back to Test</a>
</div>
</body>
</html>
<?php
exit;
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MirApi PHP Redirect Test</title>
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700&display=swap" rel="stylesheet">
<style>
:root {
--bg-gradient: linear-gradient(135deg, #0f172a 0%, #020617 100%);
--panel-bg: rgba(30, 41, 59, 0.65);
--panel-border: rgba(255, 255, 255, 0.08);
--text-primary: #f8fafc;
--text-secondary: #94a3b8;
--primary: #3b82f6;
--primary-hover: #2563eb;
--shadow: 0 20px 40px -15px rgba(0, 0, 0, 0.6);
}
body {
font-family: 'Plus Jakarta Sans', sans-serif;
background: var(--bg-gradient);
color: var(--text-primary);
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
margin: 0;
padding: 20px;
box-sizing: border-box;
}
.container {
background: var(--panel-bg);
backdrop-filter: blur(20px);
border: 1px solid var(--panel-border);
padding: 3.5rem 2.5rem;
border-radius: 24px;
max-width: 480px;
width: 100%;
text-align: center;
box-shadow: var(--shadow);
animation: fadeIn 0.5s ease-out;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
.icon {
font-size: 3.5rem;
margin-bottom: 1.5rem;
display: inline-block;
animation: pulse 2.5s infinite;
}
@keyframes pulse {
0% { transform: scale(1); }
50% { transform: scale(1.08); }
100% { transform: scale(1); }
}
h1 {
font-size: 1.8rem;
font-weight: 700;
margin: 0 0 1rem 0;
background: linear-gradient(to right, #60a5fa, #a78bfa);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
p {
color: var(--text-secondary);
font-size: 0.95rem;
line-height: 1.6;
margin: 0 0 2.2rem 0;
}
.card-details {
background: rgba(15, 23, 42, 0.45);
border: 1px solid rgba(255, 255, 255, 0.05);
border-radius: 14px;
padding: 1.2rem;
margin-bottom: 2.2rem;
text-align: left;
font-size: 0.85rem;
}
.detail-row {
display: flex;
justify-content: space-between;
margin-bottom: 0.6rem;
}
.detail-row:last-child {
margin-bottom: 0;
}
.detail-label {
color: var(--text-secondary);
}
.detail-value {
font-family: monospace;
color: #38bdf8;
font-weight: 500;
}
.btn-action {
display: block;
width: 100%;
background: var(--primary);
color: white;
padding: 1.1rem 2rem;
border-radius: 12px;
text-decoration: none;
font-weight: 600;
font-size: 1rem;
border: none;
cursor: pointer;
box-shadow: 0 4px 18px 0 rgba(59, 130, 246, 0.35);
transition: all 0.25s ease-in-out;
box-sizing: border-box;
}
.btn-action:hover {
background: var(--primary-hover);
transform: translateY(-2px);
box-shadow: 0 6px 24px 0 rgba(59, 130, 246, 0.45);
}
.btn-action:active {
transform: translateY(0);
}
.footer-note {
margin-top: 1.8rem;
font-size: 0.75rem;
color: var(--text-secondary);
text-transform: uppercase;
letter-spacing: 0.05em;
}
</style>
</head>
<body>
<div class="container">
<span class="icon"></span>
<h1>MirApi Redirect Flow</h1>
<p>Click the button below to initiate the test. The PHP backend will send a request to the proxy, which will extract the <strong>google.com</strong> link from the mock response and instantly redirect your browser there.</p>
<div class="card-details">
<div class="detail-row">
<span class="detail-label">Proxy Gateway:</span>
<span class="detail-value">proxy.mirapi.io</span>
</div>
<div class="detail-row">
<span class="detail-label">Target Upstream:</span>
<span class="detail-value">mock.mirapi.io/...</span>
</div>
<div class="detail-row">
<span class="detail-label">JSONPath Header:</span>
<span class="detail-value">$.urlResponse</span>
</div>
</div>
<a href="?action=redirect" class="btn-action">Execute Redirect</a>
<div class="footer-note">
Demonstration of X-Extract-Redirect Header
</div>
</div>
</body>
</html>

5. बॉडी मैपिंग प्रदर्शन (Dashboard Rules)

Section titled “5. बॉडी मैपिंग प्रदर्शन (Dashboard Rules)”

आप प्रॉक्सी के स्तर पर सीधे अनुरोध पेलोड (request payloads) का नाम बदल सकते हैं और पुनर्गठित कर सकते हैं, जिससे आपके बैकएंड में एडाप्टर कोड लिखने की आवश्यकता समाप्त हो जाती है।

डैशबोर्ड कॉन्फ़िगरेशन चरण:

Section titled “डैशबोर्ड कॉन्फ़िगरेशन चरण:”
  1. MirApi डैशबोर्ड पर जाएं और अपने CascadeURL रूट को संपादित करें।
  2. https://mock.mirapi.io/auth2/sameresponse या auth2/post की ओर इशारा करने वाले अपने लक्षित एंडपॉइंट का चयन करें।
  3. Body Map नियम अनुभाग में, नियम जोड़ें:
    data.amount=>data.sum, action=>event_type

अपने कॉन्फ़िगर किए गए CascadeURL रूट का परीक्षण करने के लिए cURL के माध्यम से एक अनुरोध भेजें:

Terminal window
curl --location 'https://proxy.mirapi.io/' \
--header 'X-MirApi-Key: la_************************************************' \
--header 'X-Route-Key: CascadeURL' \
--header 'Content-Type: application/json' \
--data '{
"action": "test-webhook",
"data": {
"amount": 10222
}
}'

अपेक्षित आउटपुट:

Section titled “अपेक्षित आउटपुट:”

चूंकि मॉक सर्वर पेलोड वापस प्रतिध्वनित (echo) करता है, आपको एक JSON प्रतिक्रिया प्राप्त होगी जो दर्शाती है कि प्रॉक्सी गेटवे द्वारा फ़ील्ड को अपस्ट्रीम पर भेजने से पहले स्वचालित रूप से बदल दिया गया था:

{
"event_type": "test-webhook",
"data": {
"sum": 10222
}
}

6. रिस्पॉन्स एक्सट्रैक्शन और ट्रांसफ़ॉर्मेशन उदाहरण (Response Extraction & Transformation)

Section titled “6. रिस्पॉन्स एक्सट्रैक्शन और ट्रांसफ़ॉर्मेशन उदाहरण (Response Extraction & Transformation)”

आप API प्रतिक्रियाओं की संरचना को गतिशील रूप से बदलने, या विशिष्ट JSON फ़ील्ड पर तत्काल रीडायरेक्शन ट्रिगर करने के लिए अनुरोध हेडर का भी उपयोग कर सकते हैं।

परीक्षण करने के लिए, हम मॉक एंडपॉइंट GET https://mock.mirapi.io/echo/get/json को क्वेरी करेंगे, जो निम्नलिखित JSON पेलोड लौटाता है:

{
"success": "true",
"message": "reqres standard echo response",
"urlResponse": "https://google.com",
"amount": "100"
}

परीक्षण 1: X-Extract-Map के माध्यम से प्रतिक्रिया बदलना

Section titled “परीक्षण 1: X-Extract-Map के माध्यम से प्रतिक्रिया बदलना”

केवल amount और message फ़ील्ड निकालें, उन्हें क्रमशः total और info नाम दें।

Terminal window
curl -i --location 'https://proxy.mirapi.io/' \
--header 'X-MirApi-Key: la_************************************************' \
--header 'X-Target-URL: https://mock.mirapi.io/echo/get/json' \
--header 'X-Extract-Map: $.amount=>total, $.message=>info'

अपेक्षित आउटपुट:

Section titled “अपेक्षित आउटपुट:”

प्रॉक्सी गेटवे प्रतिक्रिया को रोकता है, JSONPath का उपयोग करके फ़ील्ड निकालता है, और परिणाम देता है:

{
"total": "100",
"info": "reqres standard echo response"
}

परीक्षण 2: X-Extract-Redirect के माध्यम से क्लाइंट रीडायरेक्शन

Section titled “परीक्षण 2: X-Extract-Redirect के माध्यम से क्लाइंट रीडायरेक्शन”

urlResponse फ़ील्ड (जिसमें https://google.com शामिल है) को निकालें और प्रॉक्सी को तत्काल 302 Found रीडायरेक्शन जारी करने का निर्देश दें।

(cURL को रीडायरेक्ट का पालन करने से रोकने के लिए --location ध्वज छोड़ दें, जिससे आप हेडर का निरीक्षण कर सकें)।

Terminal window
curl -i 'https://proxy.mirapi.io/' \
--header 'X-MirApi-Key: la_************************************************' \
--header 'X-Target-URL: https://mock.mirapi.io/echo/get/json' \
--header 'X-Extract-Redirect: $.urlResponse'

अपेक्षित आउटपुट:

Section titled “अपेक्षित आउटपुट:”

गेटवे प्रतिक्रिया को रोकता है, https://google.com निकालता है, और Google की ओर इशारा करते हुए 302 Found रीडायरेक्शन के साथ प्रतिक्रिया करता है:

HTTP/1.1 302 Found
Location: https://google.com
Content-Length: 0