شرایط با متغیرهای جریان

شما در حال مشاهده اسناد Apigee Edge هستید.
به مستندات Apigee X بروید .
اطلاعات

دستورات شرطی یک ساختار کنترلی مشترک در همه زبان های برنامه نویسی هستند. مانند یک زبان برنامه نویسی، پیکربندی پراکسی API از عبارات شرطی برای جریان ها، سیاست ها، مراحل و روت رول ها پشتیبانی می کند. با تعریف عبارات شرطی، رفتار پویا را برای API خود تعریف می کنید. این رفتار پویا به شما امکان می‌دهد کارهایی مانند تبدیل XML به JSON فقط برای دستگاه‌های تلفن همراه یا مسیریابی به URL پشتیبان بر اساس نوع محتوا یا فعل HTTP پیام درخواست را انجام دهید.

این مبحث به شما نشان می‌دهد که چگونه می‌توانید از شرایط برای اعمال پویا ویژگی‌های مدیریت API در زمان اجرا، بدون نوشتن هیچ کدی استفاده کنید.

دستورات شرطی را پیکربندی کنید

رفتار شرطی در پراکسی های API با استفاده از ترکیبی از شرایط و متغیرها پیاده سازی می شود. یک دستور شرطی با استفاده از عنصر Condition ایجاد می شود. شرط زیر یک شرط خالی است:

<Condition></Condition>

برای ایجاد یک دستور شرطی، یک عملگر شرطی و یک متغیر برای ایجاد ساختار زیر اضافه می کنید:

<Condition>{variable.name}{operator}{"value"}</Condition>

عملگرهای شرطی پشتیبانی شده عبارتند از = (برابر)، != (برابر نیست)، و > (بیشتر از). برای خوانایی، می‌توانید شرط‌ها را نیز به صورت متن بنویسید: equals ، notequals ، greaterthan .

هنگام کار با مسیرهای URI می توانید از ~/ یا MatchesPath استفاده کنید. همچنین می توانید عبارات منظم JavaRegex را با عملگر ~~ مطابقت دهید.

شرایط برای تعریف جریان‌های شرطی پروکسی API برای منابع API پشتیبان، که در ایجاد جریان‌های شرطی به منابع API باطنی توضیح داده شده است، استفاده می‌شود. برای فهرست کامل شرط ها، به مرجع شرایط مراجعه کنید.

متغیرها

شرایط کار خود را با ارزیابی مقادیر متغیرها انجام می دهند. یک متغیر ویژگی یک تراکنش HTTP است که توسط یک پراکسی API اجرا می شود، یا یک ویژگی از خود پیکربندی پروکسی API است. هر زمان که یک پروکسی API درخواستی از یک برنامه دریافت می کند، Apigee Edge لیست طولانی از متغیرهایی را پر می کند که با مواردی مانند زمان سیستم، اطلاعات شبکه برنامه، هدرهای HTTP روی پیام ها، پیکربندی پروکسی API، اجرای سیاست ها و غیره مرتبط هستند. این یک زمینه غنی ایجاد می کند که می توانید از آن برای تنظیم عبارات شرطی استفاده کنید.

متغیرها همیشه از علامت نقطه‌گذاری استفاده می‌کنند. برای مثال، هدرهای HTTP در پیام درخواست به عنوان متغیرهایی به نام request.header.{header_name} . بنابراین برای ارزیابی هدر Content-type، می توانید از متغیر request.header.Content-type استفاده کنید. برای مثال request.header.Content-type = "application/json" نشان می دهد که نوع محتوای درخواست باید JSON باشد.

تصور کنید که باید یک عبارت شرطی ایجاد کنید که باعث شود یک خط مشی فقط زمانی اجرا شود که یک پیام درخواست GET باشد. برای ایجاد شرطی که فعل HTTP یک درخواست را ارزیابی می کند، عبارت شرطی زیر را ایجاد می کنید. متغیر در این شرط request.verb است. مقدار متغیر GET است. عملگر = است.

<Condition>request.verb = "GET"</Condition>
شما همچنین می توانید استفاده کنید:
<Condition>request.verb equals "GET"</Condition>

Edge از چنین عبارتی برای ارزیابی شرایط استفاده می کند. اگر فعل HTTP مرتبط با درخواست GET باشد، مثال بالا درست ارزیابی می‌کند. اگر فعل HTTP مرتبط با درخواست POST باشد، عبارت به نادرست ارزیابی می شود.

برای فعال کردن رفتار پویا، می‌توانید Conditions را به Flows، Steps و RouteRules متصل کنید.

هنگامی که یک شرط را به یک جریان متصل می کنید، یک "جریان شرطی" ایجاد می کنید. جریان های شرطی فقط زمانی اجرا می شوند که شرط به درستی ارزیابی شود. می‌توانید هر تعداد سیاستی که می‌خواهید به یک جریان شرطی پیوست کنید. یک جریان شرطی به شما امکان می‌دهد تا قوانین پردازش بسیار تخصصی را برای پیام‌های درخواست یا پاسخی که معیارهای خاصی را برآورده می‌کنند، ایجاد کنید.

به عنوان مثال، برای ایجاد یک Flow که فقط زمانی اجرا می شود که فعل درخواست GET باشد:

<Flows>
  <Flow name="ExecuteForGETs">
  <Condition>request.verb="GET"</Condition>
  </Flow>
</Flows>

برای ایجاد یک جریان برای GET و دیگری برای POST:

<Flows>
  <Flow name="ExecuteForGETs">
  <Condition>request.verb="GET"</Condition>
  </Flow>
  <Flow name="ExecuteForPOSTs">
  <Condition>request.verb="POST"</Condition>
  </Flow>
</Flows>

همانطور که در مثال زیر نشان داده شده است، می توانید این شرط را در خود Policy Step اعمال کنید. شرط زیر باعث می شود که سیاست VerifyApiKey فقط در صورتی اجرا شود که یک پیام درخواستی POST باشد.

<PreFlow name="PreFlow">
    <Request>
        <Step>
            <Condition>request.verb equals "POST"</Condition>
            <Name>VerifyApiKey</Name>
        </Step>
    </Request>
</PreFlow>

هنگامی که چنین جریان‌های شرطی را تعریف کردید، می‌توانید خط‌مشی‌هایی را به آن‌ها ضمیمه کنید و به یک پراکسی API این امکان را می‌دهید که مجموعه‌ای از خط‌مشی‌ها را برای درخواست‌های GET و مجموعه‌ای دیگر از خط‌مشی‌ها را برای درخواست‌های POST اعمال کند.

برای اطلاعات جامع مرجع، به منابع زیر مراجعه کنید:

مثال 1

مثال زیر یک جریان شرطی منفرد به نام Convert-for-devices را نشان می دهد که در جریان پاسخ ProxyEndpoint پیکربندی شده است. شرط را به عنوان عنصری به موجودی که شرط در مورد آن اعمال می شود، اضافه کنید. در این مثال، شرط جزئی از جریان است. بنابراین، هر زمان که عبارت درست ارزیابی شود، جریان اجرا خواهد شد.

<Flows>
  <Flow name="Convert-for-devices">
  <Condition>(request.header.User-Agent = "Mozilla")</Condition>
    <Response>
      <Step><Name>ConvertToJSON</Name></Step>
    </Response>
  </Flow>
</Flows>

برای هر درخواست دریافت شده از یک برنامه، Edge مقادیر تمام هدرهای HTTP موجود به عنوان متغیر را ذخیره می کند. اگر درخواست حاوی یک هدر HTTP به نام User-Agent باشد، آن هدر و مقدار آن به عنوان متغیری به نام request.header.User-Agent ذخیره می شود.

با توجه به پیکربندی ProxyEndpoint در بالا، Edge مقدار متغیر request.header.User-Agent را بررسی می کند تا ببیند آیا شرط به درستی ارزیابی می شود یا خیر.

اگر شرط به درستی ارزیابی شود، یعنی مقدار متغیر request.header.User-Agent برابر با Mozilla باشد، آنگاه Flow شرطی اجرا می شود و خط مشی XMLtoJSON به نام ConvertToJSON اجرا می شود. در غیر این صورت، Flow اجرا نمی شود و پاسخ XML بدون تغییر (در قالب XML) به برنامه درخواست کننده بازگردانده می شود.

مثال 2

بیایید از یک مثال خاص استفاده کنیم که در آن باید پیام پاسخ را از XML به JSON تبدیل کنید - اما فقط برای دستگاه های تلفن همراه. ابتدا خط مشی را ایجاد کنید که پاسخ فرمت XML را از Weather API به JSON تبدیل کند:

<XMLToJSON name="ConvertToJSON">
  <Options>
  </Options>
  <OutputVariable>response</OutputVariable>
  <Source>response</Source>
</XMLToJSON>

پیکربندی خط‌مشی بالا به پراکسی API می‌گوید که پیام پاسخ را دریافت کند، با تنظیمات پیش‌فرض، تبدیل از XML به JSON را انجام دهد و سپس نتیجه را در پیام پاسخ جدید بنویسد. (اگر پیام درخواستی را از XML به JSON تبدیل می کنید، به سادگی هر دوی این مقادیر را برای request تنظیم کنید.)

از آنجایی که می‌خواهید پاسخ‌ها را از XML به JSON تبدیل کنید، باید یک جریان پاسخ شرطی را برای انجام تبدیل پیکربندی کنید. به عنوان مثال، برای تبدیل همه پاسخ‌ها از XML به JSON قبل از اینکه به برنامه مشتری بازگردانده شوند، جریان پاسخ ProxyEndpoint زیر را پیکربندی کنید.

<Flows>
  <Flow name="Convert-for-devices">
    <Response>
      <Step><Name>ConvertToJSON</Name></Step>
    </Response>
  </Flow>
</Flows>

وقتی API را با استفاده از درخواست استاندارد فراخوانی می‌کنید، پاسخ در JSON قالب‌بندی می‌شود.

با این حال، هدف شما این است که گزارش‌های آب و هوا را تنها زمانی به JSON تبدیل کنید که مشتری درخواست‌کننده یک دستگاه تلفن همراه باشد . برای فعال کردن چنین رفتار پویا، باید یک دستور شرطی به Flow اضافه کنید.

جریان مشروط را آزمایش کنید

در این درخواست نمونه، هدر HTTP User-Agent روی Mozilla تنظیم شده است که باعث می شود عبارت شرطی به درستی ارزیابی شود و جریان شرطی Convert-for-devices اجرا شود.

$ curl -H "User-Agent:Mozilla" http://{org_name}-test.apigee.net/weather/forecastrss?w=12797282

یا برای چاپ زیبا در جایی که پایتون در دسترس است:

$ curl -H "User-Agent:Mozilla" http://{org_name}-test.apigee.net/weather/forecastrss?w=12797282 | python -mjson.tool

نمونه پاسخ:

. . .

"yweather_forecast": [
         {
              "code": "11",
              "date": "12 Dec 2012",
              "day": "Wed",
              "high": "55",
              "low": "36",
              "text": "Showers"
          },
          {
              "code": "32",
              "date": "13 Dec 2012",
              "day": "Thu",
              "high": "56",
              "low": "38",
              "text": "Sunny"
          }
      ]
  }

. . .

درخواستی که بدون سربرگ User-Agent یا با مقداری متفاوت از Mozilla ارسال شود، منجر به پاسخی با قالب XML خواهد شد.

$ curl http://{org_name}-test.apigee.net/weather/forecastrss?w=12797282

پاسخ XML اصلاح نشده برگردانده می شود.

نمونه پاسخ:

<yweather:forecast day="Wed" date="12 Dec 2012" low="36" high="55" text="Showers" code="11" /> <yweather:forecast day="Thu" date="13 Dec 2012" low="38" high="56" text="Sunny" code="32" />

تطبیق الگو

این بخش نحوه استفاده از تطبیق الگو با شرایط در یک جریان Apigee را توضیح می دهد.

اپراتورها

این بخش نحوه استفاده از عملگرهای تطبیق الگوی زیر را در عبارات شرطی توضیح می دهد:

مسابقات

بیایید ابتدا به عملگر شرطی "Matches" یا "~" نگاه کنیم. این دو عملگر یکسان هستند -- نسخه انگلیسی "Matches" گزینه قابل خواندن تری در نظر گرفته می شود.

خلاصه: عملگر "Match" دو احتمال را به شما می دهد. یا رشته را به معنای واقعی کلمه مطابقت دهید، یا یک تطبیق عام با "*" انجام دهید. همانطور که ممکن است انتظار داشته باشید، حروف عام با صفر یا بیشتر کاراکتر مطابقت دارد. بیایید ببینیم این چگونه کار می کند.

XML زیر یک شرط Step را نشان می دهد. زمانی سیاست SomePolicy را اجرا می کند که شرط به درستی ارزیابی شود. در این مثال، متغیر proxy.pathsuffix را آزمایش می‌کنیم، یک متغیر داخلی در Edge که پسوند مسیر درخواست را ذخیره می‌کند. توجه داشته باشید، با این حال، می توانید مقدار هر متغیر جریانی را که دارای یک رشته است، آزمایش کنید. بنابراین، در این حالت، اگر مسیر پایه درخواست ورودی /animals و درخواست /animals/cat باشد، پسوند مسیر رشته تحت اللفظی " /cat " است.

    <PreFlow name="PreFlow">
        <Request>
            <Step>
                <Condition>(proxy.pathsuffix Matches "/cat")</Condition>
                <Name>SomePolicy</Name>
            </Step>
        </Request>
        <Response/>
    </PreFlow>

سوال: کدام پسوند مسیر پراکسی باعث اجرای SomePolicy می شود؟ فقط یک امکان وجود دارد

تماس API:

GET http://artomatic-test.apigee.net/matchtest/cat

آیا سیاست اجرا می شود؟ بله، زیرا پسوند مسیر پراکسی دقیقاً با " /cat " مطابقت دارد. اگر پسوند /bat یا /dog یا " / " یا هر چیز دیگری باشد، اجرا نمی شود.

اکنون، این عبارت شرطی را در نظر بگیرید که در آن از کاراکتر عام " * " استفاده می کنیم:

<Condition>(proxy.pathsuffix Matches "/*at")</Condition>

تماس API:

GET http://artomatic-test.apigee.net/matchtest/cat

آیا سیاست اجرا می شود؟ بله، زیرا حروف عام با هر شخصیتی مطابقت دارد و "/cat " یک تطابق است.

تماس API:

GET http://artomatic-test.apigee.net/matchtest/bat

آیا سیاست اجرا می شود؟ بله، چون حروف عام با هر شخصیتی مطابقت دارد، "/bat" یک تطابق است.

تماس API:

GET http://artomatic-test.apigee.net/matchtest/owl

آیا سیاست اجرا می شود؟ مطمئناً نه -- اگرچه حروف عام با " o " مطابقت دارد، اما حروف " wl " مطابقت ندارند.

حال اجازه دهید علامت عام را به انتهای پسوند منتقل کنیم:

<Condition>(proxy.pathsuffix Matches "/cat*")</Condition>

تماس API:

GET http://artomatic-test.apigee.net/matchtest/cat

آیا سیاست اجرا می شود؟ بله، زیرا حروف عام با صفر یا بیشتر از هر کاراکتری مطابقت دارد.

تماس API:

GET http://artomatic-test.apigee.net/matchtest/bat

آیا سیاست اجرا می شود؟ نه، " /bat " همسان نیست.

تماس API:

GET http://artomatic-test.apigee.net/matchtest/cat123

آیا سیاست اجرا می شود؟ بله، حروف عام با صفر یا بیشتر از هر کاراکتر مطابقت دارد، بنابراین " 123 " یک تطابق ایجاد می کند.

تماس API:

GET http://artomatic-test.apigee.net/matchtest/cat/bird/mouse

آیا سیاست اجرا می شود؟ بله، از آنجا که کاراکتر عام با صفر یا بیشتر از هر کاراکتر مطابقت دارد، بنابراین " /bird/mouse " یک تطابق ایجاد می کند. توجه داشته باشید که چگونه عبارتی مانند این می تواند شما را به دردسر بیاندازد زیرا با همه چیز بعد از کاراکترهای تحت اللفظی مطابقت دارد!

سوال: آیا عملگر Maches به حروف کوچک و بزرگ حساس است؟

بله. فرض کنید شرایطی مانند این دارید:

<Condition>(proxy.pathsuffix Matches "/*At")</Condition>

تماس API:

GET http://artomatic-test.apigee.net/matchtest/cat

آیا سیاست اجرا می شود؟ خیر، حروف عام با هر حرفی مطابقت دارد (بدون توجه به حروف کوچک)، اما حروف کوچک "a" با "A" مطابقت ندارد.

تماس API:

GET http://artomatic-test.apigee.net/matchtest/bAt

آیا سیاست اجرا می شود؟ بله، مورد مطابقت دارد.

سوال: چگونه با عملگر Maches از کاراکترها فرار کنم؟

از نویسه درصد "%" برای فرار از کاراکترهای رزرو شده استفاده کنید. به عنوان مثال:

<Condition>(proxy.pathsuffix Matches "/c%*at")</Condition>

تماس API:

GET http://artomatic-test.apigee.net/matchtest/cat

آیا سیاست اجرا می شود؟ نه، عملگر Matches به دنبال رشته تحت اللفظی "c*at" است.

تماس API:

GET http://artomatic-test.apigee.net/matchtest/c*at

سوال: آیا این خط مشی اجرا می شود؟

بله، این مسیر، اگرچه کمی غیر معمول، مطابقت دارد.

JavaRegex

همانطور که می بینید، عملگر "Match" برای موقعیت های ساده عالی است. اما شما می توانید از یک عملگر دیگر، "JavaRegex" یا "~~" استفاده کنید. این دو عملگر یکسان هستند، با این تفاوت که JavaRegex قابل خواندن تر است. JavaRegex نامیده می شود زیرا امکان تطبیق الگوی عبارت منظم را می دهد و Edge از قوانین مشابه کلاس های بسته java.util.regex در زبان جاوا پیروی می کند. نحوه کار اپراتور JavaRegex با عملگر Matches بسیار متفاوت است، بنابراین مهم است که این دو را اشتباه نگیرید!

خلاصه: عملگر "JavaRegex" به شما امکان می دهد از نحو عبارت منظم در دستورات شرطی استفاده کنید.

کد زیر یک شرط Step را نشان می دهد. اگر شرط به درستی ارزیابی شود، خط مشی SomePolicy را اجرا می کند. در این مثال، متغیر proxy.pathsuffix را آزمایش می‌کنیم، یک متغیر داخلی در Edge که پسوند مسیر درخواست را ذخیره می‌کند. اگر مسیر پایه درخواست ورودی /animals و درخواست /animals/cat باشد، پسوند مسیر رشته تحت اللفظی " /cat " است.

    <PreFlow name="PreFlow">
        <Request>
            <Step>
                <Condition>(proxy.pathsuffix JavaRegex "/cat")</Condition>
                <Name>SomePolicy</Name>
            </Step>
        </Request>
        <Response/>
    </PreFlow>

سوال: کدام پسوند مسیر پراکسی باعث اجرای SomePolicy می شود؟ درست مانند عملگر Maches، در این مورد نیز تنها یک امکان وجود دارد.

تماس API:

GET http://artomatic-test.apigee.net/matchtest/cat

آیا سیاست اجرا می شود؟ بله، زیرا پسوند مسیر پراکسی دقیقاً با " /cat " مطابقت دارد. اگر پسوند /bat یا /dog یا هر چیز دیگری باشد اجرا نمی شود.

حال، بیایید با استفاده از کمیت "*" یک عبارت منظم ایجاد کنیم. این کمیت با صفر یا بیشتر از کاراکتر قبلی مطابقت دارد.

<Condition>(proxy.pathsuffix JavaRegex "/c*t")</Condition>

تماس API:

GET http://artomatic-test.apigee.net/matchtest/cat

آیا سیاست اجرا می شود؟ نه! کمیت "*" با صفر یا بیشتر از کاراکتر قبلی مطابقت دارد که یک " c " است.

تماس API:

GET http://artomatic-test.apigee.net/matchtest/ccccct

آیا سیاست اجرا می شود؟ بله، زیرا حروف عام با صفر یا بیشتر از کاراکتر قبلی مطابقت دارد.

در مرحله بعد، از کمیت " ? " استفاده می کنیم که یک بار یا اصلاً با کاراکتر قبلی مطابقت دارد.

<Condition>(proxy.pathsuffix JavaRegex "/ca?t")</Condition>

تماس API:

GET http://artomatic-test.apigee.net/matchtest/cat

آیا سیاست اجرا می شود؟ بله. کمیت " ? " با صفر یا یک نویسه قبلی مطابقت دارد که یک " a " است.

تماس API:

GET http://artomatic-test.apigee.net/matchtest/ct

آیا سیاست اجرا می شود؟ بله. کمیت " ? " با یک یا هیچ یک از نویسه های قبلی مطابقت دارد. در این مورد، هیچ کاراکتر "a" وجود ندارد، بنابراین شرط به درستی ارزیابی می شود.

تماس API:

GET http://artomatic-test.apigee.net/matchtest/caat

آیا سیاست اجرا می شود؟ نه. "؟" کمیت با یکی از کاراکترهای قبلی که " a " است مطابقت دارد.

در مرحله بعد، ما از سبک " [abc] " یا "گروه‌بندی" بیان regex استفاده می‌کنیم. با کاراکترهای " a " یا " b " یا " c " مطابقت دارد.

<Condition>(proxy.pathsuffix JavaRegex "/[cbr]at")</Condition>

تماس API:

GET http://artomatic-test.apigee.net/matchtest/cat

آیا سیاست اجرا می شود؟ بله. ما در اینجا از عبارات منظم استفاده می کنیم و عبارت " [cbr] " با "c"، "b"، یا "r" مطابقت دارد. این تماس ها نیز مطابقت دارند:

GET http://artomatic-test.apigee.net/matchtest/bat

GET http://artomatic-test.apigee.net/matchtest/rat

اما این یک مسابقه نیست:

GET http://artomatic-test.apigee.net/matchtest/mat

سوال: آیا عملگر JavaRegex به حروف کوچک و بزرگ حساس است؟

بله. فرض کنید شرایطی مانند این دارید:

<Condition>(proxy.pathsuffix JavaRegex "/ca?t")</Condition>

تماس API:

GET http://artomatic-test.apigee.net/matchtest/cat

آیا سیاست اجرا می شود؟ بله، regex با صفر یا یک کاراکتر قبلی که "a" است مطابقت دارد.

تماس API:

GET http://artomatic-test.apigee.net/matchtest/cAt

سوال: آیا سیاست اجرا می شود؟

خیر، زیرا بزرگ "A" با حروف کوچک "a" مطابقت ندارد.

MatchesPath

عملگر MatchesPath نیز می توان مانند این "~/" مشخص کرد. کمی شبیه عملگرهای Matches (~) و JavaRegex (~~) است. اما MatchesPath کاملاً متفاوت است.

فقط به یاد داشته باشید که این عملگر به یک مسیر به عنوان یک سری قطعات نگاه می کند. بنابراین، اگر مسیر: /animals/cats/wild باشد، می‌توانید مسیر را متشکل از بخش‌های " /animals "، " /cats " و " /wild " در نظر بگیرید.

عملگر MatchesPath به شما امکان می دهد از دو علامت عام استفاده کنید: یک ستاره (*) و یک ستاره دوتایی (**). ستاره منفرد با یک عنصر مسیر مطابقت دارد. ستاره دوتایی با یک یا چند عنصر مسیر مطابقت دارد.

بیایید به یک مثال نگاه کنیم. در این مثال، متغیر proxy.pathsuffix را آزمایش می‌کنیم، یک متغیر داخلی در Edge که پسوند مسیر درخواست را ذخیره می‌کند. توجه داشته باشید، با این حال، می توانید مقدار هر متغیر جریانی را که دارای یک رشته است، آزمایش کنید.

    <PreFlow name="PreFlow">
        <Request>
            <Step>
                <Condition>(proxy.pathsuffix MatchesPath "/animals/*")</Condition>
                <Name>SomePolicy</Name>
            </Step>
        </Request>
        <Response/>
    </PreFlow>

سوال: کدام پسوند مسیر پراکسی باعث اجرای SomePolicy می شود؟

تماس API:

GET http://artomatic-test.apigee.net/matchtest/animals

سوال: آیا سیاست اجرا می شود؟

خیر، زیرا شرط نیاز به عنصر مسیر دیگری بعد از " /animals " دارد، همانطور که توسط " /* " مشخص شده است.

تماس API:

GET http://artomatic-test.apigee.net/matchtest/animals /

آیا سیاست اجرا می شود؟ بله، مسیر دارای عنصر مسیر دیگری است (قسمت بعد از " /animals/ ")، اما فقط خالی است.

تماس API:

GET http://artomatic-test.apigee.net/matchtest/animals/cats

آیا سیاست اجرا می شود؟ بله، زیرا مسیر به وضوح دارای یک عنصر (" /cats ") است که بعد از " /animals " می آید.

تماس API:

GET http://artomatic-test.apigee.net/matchtest/animals/cats/wild

سوال: آیا سیاست اجرا می شود؟

خیر، زیرا ستاره تنها با یک عنصر مسیر مطابقت دارد و این API بیش از یک عنصر بعد از " /animals " دارد.

حالا بیایید از ستاره دوتایی استفاده کنیم:

    <PreFlow name="PreFlow">
        <Request>
            <Step>
                <Condition>(proxy.pathsuffix MatchesPath "/animals/**")</Condition>
                <Name>SomePolicy</Name>
            </Step>
        </Request>
        <Response/>
    </PreFlow>

سوال: کدام پسوند مسیر پراکسی باعث اجرای SomePolicy می شود؟

تماس API:

GET http://artomatic-test.apigee.net/matchtest/animals

آیا سیاست اجرا می شود؟ خیر، زیرا شرط حداقل به یک عنصر مسیر زیر نیاز دارد که توسط " /** " مشخص شده باشد.

تماس API:

GET http://artomatic-test.apigee.net/matchtest/animals /

آیا سیاست اجرا می شود؟

بله، مسیر دارای عنصر مسیر دیگری است (قسمت بعد از " /animals/ ")، اما فقط خالی است.

تماس API:

GET http://artomatic-test.apigee.net/matchtest/animals/cats

آیا سیاست اجرا می شود؟

بله، زیرا مسیر حداقل یک عنصر دارد که بعد از " /animals " می آید.

تماس API:

GET http://artomatic-test.apigee.net/matchtest/animals/cats/wild

آیا سیاست اجرا می شود؟

بله، زیرا مسیر بیش از یک عنصر دارد که بعد از " /animals " می آید.

اختلاط ستاره ها

می‌توانید از ترکیب‌های ستاره تک (*) و دوگانه (**) برای اصلاح بیشتر تطابق مسیر خود استفاده کنید.

    <PreFlow name="PreFlow">
        <Request>
            <Step>
                <Condition>(proxy.pathsuffix MatchesPath "/animals/*/wild/**")</Condition>
                <Name>SomePolicy</Name>
            </Step>
        </Request>
        <Response/>
    </PreFlow>

تماس API:

همه این تماس‌های API یک تطابق ایجاد می‌کنند:

GET http://artomatic-test.apigee.net/matchtest/animals/cats/wild/

و

GET http://artomatic-test.apigee.net/matchtest/animals/dogs/wild/austrailian

و

GET http://artomatic-test.apigee.net/matchtest/animals/birds/wild/american/finches

منابع API

خدمات RESTful مجموعه ای از منابع API هستند. یک منبع API یک قطعه مسیر URI است که نهادی را شناسایی می کند که توسعه دهندگان می توانند با فراخوانی API شما به آن دسترسی داشته باشند. به عنوان مثال، اگر سرویس شما گزارش های آب و هوا و پیش بینی های آب و هوا را ارائه می دهد، سرویس پشتیبان شما ممکن است دو منبع API را تعریف کند:

  • http://mygreatweatherforecast.com /reports
  • http://mygreatweatherforecast.com /forecasts

هنگامی که یک پراکسی API ایجاد می کنید (همانطور که در ساخت اولین پروکسی API خود نشان داده شده است)، حداقل یک URL پایه نام مستعار ایجاد می کنید که به سرویس باطن شما نگاشت می شود. به عنوان مثال:

URL پایه Backend URL پروکسی API جدید/معادل
http://mygreatweatherforecast.com http://{your_org}-{environment}.apigee.net/mygreatweatherforecast

در این مرحله می‌توانید با استفاده از هر یک از URLهای پایه، با پشتیبان خود تماس‌های API برقرار کنید. اما وقتی از URL پروکسی API استفاده می کنید، چیزها شروع به جالب شدن می کنند.

علاوه بر تجزیه و تحلیل API که Edge هنگام استفاده از پراکسی API شروع به جمع‌آوری می‌کند، پراکسی‌ها همچنین به شما امکان می‌دهند جریان‌های شرطی را تعریف کنید که به منابع موجود در باطن شما نگاشت می‌شوند. در اصل، "اگر یک تماس GET به منبع /reports وارد شود، Edge باید کاری انجام دهد."

تصویر زیر تفاوت رفتار بین دو URL را نشان می دهد که در نهایت به یک Backend دسترسی دارند. یکی URL منبع بدون پروکسی است، دیگری یک پروکسی Edge API با یک جریان مشروط به همان منبع باطن است. در زیر جریانهای مشروط را با جزئیات بیشتری شرح خواهیم داد.

چگونه پراکسی های API به منابع باطن خاص نگاشت می شوند

با یک URL پروکسی API که به URL اصلی سرویس پشتیبان نگاشت شده است (هنگامی که پروکسی را ایجاد می کنید)، می توانید جریان های مشروط را به منابع خاصی اضافه کنید، مانند منابع /reports و /forecasts که قبلا ذکر شد.

فرض کنید می‌خواهید زمانی که تماس‌ها به منابع /reports یا /forecasts می‌آیند، Edge "کاری انجام دهد". در این مرحله شما به Edge نمی‌گویید که چه کاری انجام دهد، فقط باید به تماس‌های آن منابع گوش دهد. شما این کار را با شرایط انجام می دهید. در پروکسی Edge API خود، می‌توانید جریان‌های شرطی برای /reports و /forecasts ایجاد کنید. برای اهداف مفهومی، پروکسی API XML زیر نشان می‌دهد که این شرایط چگونه ممکن است به نظر برسند.

<Flows>
    <Flow name="reports">
        <Description/>
        <Request/>
        <Response/>
        <Condition>(proxy.pathsuffix MatchesPath "/reports") and (request.verb = "GET")</Condition>
    </Flow>
    <Flow name="forecasts">
        <Description/>
        <Request/>
        <Response/>
        <Condition>(proxy.pathsuffix MatchesPath "/forecasts") and (request.verb = "GET")</Condition>
    </Flow>
</Flows>

این شرایط می‌گوید: «وقتی درخواست GET با /reports و /forecasts در URL وارد می‌شود، Edge هر کاری را که شما (توسعه‌دهنده API) به آن بگویید، از طریق خط‌مشی‌هایی که به آن جریان‌ها متصل می‌کنید، انجام می‌دهد.

حالا در اینجا مثالی است که به Edge می گوییم در صورت تحقق یک شرط چه کاری انجام دهد. در XML پروکسی API زیر، وقتی یک درخواست GET به https://yourorg-test.apigee.net/mygreatweatherforecast/reports ارسال می شود، Edge خط مشی "XML-to-JSON-1" را در پاسخ اجرا می کند.

<Flows>
    <Flow name="reports">
        <Description/>
        <Request/>
        <Response>
            <Step>
                <Name>XML-to-JSON-1</Name>
            </Step>
        </Response>
        <Condition>(proxy.pathsuffix MatchesPath "/reports") and (request.verb = "GET")</Condition>
</Flow>

علاوه بر آن جریان‌های شرطی اختیاری، هر پروکسی API نیز دارای دو جریان پیش‌فرض است: یک <PreFlow> که قبل از جریان‌های شرطی شما اجرا می‌شود، و یک <PostFlow> که پس از جریان‌های شرطی شما اجرا می‌شود. هنگامی که هر تماسی با یک پروکسی API برقرار می شود، این موارد برای اجرای خط مشی ها مفید هستند. برای مثال، اگر می‌خواهید کلید API برنامه‌ای را با هر تماس تأیید کنید، بدون توجه به منبع پشتیبان مورد دسترسی، می‌توانید یک خط‌مشی Verify API Key را در <PreFlow> قرار دهید. برای اطلاعات بیشتر در مورد جریان، به پیکربندی جریان ها مراجعه کنید.

جریان های مشروط را برای منابع پشتیبان ایجاد کنید

تعریف جریان های شرطی به منابع پشتیبان در یک پراکسی API کاملا اختیاری است. با این حال، آن جریان های مشروط به شما توانایی اعمال مدیریت و نظارت دقیق را می دهد.

شما قادر خواهید بود:

  • مدیریت را به گونه ای اعمال کنید که معنایی مدل API شما را منعکس کند
  • اعمال خط‌مشی‌ها و رفتار اسکریپت‌شده برای مسیرهای منابع فردی (URI)
  • معیارهای دقیق را برای سرویس های Analytics جمع آوری کنید

به عنوان مثال، تصور کنید که باید انواع مختلفی از منطق را در backend/developers خود در منابع /apps اعمال کنید.

برای انجام این کار، دو جریان مشروط را در پروکسی API خود اضافه می‌کنید: /developers و /apps .

در نمای توسعه از پنجره ناوبر ویرایشگر پروکسی API، روی نماد + در کنار پیش‌فرض در نقاط پایانی پروکسی کلیک کنید.

در پنجره "جریان مشروط جدید"، تنظیمات کلیدی زیر را وارد کنید:

  • نام جریان : توسعه دهندگان
  • نوع شرایط : مسیر
  • مسیر : / توسعه دهندگان

اگر تماسی به پروکسی با /developers در انتهای URI ارسال شود، این شرط فعال می‌شود (و خط‌مشی‌ها اجرا می‌شوند).

اکنون یک جریان شرطی برای /apps اضافه کنید، و فرض کنید می‌خواهید شرط در URI و فعل POST در یک درخواست فعال شود. پیکربندی شامل تنظیم موارد زیر است:

  • نام جریان : برنامه ها
  • نوع شرط : مسیر و فعل
  • مسیر : /apps
  • فعل : POST

اگر تماسی با /apps در انتهای URI و یک فعل POST به پروکسی ارسال شود، شرط فعال می‌شود (و خط‌مشی‌ها اجرا می‌شوند).

در قسمت Navigator، جریان‌های جدیدی را برای برنامه‌ها و توسعه‌دهندگان خواهید دید.

یکی از جریان ها را برای مشاهده پیکربندی جریان شرطی در نمای کد ویرایشگر پروکسی API انتخاب کنید:

<Flow name="Apps">
    <Description>Developer apps registered in Developer Services</Description>
    <Request/>
    <Response/>
    <Condition>(proxy.pathsuffix MatchesPath "/apps") and (request.verb = "POST")</Condition>
</Flow>

همانطور که می بینید، منابع API به سادگی جریان های شرطی هستند که مسیر URI درخواست ورودی را ارزیابی می کنند. (متغیر proxy.pathsuffix URI درخواستی را که از BasePath پیکربندی شده در پیکربندی ProxyEndpoint پیروی می کند، شناسایی می کند.)

هر منبع API که تعریف می کنید توسط یک Flow شرطی در پراکسی API پیاده سازی می شود. (به پیکربندی جریان ها مراجعه کنید.)

پس از استقرار پراکسی API در محیط آزمایشی، درخواست زیر را انجام دهید:

http://{org_name}-test.apigee.net/{proxy_path}/apps

باعث می شود شرط به درستی ارزیابی شود و این جریان به همراه هر خط مشی مرتبط اجرا می شود.

شرط مثال زیر از یک عبارت معمولی جاوا برای تشخیص تماس های برقرار شده با منبع /apps با یا بدون اسلش رو به جلو ( /apps یا /apps/** ) استفاده می کند:

<Condition>(proxy.pathsuffix JavaRegex "/apps(/?)") and (request.verb = "POST")</Condition>

برای اطلاعات بیشتر در مورد این نوع شرایط، به نحوه مطابقت بدون توجه به ... در انجمن Apigee مراجعه کنید.

مدلسازی URIهای سلسله مراتبی

در برخی موارد، منابع API سلسله مراتبی خواهید داشت. به عنوان مثال، Developer Services API روشی را برای فهرست کردن همه برنامه‌هایی که به یک توسعه‌دهنده تعلق دارند، ارائه می‌کند. مسیر URI:

/developers/{developer_email}/apps

ممکن است منابعی داشته باشید که در آنها یک شناسه منحصربه‌فرد برای هر موجودیت در یک مجموعه ایجاد می‌شود که گاهی اوقات به صورت زیر مشروح می‌شود:

/genus/:id/species

این مسیر به طور مساوی برای دو URI زیر اعمال می شود:

/genus/18904/species
/genus/17908/species

برای نشان دادن این ساختار در یک منبع API، می توانید از حروف عام استفاده کنید. به عنوان مثال:

/developers/*/apps
/developers/*example.com/apps
/genus/*/species

این URI های سلسله مراتبی را به عنوان منابع API به طور مناسب حل می کند.

در برخی موارد، به ویژه برای APIهای عمیقاً سلسله مراتبی، ممکن است بخواهید همه موارد زیر یک قطعه URI خاص را حل کنید. برای انجام این کار، از علامت علامت دو ستاره در تعریف منبع خود استفاده کنید. به عنوان مثال، اگر منبع API زیر را تعریف کنید:
/developers/**

آن منبع API مسیرهای URI زیر را حل می کند:

/developers/{developer_email}/apps
/developers/{developer_email}/keys
/developers/{developer_email}/apps/{app_id}/keys

در اینجا شرایط جریان شرطی در تعریف پراکسی API به نظر می رسد:

<Condition>(proxy.pathsuffix MatchesPath "/developers/**") and (request.verb = "POST")</Condition>

نمونه های بیشتر

شرایط متصل به RouteRule

<RouteRule name="default">
 <!--this routing executes if the header indicates that this is an XML call. If true, the call is routed to the endpoint XMLTargetEndpoint-->
  <Condition>request.header.content-type = "text/xml"</Condition>
  <TargetEndpoint>XmlTargetEndpoint</TargetEndpoint>
</RouteRule>

شرایط پیوست به یک سیاست

<Step>
<!--the policy MaintenancePolicy only executes if the response status code is exactly 503-->
  <Condition>response.status.code = 503</Condition>
  <Name>MaintenancePolicy</Name>
</Step>

جریان مشروط

<!-- this entire flow is executed only if the request verb is a GET-->
<Flow name="GetRequests">
  <Condition>request.verb="GET"</Condition>
  <Request>
    <Step>
<!-- this policy only executes if request path includes a term like statues-->
<Condition>request.path ~ "/statuses/**"</Condition>
      <Name>StatusesRequestPolicy</Name>
    </Step>
  </Request>
  <Response>
    <Step>
<!-- this condition has multiple expressions. The policy executes if the response code status is exactly 503 or 400-->
<Condition>(response.status.code = 503) or (response.status.code = 400)</Condition>
      <Name>MaintenancePolicy</Name>
    </Step>
  </Response>
</Flow>

نمونه عملگرها در شرایط

در اینجا چند نمونه از عملگرهای مورد استفاده برای ایجاد شرایط آورده شده است:

  • request.header.content-type = "text/xml"
  • request.header.content-length < 4096 && request.verb = "PUT"
  • response.status.code = 404 || response.status.code = 500
  • request.uri MatchesPath "/*/statuses/**"
  • request.queryparam.q0 NotEquals 10

یک مثال عملی: "/" را در انتهای مسیر نادیده بگیرید

توسعه دهندگان لبه معمولاً می خواهند هر دو پسوند مسیر را مدیریت کنند: " /cat " و " /cat/ ". این به این دلیل است که برخی از کاربران یا مشتریان ممکن است API شما را با اسلش اضافی در انتهای مسیر فراخوانی کنند و شما باید بتوانید آن را در دستورات شرطی خود مدیریت کنید. این مورد استفاده دقیق در انجمن Apigee مورد بحث قرار گرفته است .

اگر ترجیح می‌دهید، می‌توانید بدون استفاده از Regex به این هدف دست پیدا کنید:

    <PreFlow name="PreFlow">
        <Request>
            <Step>
                <Condition>((proxy.pathsuffix = "/cat") OR (proxy.pathsuffix = "/cat/")</Condition>
                <Name>SomePolicy</Name>
            </Step>
        </Request>
        <Response/>
    </PreFlow>

این گزینه خوبی است. واضح و خواندنی است.

شما می توانید همین کار را با Regex انجام دهید، اما به این صورت. از پرانتزها برای گروه بندی قسمت regex دستور استفاده می شود، اما نیازی به آنها نیست.

<Condition>(proxy.pathsuffix JavaRegex "/cat(/?)"</Condition>

تماس های API:

GET http://artomatic-test.apigee.net/matchtest/cat
or

GET http://artomatic-test.apigee.net/matchtest/cat /

آیا سیاست اجرا می شود؟ بله. توجه داشته باشید که در یک عبارت منظم، کاراکتر " ? " به این معنی است: مطابقت با صفر یا یکی از کاراکترهای قبلی. بنابراین، هر دو " /cat " و " /cat/ " مطابق هستند.

تماس API:

GET http://artomatic-test.apigee.net/matchtest/cat/spotted

آیا سیاست اجرا می شود؟ نه. عبارت منظم با صفر یا تنها یک مورد از کاراکتر قبلی مطابقت دارد و هیچ چیز دیگری مجاز نیست.

تطبیق رشته های دلخواه با JavaRegex

در تمام مثال‌های این مبحث، نحوه تطبیق یکی از متغیرهای جریان داخلی را نشان می‌دهیم: proxy.pathsuffix. خوب است بدانید که می‌توانید تطبیق الگو را روی هر رشته یا متغیر جریان دلخواه انجام دهید، خواه یک متغیر جریان داخلی مانند پسوند proxy.path باشد یا نباشد.

برای مثال، اگر شرطی دارید که یک رشته دلخواه را آزمایش می کند، شاید رشته ای که در یک بار پشتیبان بازگردانده شده است، یا رشته ای که از جستجوی سرور احراز هویت برگردانده شده است، می توانید از عملگرهای منطبق برای آزمایش آن استفاده کنید. اگر از JavaRegex استفاده می کنید، عبارت منظم با کل رشته موضوع مقایسه می شود. اگر موضوع "abc" و عبارت منظم "[az] باشد، مطابقت ندارد، زیرا "[az]" دقیقاً با یک کاراکتر آلفا مطابقت دارد. عبارت "[az]+" مانند "[az]*" و "[az]{3} کار می کند.

بیایید به یک مثال عینی نگاه کنیم. فرض کنید سرور احراز هویت فهرستی از نقش‌ها را به‌صورت رشته‌ای با کاما برمی‌گرداند: «ویرایشگر، نویسنده، مهمان».

برای آزمایش حضور نقش ویرایشگر، این ساختار کار نخواهد کرد، زیرا "ویرایشگر" تنها بخشی از کل رشته است.

<Condition>returned_roles ~~ "editor"</Condition>

با این حال، این ساخت و ساز کار خواهد کرد:

<Condition>returned_roles ~~ ".*\beditor\b.*")</Condition>

این کار به این دلیل کار می کند که شکست های کلمه و هر قسمت دیگر رشته را با پیشوند و پسوند .* در نظر می گیرد.

در این مثال، شما همچنین می توانید برای "ویرایشگر" با عملگر Matches تست کنید:

<Condition>returned_roles ~~ "*editor*")</Condition>

با این حال، در مواردی که به دقت بیشتری نیاز دارید، JavaRegex اغلب انتخاب بهتری است.

فرار از دو نقل قول در عبارات JavaRegex

دستور Condition به یک عبارت JavaRegex نیاز دارد که در دو گیومه پیچیده شود. بنابراین، اگر یک عبارت Regex دارید که شامل نقل قول‌های دوگانه است، به روشی جایگزین برای مطابقت با آنها نیاز دارید. پاسخ یونیکد است. به عنوان مثال، فرض کنید در یک هدر که شامل نقل قول های دوگانه است، عبور می کنید، مانند موارد زیر:
 -H 'content-type:multipart/related; type="application/xop+xml"'
اگر سعی کنید آن هدر را در یک شرط Regex مطابقت دهید، یک خطای Invalid Condition دریافت خواهید کرد زیرا عبارت شامل نقل قول های دوگانه است:
request.header.Content-Type ~~ "(multipart\/related)(; *type="application\/xop\+xml\")"
راه حل این است که به جای گیومه های دوگانه مبتنی بر ASCII با معادل یونیکد آنها، \u0022 . به عنوان مثال، عبارت زیر معتبر است و نتیجه مورد انتظار را ایجاد می کند:
request.header.Content-Type ~~ "(multipart\/related)(; *type=\u0022application\/xop\+xml\u0022)"