<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Yilia</title>
    <description>The latest articles on DEV Community by Yilia (@yilialinn).</description>
    <link>https://dev.to/yilialinn</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F972804%2Ff233b99c-5dfb-4559-912d-5fcd16340f87.jpg</url>
      <title>DEV Community: Yilia</title>
      <link>https://dev.to/yilialinn</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yilialinn"/>
    <language>en</language>
    <item>
      <title>TLS Key Exchange for API Gateway Origins: Cut Handshake Retries Safely</title>
      <dc:creator>Yilia</dc:creator>
      <pubDate>Thu, 29 Oct 2026 06:15:26 +0000</pubDate>
      <link>https://dev.to/yilialinn/tls-key-exchange-for-api-gateway-origins-cut-handshake-retries-safely-30dn</link>
      <guid>https://dev.to/yilialinn/tls-key-exchange-for-api-gateway-origins-cut-handshake-retries-safely-30dn</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Foljlc941clmt3a2upfx2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Foljlc941clmt3a2upfx2.png" alt="API7: Cut Origin TLS Retries" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By Yilia Lin. Originally published on &lt;a href="https://api7.ai/blog/tls-key-exchange-api-gateway-origins" rel="noopener noreferrer"&gt;API7.ai&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Disclosure: This syndicated edition was prepared with AI assistance.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;TLS latency is not only a client-to-edge concern. An API gateway also acts as a TLS client when it opens an HTTPS connection to an upstream service. If the gateway offers a key share that the origin cannot use, TLS 1.3 may require a &lt;code&gt;HelloRetryRequest&lt;/code&gt; and another network round trip before application data can flow.&lt;/p&gt;

&lt;p&gt;That detail became a developer-infrastructure topic in September 2026 after Cloudflare reported that its origin-facing Automatic Key Exchange rollout reduced &lt;code&gt;HelloRetryRequest&lt;/code&gt; rates from roughly 52% to 3.7% for a scanned cohort. The accompanying &lt;a href="https://news.ycombinator.com/item?id=49700255" rel="noopener noreferrer"&gt;Hacker News discussion&lt;/a&gt; focused on the practical result: better key-share selection can improve post-quantum adoption and remove avoidable connection latency.&lt;/p&gt;

&lt;p&gt;An API gateway team should not copy Cloudflare's system or production numbers into its own plan. It should copy the engineering question: how do we make gateway-to-origin TLS secure, compatible, observable, and cheap enough that handshakes do not become an invisible tax?&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Client-to-gateway and gateway-to-origin TLS are separate handshakes with separate certificates, protocol support, and failure modes.&lt;/li&gt;
&lt;li&gt;In TLS 1.3, an unsupported initial key share can trigger a &lt;code&gt;HelloRetryRequest&lt;/code&gt;, adding a round trip before the handshake completes.&lt;/li&gt;
&lt;li&gt;Post-quantum policy cannot create support on an origin; incompatible strict policy can make every connection fail.&lt;/li&gt;
&lt;li&gt;Connection reuse often matters more than micro-optimizing a single handshake, because reused keep-alive connections do not repeat it.&lt;/li&gt;
&lt;li&gt;Measure handshake outcomes by upstream and deployment version before changing algorithms or compliance policy.&lt;/li&gt;
&lt;li&gt;API7 Gateway and Apache APISIX can terminate TLS at the edge and establish protected upstream connections, but automatic origin capability probing should not be assumed unless the deployed product documents it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Understand the Two TLS Boundaries
&lt;/h2&gt;

&lt;p&gt;In a common reverse-proxy path, one request can cross two independent encrypted connections:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flm08dys3x5un3vujvieh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flm08dys3x5un3vujvieh.png" alt="Two separate TLS boundaries: API client → API gateway uses TLS connection 1; API gateway → origin service uses TLS connection 2." width="798" height="173"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the first connection, the gateway is the server. It selects a certificate based on SNI, negotiates a protocol and cipher suite, and may verify a client certificate. On the second, the gateway is the client. It sends the origin's hostname, offers supported algorithms, verifies the server according to configured policy, and may present its own certificate for upstream mTLS.&lt;/p&gt;

&lt;p&gt;These boundaries should be operated separately. Rotating the public certificate does not rotate an upstream client certificate. Enabling TLS 1.3 for incoming clients does not prove every upstream load balancer accepts the same key exchanges. A dashboard that combines both directions into one “TLS errors” counter hides which trust boundary failed.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://docs.api7.ai/api7-gateway/3.9.x/key-concepts/ssl-certificates" rel="noopener noreferrer"&gt;API7 Gateway SSL certificate guide&lt;/a&gt; explains edge termination and upstream re-encryption. The &lt;a href="https://docs.api7.ai/api7-gateway/3.9.x/security-and-compliance/authenticate/upstream-mtls" rel="noopener noreferrer"&gt;upstream mTLS guide&lt;/a&gt; covers the gateway's client certificate and upstream certificate verification. Apache APISIX also documents its &lt;a href="https://apisix.apache.org/docs/apisix/ssl-protocol/" rel="noopener noreferrer"&gt;TLS protocol configuration&lt;/a&gt; and upstream TLS fields.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why &lt;code&gt;HelloRetryRequest&lt;/code&gt; Changes Latency
&lt;/h2&gt;

&lt;p&gt;TLS 1.3 normally completes a full handshake in one round trip. The client includes a key share in &lt;code&gt;ClientHello&lt;/code&gt; so the server can immediately continue with a compatible choice. If the server supports another offered group but not the supplied key share, it can return &lt;code&gt;HelloRetryRequest&lt;/code&gt; and ask for a new one. The client sends another &lt;code&gt;ClientHello&lt;/code&gt;, adding a network round trip.&lt;/p&gt;

&lt;p&gt;This mechanism is part of &lt;a href="https://www.rfc-editor.org/rfc/rfc8446" rel="noopener noreferrer"&gt;RFC 8446&lt;/a&gt;. It preserves interoperability, but it is not free. The extra delay is especially visible when the gateway and origin are in different regions, a cache miss opens a new connection, or a burst exceeds the existing connection pool.&lt;/p&gt;

&lt;p&gt;Cloudflare's &lt;a href="https://blog.cloudflare.com/automatic-key-exchange-for-origins/" rel="noopener noreferrer"&gt;Automatic Key Exchange report&lt;/a&gt; describes an out-of-band scanner that learns an origin's supported preference before leading with a key share. For its scanned origins, avoiding the retry reduced p90 handshake latency by more than 150 ms. That is evidence for Cloudflare's topology, not a universal benchmark. A private gateway in the same Kubernetes cluster may have sub-millisecond network latency; a hybrid-cloud origin can have a far larger round trip.&lt;/p&gt;

&lt;h2&gt;
  
  
  Post-Quantum Readiness Is a Compatibility Program
&lt;/h2&gt;

&lt;p&gt;The post-quantum part of this story matters because Cloudflare's preferred &lt;code&gt;X25519MLKEM768&lt;/code&gt; group combines X25519 with ML-KEM-768. NIST's &lt;a href="https://csrc.nist.gov/pubs/fips/203/final" rel="noopener noreferrer"&gt;FIPS 203&lt;/a&gt; standardizes ML-KEM, including ML-KEM-768. &lt;a href="https://datatracker.ietf.org/doc/html/rfc10024" rel="noopener noreferrer"&gt;RFC 10024&lt;/a&gt; also standardizes hybrid groups based on P-256 and P-384, so gateway teams should inventory the exact groups supported by each TLS stack. A hybrid TLS group can protect against “harvest now, decrypt later” risk while retaining a classical component.&lt;/p&gt;

&lt;p&gt;Yet a policy switch cannot upgrade an origin. The gateway's TLS library, origin server, load balancer, service mesh, firewall, and any middlebox on the path must handle the larger &lt;code&gt;ClientHello&lt;/code&gt; and the selected group correctly. If policy permits only a hybrid group and the origin does not support it, there is no mutually acceptable key exchange and the connection fails.&lt;/p&gt;

&lt;p&gt;Treat rollout as capability discovery plus controlled enforcement:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Inventory TLS libraries and termination points on both sides.&lt;/li&gt;
&lt;li&gt;Test a representative origin from the actual gateway network path.&lt;/li&gt;
&lt;li&gt;Record negotiated protocol, group, handshake duration, retries, and failures.&lt;/li&gt;
&lt;li&gt;Enable compatible preferences in a small canary pool.&lt;/li&gt;
&lt;li&gt;Keep a rollback path to the last approved classical policy.&lt;/li&gt;
&lt;li&gt;Enforce a strict post-quantum-only requirement only where policy and origin capability both demand it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Do not label an entire API “post-quantum protected” after testing only client-to-gateway TLS. If the requirement covers data to the origin, verify the second connection too.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connection Reuse Is the First Performance Control
&lt;/h2&gt;

&lt;p&gt;The fastest handshake is the one the gateway does not repeat. A keep-alive pool lets many requests reuse an established upstream connection, subject to protocol, concurrency, idle timeout, and maximum-request settings. Cloudflare explicitly notes that requests on existing keep-alive connections were unaffected by its handshake optimization.&lt;/p&gt;

&lt;p&gt;This changes the order of operations for API gateway teams:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;verify that upstream connection reuse is actually occurring;&lt;/li&gt;
&lt;li&gt;align idle timeouts across gateway, load balancer, and origin;&lt;/li&gt;
&lt;li&gt;avoid connection churn during deployments and endpoint updates;&lt;/li&gt;
&lt;li&gt;separate new-connection latency from total upstream response latency;&lt;/li&gt;
&lt;li&gt;then optimize key-share selection for the connections that remain.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Apache APISIX upstream resources expose a configurable &lt;code&gt;keepalive_pool&lt;/code&gt;, along with connection, send, and read timeouts. Those controls are described in the &lt;a href="https://apisix.apache.org/docs/apisix/admin-api/" rel="noopener noreferrer"&gt;APISIX Admin API reference&lt;/a&gt;. They do not remove the need to observe whether an upstream or network appliance closes connections earlier than expected.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build an Origin TLS Dashboard
&lt;/h2&gt;

&lt;p&gt;A useful dashboard groups measurements by upstream service, region, gateway version, and TLS policy. Avoid high-cardinality labels such as raw client IDs or request paths.&lt;/p&gt;

&lt;p&gt;Track at least:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;new upstream TLS connections per second;&lt;/li&gt;
&lt;li&gt;handshake success and failure counts;&lt;/li&gt;
&lt;li&gt;handshake duration percentiles;&lt;/li&gt;
&lt;li&gt;negotiated TLS version and key-exchange group where available;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;HelloRetryRequest&lt;/code&gt; or retry indicators where the TLS stack exposes them;&lt;/li&gt;
&lt;li&gt;connection reuse ratio and pool misses;&lt;/li&gt;
&lt;li&gt;certificate validation, SNI, and mTLS errors;&lt;/li&gt;
&lt;li&gt;end-to-end upstream latency for reused versus new connections.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A spike in handshake failures after an origin deployment suggests compatibility. A normal handshake rate with worsening application latency points elsewhere. A rising new-connection rate with stable traffic suggests pool churn rather than cryptography.&lt;/p&gt;

&lt;p&gt;The gateway's request metrics still matter. API7.ai's &lt;a href="https://api7.ai/blog/api-observability-guide" rel="noopener noreferrer"&gt;API observability guide&lt;/a&gt; shows how metrics, logs, traces, and SLOs complement one another. Correlate an affected request with gateway error logs and origin deployment events; do not place sensitive certificate material or keys into telemetry.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Safe Rollout Checklist
&lt;/h2&gt;

&lt;p&gt;Before changing gateway-to-origin TLS policy, confirm:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;every origin hostname and SNI is explicit;&lt;/li&gt;
&lt;li&gt;server-certificate verification and trusted CAs match the environment;&lt;/li&gt;
&lt;li&gt;upstream client certificates are scoped and rotated independently;&lt;/li&gt;
&lt;li&gt;TLS 1.3 support is verified on the real path, not inferred from a version string;&lt;/li&gt;
&lt;li&gt;allowed key exchanges meet policy without excluding required origins;&lt;/li&gt;
&lt;li&gt;keep-alive reuse is measured and timeout settings agree;&lt;/li&gt;
&lt;li&gt;canaries include long-distance, legacy, and multi-origin paths;&lt;/li&gt;
&lt;li&gt;dashboards separate handshake failures from HTTP errors;&lt;/li&gt;
&lt;li&gt;rollback does not require distributing new client configuration.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Cloudflare's result makes an obscure handshake message operationally concrete: a wrong initial guess can cost a round trip at enormous scale. For most API gateway deployments, the lesson is not to build a global origin scanner. It is to treat upstream TLS as a measurable connection system rather than a certificate checkbox.&lt;/p&gt;

&lt;p&gt;Start with correct trust and SNI, maximize safe connection reuse, measure negotiation by origin, and introduce post-quantum policy through compatibility-tested canaries. Explore &lt;a href="https://api7.ai/enterprise" rel="noopener noreferrer"&gt;API7 Gateway&lt;/a&gt; when you need a governed place to manage client-facing and upstream API traffic while keeping their TLS responsibilities explicit.&lt;/p&gt;




&lt;p&gt;Originally published at &lt;a href="https://api7.ai/blog/tls-key-exchange-api-gateway-origins" rel="noopener noreferrer"&gt;API7.ai&lt;/a&gt; by Yilia Lin.&lt;/p&gt;

</description>
      <category>api</category>
      <category>security</category>
      <category>performance</category>
    </item>
    <item>
      <title>HTTP Connection Reuse: The Hidden API Latency Multiplier</title>
      <dc:creator>Yilia</dc:creator>
      <pubDate>Thu, 22 Oct 2026 09:57:22 +0000</pubDate>
      <link>https://dev.to/yilialinn/http-connection-reuse-the-hidden-api-latency-multiplier-2le5</link>
      <guid>https://dev.to/yilialinn/http-connection-reuse-the-hidden-api-latency-multiplier-2le5</guid>
      <description>&lt;p&gt;&lt;em&gt;By Yilia Lin. Originally published on &lt;a href="https://api7.ai/blog/http-connection-reuse-api-gateway-latency" rel="noopener noreferrer"&gt;API7.ai&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Disclosure: This syndicated edition was prepared with AI assistance.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;An API can be fast at the origin and still feel slow because a client repeatedly pays to establish TCP and TLS connections. That cost is easy to miss: application traces show a short handler, the gateway reports healthy backends, and no single request looks broken. The lost time sits between requests, where a reusable connection should have been.&lt;/p&gt;

&lt;p&gt;Go made this failure mode unusually visible in October 2026. Its engineering team explained how &lt;a href="https://go.dev/blog/http-connection-reuse" rel="noopener noreferrer"&gt;Go 1.27 improves HTTP/1 connection reuse&lt;/a&gt; when a caller closes a response without reading its body to the end. In the post's local example, 100 sequential requests fell from about 710 milliseconds to about 150 milliseconds. That is an illustration from one machine and workload, not a general five-times performance promise.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://news.ycombinator.com/item?id=50090369" rel="noopener noreferrer"&gt;Hacker News discussion&lt;/a&gt; focused on the runtime fix, but the operational lesson is larger. API teams need to know which hop owns each connection, why reuse was lost, and whether a proposed fix trades handshake cost for extra body reads, idle sockets, or retry risk.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Draw the full path: client → API gateway → origin. Each hop has its own protocol, pool, limits, and failure modes.&lt;/li&gt;
&lt;li&gt;A successful HTTP response does not prove that its connection returned to the reusable pool.&lt;/li&gt;
&lt;li&gt;Go 1.27's automatic drain is bounded to 50 milliseconds or 256 KiB and applies to unread HTTP/1 response bodies.&lt;/li&gt;
&lt;li&gt;HTTP/2 multiplexing changes the mechanics; do not copy an HTTP/1 body-drain workaround into every protocol.&lt;/li&gt;
&lt;li&gt;Measure handshake rate, connection churn, request latency, and origin latency together before changing pool sizes.&lt;/li&gt;
&lt;li&gt;Treat gateway keep-alive tuning and client-library behavior as related evidence, not interchangeable fixes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why an Unread Body Can Discard a Healthy Connection
&lt;/h2&gt;

&lt;p&gt;HTTP/1 responses share a byte stream. Before a client can parse the next response on the same connection, it must know where the current response ends. &lt;code&gt;Content-Length&lt;/code&gt;, chunked transfer framing, or connection closure supplies that boundary, but the client still has to consume the framed body.&lt;/p&gt;

&lt;p&gt;Through Go 1.26, closing &lt;code&gt;resp.Body&lt;/code&gt; with unread bytes generally prevented &lt;code&gt;net/http.Transport&lt;/code&gt; from reusing that connection. A program that wanted only a status code could therefore open another connection for its next request. Even JSON decoding could leave one trailing newline unread after the decoder found the closing object delimiter.&lt;/p&gt;

&lt;p&gt;Starting in Go 1.27, &lt;code&gt;Transport&lt;/code&gt; asynchronously drains an unread HTTP/1 response body for up to 50 milliseconds or 256 KiB, according to the &lt;a href="https://go.dev/doc/go1.27#net/http" rel="noopener noreferrer"&gt;Go 1.27 release notes&lt;/a&gt;. It skips work when reuse cannot help, such as a response with &lt;code&gt;Connection: close&lt;/code&gt;. The bounds matter: downloading an unlimited or slow body merely to save a socket could cost more than establishing another connection.&lt;/p&gt;

&lt;p&gt;This behavior does not make body ownership optional. Applications still need to close bodies, stream large responses deliberately, and set request deadlines. It also does not change an API gateway written on another network stack. It removes one sharp edge in one Go client path.&lt;/p&gt;

&lt;h2&gt;
  
  
  Map the Two Connection Pools
&lt;/h2&gt;

&lt;p&gt;Teams often say “the gateway connection” as if there were one socket. A reverse proxy terminates one downstream connection and opens or reuses a separate upstream connection.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwnkbkeavyzners4oank3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwnkbkeavyzners4oank3.png" alt="Two separate connection pools: API client to API gateway to API origin; the gateway also produces latency and status evidence." width="800" height="280"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The two hops can use different protocols. A client may speak HTTP/2 to the gateway while the gateway uses HTTP/1.1 to an origin. A mobile client may create a new downstream connection on every network transition while the gateway maintains a warm upstream pool. Conversely, downstream reuse can look healthy while an origin sends &lt;code&gt;Connection: close&lt;/code&gt; or a gateway pool is undersized.&lt;/p&gt;

&lt;p&gt;Ask four questions for each hop:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Question&lt;/th&gt;
&lt;th&gt;Client → gateway&lt;/th&gt;
&lt;th&gt;Gateway → origin&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Which protocol is negotiated?&lt;/td&gt;
&lt;td&gt;HTTP/1.1, HTTP/2, or HTTP/3&lt;/td&gt;
&lt;td&gt;Depends on gateway and upstream configuration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Who owns the pool?&lt;/td&gt;
&lt;td&gt;Client library, SDK, browser, or sidecar&lt;/td&gt;
&lt;td&gt;Gateway worker and upstream configuration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;What prevents reuse?&lt;/td&gt;
&lt;td&gt;Unread body, close header, timeout, network change&lt;/td&gt;
&lt;td&gt;Close header, pool pressure, idle expiry, origin behavior&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Which evidence exists?&lt;/td&gt;
&lt;td&gt;Client trace, DNS/TCP/TLS timings&lt;/td&gt;
&lt;td&gt;Gateway latency, origin logs, socket and handshake telemetry&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This map prevents a common mistake: changing an upstream gateway pool to fix a downstream mobile-client problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Diagnose Churn Before Tuning Keep-Alive
&lt;/h2&gt;

&lt;p&gt;Start with a controlled comparison, not a production-wide configuration change.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Choose one route and one client version.&lt;/strong&gt; Mixes of SDKs and protocols blur the result.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Record total and origin latency.&lt;/strong&gt; Apache APISIX's &lt;a href="https://apisix.apache.org/docs/apisix/plugins/prometheus/" rel="noopener noreferrer"&gt;Prometheus plugin&lt;/a&gt; exposes request, upstream, and gateway-side latency views. Those signals do not identify every handshake by themselves, but their divergence helps locate the slow hop.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Count new connections and handshakes.&lt;/strong&gt; Use client tracing, origin server metrics, load-balancer logs, or a bounded packet capture in a test environment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check response framing and completion.&lt;/strong&gt; Look for unread bodies, early cancellation, streaming responses, &lt;code&gt;Connection: close&lt;/code&gt;, and timeouts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Repeat with connection reuse disabled.&lt;/strong&gt; If latency barely changes, the suspected pool may not be the bottleneck. If it changes sharply, confirm why before increasing limits.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Correlate the result with the broader &lt;a href="https://api7.ai/blog/api-observability-guide" rel="noopener noreferrer"&gt;API observability signals&lt;/a&gt; for errors, saturation, and route-level latency. A lower handshake count is useful only if tail latency, error rate, memory, and file-descriptor pressure remain acceptable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configure the Gateway Side Deliberately
&lt;/h2&gt;

&lt;p&gt;Apache APISIX lets an Upstream use a separate keep-alive pool. The current &lt;a href="https://apisix.apache.org/docs/apisix/admin-api/#upstream" rel="noopener noreferrer"&gt;APISIX Admin API documentation&lt;/a&gt; exposes pool size, idle timeout, and requests-per-connection controls. This article references the APISIX 3.19 documentation available on October 20, 2026; verify fields and defaults against the version you deploy.&lt;/p&gt;

&lt;p&gt;There is no universal correct pool size. A larger pool can reduce connection creation, but it also retains more idle sockets per worker and per upstream. Long idle timeouts may preserve warm connections while increasing the chance that an intermediary or origin has already discarded them. A high requests-per-connection value reduces churn but may conflict with an origin's lifecycle policy.&lt;/p&gt;

&lt;p&gt;Tune from the path's capacity model:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;gateway workers × upstreams × idle connections per pool;&lt;/li&gt;
&lt;li&gt;expected concurrency and request duration;&lt;/li&gt;
&lt;li&gt;TLS handshake cost and network round-trip time;&lt;/li&gt;
&lt;li&gt;origin limits, load-balancer idle timeout, and deployment churn;&lt;/li&gt;
&lt;li&gt;long-lived streams versus short request-response traffic.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Keep retries separate from reuse. Retrying an idempotent request after a stale pooled connection fails may be safe under a defined policy. Retrying a payment or another non-idempotent write can duplicate a side effect. Connection tuning must not quietly broaden retry semantics.&lt;/p&gt;

&lt;h2&gt;
  
  
  Design API Responses for Predictable Consumption
&lt;/h2&gt;

&lt;p&gt;Clients and gateways cannot optimize around an API contract that sends unnecessary or unbounded response bodies.&lt;/p&gt;

&lt;p&gt;For status-oriented operations, return the smallest representation that still communicates the result. A &lt;code&gt;204 No Content&lt;/code&gt; response may fit an operation with no representation, while a structured error body is valuable when a call fails. Do not remove useful diagnostics merely to save a connection; make success and error shapes intentional.&lt;/p&gt;

&lt;p&gt;For large exports and streams, document whether callers may stop early, whether byte ranges or pagination exist, and how cancellation reaches the origin. For ordinary JSON APIs, keep framing correct and avoid middleware that appends unexpected bytes. Test with the actual SDKs your consumers use.&lt;/p&gt;

&lt;p&gt;The same principle appears in &lt;a href="https://api7.ai/blog/tls-key-exchange-api-gateway-origins" rel="noopener noreferrer"&gt;TLS key exchange planning for API gateway origins&lt;/a&gt;: handshake choices, connection lifetime, and compatibility belong to one measured path. Optimizing one component without the path model can move cost rather than remove it.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Safe Rollout Checklist
&lt;/h2&gt;

&lt;p&gt;Before changing client or gateway behavior, capture a baseline and a rollback trigger:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;protocol on both sides of the gateway;&lt;/li&gt;
&lt;li&gt;new connections and TLS handshakes per request;&lt;/li&gt;
&lt;li&gt;total, upstream, and gateway-attributed latency percentiles;&lt;/li&gt;
&lt;li&gt;client cancellations, resets, and timeout errors;&lt;/li&gt;
&lt;li&gt;gateway and origin socket counts;&lt;/li&gt;
&lt;li&gt;response-body size distribution;&lt;/li&gt;
&lt;li&gt;retry count and method distribution;&lt;/li&gt;
&lt;li&gt;memory and file-descriptor headroom.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Upgrade one client cohort or adjust one Upstream at a time. Confirm that fewer handshakes correspond to better tail latency without increasing stale-connection errors or resource pressure. For Go applications, test on Go 1.27 with the real response sizes and cancellation patterns; do not infer production gains from the blog's small sequential benchmark.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Connection reuse is a path property, not a switch labeled “keep-alive.” Go 1.27 fixes a specific HTTP/1 client sharp edge, but API teams still need to distinguish downstream from upstream pools, protocol behavior from configuration, and lower handshake counts from actual user value.&lt;/p&gt;

&lt;p&gt;Use an API gateway as the observable boundary: compare end-to-end and upstream latency, keep pool settings explicit, and roll changes out by route and client cohort. If you operate Apache APISIX or API7 Gateway, start with one high-volume API, draw both connection hops, and test the smallest change that explains the evidence.&lt;/p&gt;




&lt;p&gt;Originally published at &lt;a href="https://api7.ai/blog/http-connection-reuse-api-gateway-latency" rel="noopener noreferrer"&gt;API7.ai&lt;/a&gt; by Yilia Lin.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>api</category>
      <category>performance</category>
      <category>go</category>
    </item>
    <item>
      <title>Bot Traffic Moves: Build API Defenses That Follow Behavior</title>
      <dc:creator>Yilia</dc:creator>
      <pubDate>Wed, 21 Oct 2026 09:11:00 +0000</pubDate>
      <link>https://dev.to/yilialinn/bot-traffic-moves-build-api-defenses-that-follow-behavior-38h3</link>
      <guid>https://dev.to/yilialinn/bot-traffic-moves-build-api-defenses-that-follow-behavior-38h3</guid>
      <description>&lt;p&gt;Blocking one source network can make a dashboard look safer while the automation simply moves. The operator changes cloud providers, the source IPs and autonomous system number (ASN) change, and the same request sequence resumes against the same API paths.&lt;/p&gt;

&lt;p&gt;That pattern became visible in an October 2026 &lt;a href="https://blog.cloudflare.com/yandex-outage/" rel="noopener noreferrer"&gt;Cloudflare analysis of the Yandex network disruption&lt;/a&gt;. Cloudflare observed one targeted customer's matching bot traffic disappear from Yandex.Cloud and appear from other Russian hosting ASNs with the same JA4 TLS fingerprint, uncommon paths and headers, and custom user-agent strings. Across the described week, the relevant Russian bot traffic for that account remained roughly flat. This is one network's observation of specific traffic; it does not identify the operator or prove that every bot migrates.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://news.ycombinator.com/item?id=50094673" rel="noopener noreferrer"&gt;Hacker News discussion&lt;/a&gt; made the operational question timely: if hostile or unwanted automation can change infrastructure faster than a blocklist review, which controls should remain effective after the move?&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use source IP and ASN as signals, not as durable identities.&lt;/li&gt;
&lt;li&gt;Authenticate valuable API operations and rate-limit by a trustworthy consumer or tenant identity where possible.&lt;/li&gt;
&lt;li&gt;Combine identity, route, method, request cost, concurrency, and behavior; no single fingerprint is permanent.&lt;/li&gt;
&lt;li&gt;Keep global abuse controls separate from per-replica counters and document degradation behavior.&lt;/li&gt;
&lt;li&gt;Measure allowed, challenged, rate-limited, and blocked traffic by policy reason, not only by source network.&lt;/li&gt;
&lt;li&gt;A gateway can enforce API policy, but upstream DDoS absorption, device reputation, and application fraud controls remain separate layers.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What the Yandex Event Actually Showed
&lt;/h2&gt;

&lt;p&gt;Cloudflare separated two Yandex networks with different traffic profiles. The Yandex Search ASN primarily carried verified search crawlers. Yandex.Cloud carried third-party workloads and a different mix of automation. During the disruption, requests from both networks fell, but their meaning was not the same.&lt;/p&gt;

&lt;p&gt;For one gambling customer, Cloudflare saw identical request behavior move from Yandex.Cloud to Radist and Selectel. The evidence was not merely “traffic increased elsewhere.” It included the same TLS client fingerprint, unusual paths and headers, and custom user-agent strings. That correlation made workload migration a stronger explanation than unrelated traffic.&lt;/p&gt;

&lt;p&gt;Two cautions belong next to that conclusion:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A source network does not prove who operates a request. Cloud platforms host many unrelated tenants.&lt;/li&gt;
&lt;li&gt;A fingerprint describes observed behavior at a point in time. A capable client can change its TLS stack, headers, timing, and hosting provider.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;An API defense should therefore use source attributes as part of a decision, not equate them with identity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build Controls That Survive an IP Change
&lt;/h2&gt;

&lt;p&gt;The most durable control is a principal or credential the API can validate and bind to a consumer or tenant. For an authenticated API, that may be a validated access token, service identity, consumer credential, or tenant key. Rate limits and authorization can then follow the caller across networks.&lt;/p&gt;

&lt;p&gt;That identity is only as strong as its verification and lifecycle. A raw header such as &lt;code&gt;X-Tenant-ID&lt;/code&gt; is caller-controlled unless a trusted authentication layer binds it to a verified principal. A leaked API key lets automation carry the same identity to a new provider. Pair the identifier with expiration, rotation, revocation, scope, and anomaly detection.&lt;/p&gt;

&lt;p&gt;For public or anonymous endpoints, combine weaker signals:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Signal&lt;/th&gt;
&lt;th&gt;Useful for&lt;/th&gt;
&lt;th&gt;Limitation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Source IP or ASN&lt;/td&gt;
&lt;td&gt;Burst control and emergency containment&lt;/td&gt;
&lt;td&gt;Shared, rotating, proxied, or easy to move&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Authenticated consumer&lt;/td&gt;
&lt;td&gt;Quotas and attribution&lt;/td&gt;
&lt;td&gt;Credential theft or sharing changes the actor behind it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Route and method&lt;/td&gt;
&lt;td&gt;Protecting expensive operations&lt;/td&gt;
&lt;td&gt;Does not distinguish callers on the same operation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Request shape&lt;/td&gt;
&lt;td&gt;Detecting scanners and repeated abuse sequences&lt;/td&gt;
&lt;td&gt;Legitimate clients can share shapes; bots can mutate them&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TLS or client fingerprint&lt;/td&gt;
&lt;td&gt;Correlating toolchains across networks&lt;/td&gt;
&lt;td&gt;Can change and may group unrelated clients&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Concurrency and cost&lt;/td&gt;
&lt;td&gt;Protecting capacity&lt;/td&gt;
&lt;td&gt;Needs a defensible cost model and safe thresholds&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The goal is not a magical bot score. It is a policy whose important limits still hold when one signal changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rate-Limit by the Resource You Need to Protect
&lt;/h2&gt;

&lt;p&gt;A request-per-second limit is useful when request cost is reasonably uniform. Many APIs are not uniform. A cached &lt;code&gt;GET&lt;/code&gt; and a report export may consume very different database, CPU, and bandwidth capacity. Login attempts, search queries, uploads, and bulk writes also need different windows and keys.&lt;/p&gt;

&lt;p&gt;Design limits around the protected resource:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;per verified consumer for contractual quotas;&lt;/li&gt;
&lt;li&gt;per tenant and route for shared-credential applications;&lt;/li&gt;
&lt;li&gt;per IP for unauthenticated bursts, with proxy trust configured correctly;&lt;/li&gt;
&lt;li&gt;per operation for expensive endpoints;&lt;/li&gt;
&lt;li&gt;concurrency limits for long-running requests;&lt;/li&gt;
&lt;li&gt;a global safety ceiling for origin capacity.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Apache APISIX provides request-rate, count, and concurrency controls. Its current &lt;a href="https://apisix.apache.org/docs/apisix/plugins/limit-count/" rel="noopener noreferrer"&gt;&lt;code&gt;limit-count&lt;/code&gt; documentation&lt;/a&gt; supports variable and variable-combination keys. This article references Apache APISIX 3.19 documentation available on October 20, 2026; confirm behavior in your deployed release.&lt;/p&gt;

&lt;p&gt;Do not compose a limit key from an unverified header and call it tenant-aware. Authenticate first, or explicitly treat the value as a weak partition that an attacker can change.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understand Local and Shared Counter Boundaries
&lt;/h2&gt;

&lt;p&gt;Distributed gateways introduce another scope problem. With the default local policy documented for APISIX &lt;code&gt;limit-count&lt;/code&gt;, each gateway instance maintains its own counters. If traffic reaches several instances, the effective aggregate allowance is approximately the configured limit multiplied by the number of instances.&lt;/p&gt;

&lt;p&gt;That may be acceptable for coarse load shedding. It is usually wrong for a contractual tenant quota that must apply across the fleet. APISIX also documents Redis-backed policies for shared counters. The trade-off is a runtime dependency: latency, availability, synchronization, and failure behavior now affect enforcement.&lt;/p&gt;

&lt;p&gt;Write the intended semantics next to the configuration:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is the limit per instance or fleet-wide?&lt;/li&gt;
&lt;li&gt;What happens when the shared counter store is slow or unavailable?&lt;/li&gt;
&lt;li&gt;Is temporary over-admission acceptable?&lt;/li&gt;
&lt;li&gt;Which status and &lt;code&gt;Retry-After&lt;/code&gt; behavior does the client receive?&lt;/li&gt;
&lt;li&gt;Can an operator disable or bypass the rule, and is that action audited?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The HTTP specification defines &lt;a href="https://www.rfc-editor.org/rfc/rfc6585#section-4" rel="noopener noreferrer"&gt;&lt;code&gt;429 Too Many Requests&lt;/code&gt;&lt;/a&gt; and permits a &lt;code&gt;Retry-After&lt;/code&gt; header. A gateway may be configured to return another status, so test the actual route rather than assuming the default communicates the policy you intended.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use Behavior for Detection, Identity for Enforcement
&lt;/h2&gt;

&lt;p&gt;Behavioral signals help discover that traffic moved. Identity and resource controls decide what it is allowed to do.&lt;/p&gt;

&lt;p&gt;Suppose an API sees a sequence of requests for rarely used administration paths. After one ASN is blocked, the same sequence returns from several providers. A useful response is not an endless list of ASNs. It is to verify that administrative routes require authentication, reduce anonymous reachability, rate-limit repeated failures, and alert on the sequence across source changes.&lt;/p&gt;

&lt;p&gt;At the gateway, record the smallest useful evidence:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;verified consumer or anonymous classification;&lt;/li&gt;
&lt;li&gt;route and method;&lt;/li&gt;
&lt;li&gt;status and policy outcome;&lt;/li&gt;
&lt;li&gt;rate-limit key category, without logging the secret itself;&lt;/li&gt;
&lt;li&gt;source network and trusted proxy chain;&lt;/li&gt;
&lt;li&gt;request-size and latency bands;&lt;/li&gt;
&lt;li&gt;bounded behavioral or fingerprint labels;&lt;/li&gt;
&lt;li&gt;origin outcome and gateway-generated outcome separately.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Avoid logging full credentials, request bodies, or personal data merely to improve correlation. The &lt;a href="https://api7.ai/blog/gateway-logging-best-practices" rel="noopener noreferrer"&gt;API gateway logging best practices&lt;/a&gt; apply here: evidence should support response without creating a second sensitive-data store.&lt;/p&gt;

&lt;h2&gt;
  
  
  Separate Gateway Policy from the Other Defense Layers
&lt;/h2&gt;

&lt;p&gt;An API gateway is well placed to authenticate, authorize, apply route-aware limits, normalize selected requests, and produce consistent decision telemetry. It is not every part of bot defense.&lt;/p&gt;

&lt;p&gt;Volumetric attacks may need upstream network or DDoS protection before traffic reaches the gateway. Browser automation may need challenge, device, or session signals. Credential stuffing requires identity-provider and account-risk controls. Business abuse—such as inventory hoarding or promotion fraud—needs application context the gateway may not have.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://owasp.org/API-Security/" rel="noopener noreferrer"&gt;OWASP API Security Top 10&lt;/a&gt; calls out unrestricted resource consumption and sensitive business flows as distinct risks. Treat them that way. One capacity limit should not stand in for transaction authorization, and a WAF rule should not stand in for account recovery controls.&lt;/p&gt;

&lt;p&gt;For scraping-specific patterns, use the narrower guidance in &lt;a href="https://api7.ai/blog/how-to-protect-your-apis-from-scrapers" rel="noopener noreferrer"&gt;How to Protect Your APIs from Scrapers&lt;/a&gt;. The lesson from migrating traffic is to make those controls portable across source changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test the Migration Counterexample
&lt;/h2&gt;

&lt;p&gt;Before rollout, run a small adversarial test:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Send the same allowed and denied request sequences from two source networks.&lt;/li&gt;
&lt;li&gt;Rotate the source IP while keeping a valid consumer credential.&lt;/li&gt;
&lt;li&gt;Keep the source fixed while changing the credential.&lt;/li&gt;
&lt;li&gt;Remove the shared counter backend in a test environment.&lt;/li&gt;
&lt;li&gt;Send an expensive operation below the simple request-rate threshold.&lt;/li&gt;
&lt;li&gt;Confirm which layer blocks, which status the caller sees, and which evidence operators receive.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The counterexample is the real gate: if changing an IP resets every meaningful control, the design still depends on location rather than caller or cost. If losing Redis silently removes a fleet-wide quota, the failure policy is incomplete. If the rule blocks legitimate crawler or integration traffic without an exception process, it is not operationally ready.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Bot infrastructure is replaceable. Durable API defenses therefore need to follow verified identity, protected resources, and repeated behavior—not a single IP range or ASN.&lt;/p&gt;

&lt;p&gt;Use network blocks for tactical containment, then move the lasting policy to the gateway boundary: authenticate valuable operations, scope limits to the right identity and route, make distributed-counter behavior explicit, and preserve evidence that correlates a workload across source changes. Apache APISIX and API7 Gateway can provide that policy and observation point, while DDoS, identity, fraud, and application teams keep ownership of the layers the gateway cannot replace.&lt;/p&gt;




&lt;p&gt;Originally published by Yilia Lin on &lt;a href="https://api7.ai/blog/bot-traffic-migration-api-gateway" rel="noopener noreferrer"&gt;API7.ai&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Disclosure: AI tools were used to draft portions of this article.&lt;/p&gt;

</description>
      <category>security</category>
      <category>api</category>
    </item>
    <item>
      <title>Release Apache APISIX Ingress Controller 2.0</title>
      <dc:creator>Yilia</dc:creator>
      <pubDate>Mon, 22 Dec 2025 06:50:22 +0000</pubDate>
      <link>https://dev.to/apisix/release-apache-apisix-ingress-controller-20-346n</link>
      <guid>https://dev.to/apisix/release-apache-apisix-ingress-controller-20-346n</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Apache APISIX Ingress Controller 2.0 is officially released. It delivers comprehensive Gateway API support, flexible multi-data-plane deployment, and etcd-free operation for robust, scalable Kubernetes traffic management.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Built on the high-performance API gateway Apache APISIX, &lt;a href="https://github.com/apache/apisix-ingress-controller" rel="noopener noreferrer"&gt;APISIX Ingress Controller&lt;/a&gt; has undergone multiple iterations and validations, and is now capable of handling large-scale traffic management demands. The Apache APISIX community is pleased to announce the official release of &lt;a href="https://apisix.apache.org/docs/ingress-controller/overview/" rel="noopener noreferrer"&gt;APISIX Ingress Controller 2.0&lt;/a&gt;. This release delivers substantial enhancements across three foundational pillars—&lt;strong&gt;comprehensive compatibility&lt;/strong&gt;, &lt;strong&gt;adaptable architecture&lt;/strong&gt;, and &lt;strong&gt;enterprise-grade stability&lt;/strong&gt;—empowering users to migrate their technology stacks smoothly and reliably.&lt;/p&gt;

&lt;h2&gt;
  
  
  Highlights of Apache APISIX Ingress Controller 2.0
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Support Gateway API
&lt;/h3&gt;

&lt;p&gt;This release achieves a significant milestone in Gateway API coverage with the addition of TCPRoute, UDPRoute, GRPCRoute, and TLSRoute. These extensions provide native, protocol-aware routing for a wide range of traffic types—from traditional HTTP and TCP/UDP to modern gRPC and TLS passthrough/termination. This unified support allows organizations to manage diverse ingress requirements within a consistent, future-ready configuration model, simplifying multi-protocol deployment and easing the transition to full Gateway API adoption.&lt;/p&gt;

&lt;h3&gt;
  
  
  Introduce Gateway API Extensions
&lt;/h3&gt;

&lt;p&gt;Building upon adherence to the Gateway API design principles, APISIX Ingress Controller 2.0 introduces a set of API extensions under &lt;code&gt;apisix.apache.org/v1alpha1&lt;/code&gt; based on the Gateway API. These extensions provide additional capabilities not currently directly covered by the standard Gateway API, while maintaining the core semantics and usage patterns of the standard resources. They are designed to meet more complex and diverse real-world usage scenarios.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;GatewayProxy&lt;/strong&gt;: It defines the connection between the APISIX Ingress Controller and the APISIX, including auth, endpoints, and global plugins. It is referenced via &lt;code&gt;parametersRef&lt;/code&gt; in Gateway, GatewayClass, or IngressClass resources.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;BackendTrafficPolicy&lt;/strong&gt;: It is for fine-grained traffic management of backend services, including load balancing, timeouts, retries, and host header handling in the APISIX Ingress Controller.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Consumer&lt;/strong&gt;: It defines API consumers and their credentials, enabling authentication and plugin configuration for controlling access to API endpoints.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;PluginConfig&lt;/strong&gt;: It defines reusable plugin configurations that can be referenced by other resources like HTTPRoute, enabling separation of routing logic and plugin settings for better reusability and manageability.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;HTTPRoutePolicy&lt;/strong&gt;: It configures advanced traffic management and routing policies for HTTPRoute or Ingress resources, enhancing functionality without modifying the original resources.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These extensions offer a standardized, vendor-supported path to leverage advanced APISIX features directly within the Gateway API ecosystem.&lt;/p&gt;

&lt;h3&gt;
  
  
  Support APISIX Standalone API-Driven Mode
&lt;/h3&gt;

&lt;p&gt;APISIX Ingress Controller 2.0 offers a lightweight, etcd-free deployment option through its Standalone &lt;a href="https://apisix.apache.org/docs/apisix/deployment-modes/#api-driven" rel="noopener noreferrer"&gt;API-Driven Mode&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This deployment paradigm stores routing configurations entirely in memory rather than in a configuration file. Updates are performed through a dedicated Standalone Admin API, which replaces the full configuration in a single operation and takes effect immediately via hot reloading, without requiring a restart.&lt;/p&gt;

&lt;p&gt;This mode is designed specifically for the APISIX Ingress Controller and is primarily intended for integration with &lt;a href="https://github.com/api7/adc" rel="noopener noreferrer"&gt;ADC (API Declarative CLI)&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Support Multi-Data-Plane Deployment Mode
&lt;/h3&gt;

&lt;p&gt;This release introduces flexible deployment options supporting multiple data plane modes, enabling a single ingress controller to manage several independent APISIX instances. This approach is ideal for environments requiring strict isolation—such as multi-tenancy, staging vs. production, or region-based routing—while maintaining centralized control.&lt;/p&gt;

&lt;h4&gt;
  
  
  Admin API Mode
&lt;/h4&gt;

&lt;p&gt;In the traditional deployment approach, APISIX uses etcd as its configuration center, allowing administrators to dynamically manage routes, upstreams, and other resources through RESTful APIs. It supports distributed cluster deployments with real-time configuration synchronization.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstatic.api7.ai%2Fuploads%2F2025%2F12%2F19%2FlX98Vcaj_apisix-ingress-controller-2-admin-api-mode.webp" class="article-body-image-wrapper"&gt;&lt;img alt="APISIX Ingress Controller Admin API Mode" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstatic.api7.ai%2Fuploads%2F2025%2F12%2F19%2FlX98Vcaj_apisix-ingress-controller-2-admin-api-mode.webp" width="800" height="948"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Standalone Mode
&lt;/h4&gt;

&lt;p&gt;APISIX can also run independently without relying on etcd, which is especially well‑suited for Kubernetes and single‑node deployments. It stores configurations in memory and manages them through the dedicated &lt;code&gt;/apisix/admin/configs&lt;/code&gt; endpoint.&lt;/p&gt;

&lt;p&gt;This mode is particularly suitable for Kubernetes environments and single-node deployments, where the API-driven memory management approach combines the convenience of traditional Admin API with the simplicity of Standalone mode.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstatic.api7.ai%2Fuploads%2F2025%2F12%2F19%2F8IxjQgCP_apisix-ingress-controller-2-standalone-mode.webp" class="article-body-image-wrapper"&gt;&lt;img alt="APISIX Ingress Controller Standalone Mode" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstatic.api7.ai%2Fuploads%2F2025%2F12%2F19%2F8IxjQgCP_apisix-ingress-controller-2-standalone-mode.webp" width="800" height="866"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This multi-mode strategy empowers organizations to tailor their ingress architecture to diverse requirements without sacrificing manageability or control.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Apache APISIX Ingress Controller 2.0 represents a significant evolution in Kubernetes ingress management, delivering a robust platform built for the complexity of modern, multi-protocol applications. By uniting comprehensive Gateway API support, extensible configuration through official API extensions, a lightweight standalone deployment mode, and versatile multi-data-plane management, this release provides a cohesive and powerful foundation for dynamic cloud environments.&lt;/p&gt;

&lt;p&gt;Whether you are standardizing ingress across diverse workloads, seeking greater architectural flexibility, or requiring enterprise-grade stability at scale, APISIX Ingress Controller 2.0 offers a forward-looking solution that simplifies operations without compromising capability. It stands as a testament to the community-driven innovation within the Apache APISIX ecosystem, designed to meet today's demands while adapting to tomorrow's challenges.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For a complete list of features and changes, please refer to the &lt;a href="https://github.com/apache/apisix-ingress-controller/blob/2.0.0/CHANGELOG.md#200" rel="noopener noreferrer"&gt;Release Changelog&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>ingress</category>
      <category>api</category>
      <category>apigateway</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Building an AI Agent Traffic Management Platform: APISIX AI Gateway in Practice</title>
      <dc:creator>Yilia</dc:creator>
      <pubDate>Thu, 20 Nov 2025 08:12:49 +0000</pubDate>
      <link>https://dev.to/yilialinn/building-an-ai-agent-traffic-management-platform-apisix-ai-gateway-in-practice-4md8</link>
      <guid>https://dev.to/yilialinn/building-an-ai-agent-traffic-management-platform-apisix-ai-gateway-in-practice-4md8</guid>
      <description>&lt;h2&gt;
  
  
  Introduction: The Turning Point from Dispersed Traffic to Intelligent Governance
&lt;/h2&gt;

&lt;p&gt;Since early 2025, within a leading global appliance giant, multiple business lines have introduced numerous large language models (LLMs). The R&amp;amp;D department needed coding assistants to improve efficiency, the marketing team focused on content generation, and the smart product team aimed to integrate conversational capabilities into home appliances. The variety of models rapidly expanded to include both self-built solutions like DeepSeek and Qwen, as well as proprietary models from multiple cloud service providers.&lt;/p&gt;

&lt;p&gt;However, this rapid expansion soon exposed new bottlenecks: &lt;strong&gt;fragmented inference traffic&lt;/strong&gt;, &lt;strong&gt;chaotic scheduling&lt;/strong&gt;, &lt;strong&gt;rising operational costs&lt;/strong&gt;, and &lt;strong&gt;uncontrollable stability issues&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The infrastructure team realized they needed a central system capable of unified control and dynamic scheduling at the traffic layer—a gateway born for AI.&lt;/p&gt;

&lt;p&gt;Thus, the enterprise began collaborating with the API7 team to jointly build an enterprise-grade AI Agent traffic management and scheduling platform. This was not just an upgrade in gateway technology, but a comprehensive architectural transformation for the AI era.&lt;/p&gt;

&lt;h2&gt;
  
  
  Challenges: The Complexity of Multi-Model, Multi-Tenant, Hybrid Cloud
&lt;/h2&gt;

&lt;p&gt;In this appliance giant's AI practice, challenges are primarily focused on three levels:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Stability Assurance
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;With rapid model iterations and service diversification, how to ensure stable proxying and quick recovery for each request?&lt;/li&gt;
&lt;li&gt;How to achieve zero-interruption switching between different vendors' LLM services?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Multi-tenant Isolation
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Each business department operated independent AI Agents. When tasks from one tenant spiraled out of control, resource and fault isolation became essential to prevent chain reactions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Intelligent Scheduling
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The hybrid cloud architecture coexisted with self-built models and cloud models. Facing dynamic loads, the system lacked real-time health awareness and automatic routing optimization.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These problems collectively pointed to a core requirement: &lt;strong&gt;AI traffic must be uniformly governed, visually monitored, and intelligently scheduled&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  System Design: Core Architecture of the AI Gateway
&lt;/h2&gt;

&lt;p&gt;The enterprise chose to build AI gateway capabilities on top of its existing API gateway, transforming it into a unified intelligent traffic hub.&lt;/p&gt;

&lt;p&gt;From an overall perspective, the system comprises three core layers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Access Layer&lt;/strong&gt;: Provides unified entry points, handling protocol conversion, authentication, and rate limiting.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Governance Layer&lt;/strong&gt;: Implements dynamic routing, circuit breaking, fault detection, and content filtering through a plugin mechanism.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scheduling Layer&lt;/strong&gt;: Combines health checks with real-time load information to enable automatic switching between self-built and cloud models.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5ktruxtzo3jnbj0m9hvm.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5ktruxtzo3jnbj0m9hvm.webp" alt="api7-ai-gateway-architecture" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the AI gateway, some AI models undergo rapid version iterations with stability risks. For example, improper request formats might trigger model loops, persistent abnormal outputs, or generate unreasonable content. Therefore, the internal technical team leveraged APISIX AI Gateway's plugin extension mechanism. Through custom plugins for request rewriting and defense, along with flexible configuration, they implemented intervention and filtering of request and response content to ensure service reliability and output quality.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Selection Criteria for AI Gateways
&lt;/h2&gt;

&lt;p&gt;In the process of building AI capability platforms, gateway selection significantly impacts the overall architecture. The enterprise evaluated solutions based on several core dimensions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Production-Grade Stability&lt;/strong&gt;: Stability is paramount. Ensuring service stability for users, enabling business operations to continue uninterrupted even during model fluctuations, is the most critical requirement.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Continuously Evolving Technical Capabilities&lt;/strong&gt;: With AI technology iterating rapidly, the AI gateway must maintain fast update cycles to promptly adapt to new model protocols and interaction patterns. The chosen AI gateway needs to keep pace with technological trends, avoiding becoming a bottleneck for business innovation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Standardized, Reusable Architecture&lt;/strong&gt;: Mature, reusable architecture is another key point. Providing standard API management and extension interfaces that comply with mainstream technical standards and best practices. APISIX AI Gateway's extensibility stood out as a highlight, directly determining integration costs with existing technology stacks and the smoothness of future integration into broader AI ecosystems.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Fine-Grained AI Traffic Governance and Multi-tenant Isolation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Scenario 1: Automatic Fallback for Hybrid Models
&lt;/h3&gt;

&lt;p&gt;In actual usage, this leading appliance enterprise adopted a hybrid deployment model for critical models (Model A): part of the service was self-built in private data centers, served as the main carrier for core traffic; simultaneously, using this model on public cloud with pay-as-you-go pricing served as Plan B.&lt;/p&gt;

&lt;p&gt;All requests were initially directed to self-built services by default. When self-built services encountered performance bottlenecks or became unavailable due to sudden traffic spikes or peaks, the gateway—based on preset token rate limiting policies and real-time health checks—automatically and seamlessly switched requests to cloud services, achieving smooth fallback. Once self-built services recovered, traffic automatically reverted.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;curl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://127.0.0.1:9180/apisix/admin/routes"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-X&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;PUT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;-H&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"X-API-KEY: ${ADMIN_API_KEY}"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;-d&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ai-proxy-multi-route"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"uri"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/anything"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"methods"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"POST"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"plugins"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"ai-proxy-multi"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"balancer"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"algorithm"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"roundrobin"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"hash_on"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"vars"&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"fallback_strategy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"instance_health_and_rate_limiting"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"instances"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"auth"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"header"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                  &lt;/span&gt;&lt;span class="nl"&gt;"Authorization"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bearer {ALIYUN_API_KEY}"&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"qwen2.5-32b-instruct-ali-bailian"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"options"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"model"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"qwen2.5-32b-instruct"&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"override"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"
                "&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions"&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"priority"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"provider"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"openai-compatible"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"weight"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"auth"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"header"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                  &lt;/span&gt;&lt;span class="nl"&gt;"Authorization"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bearer {CUSTOM_API_KEY}"&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"checks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"active"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                  &lt;/span&gt;&lt;span class="nl"&gt;"concurrency"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                  &lt;/span&gt;&lt;span class="nl"&gt;"healthy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"http_statuses"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                      &lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                      &lt;/span&gt;&lt;span class="mi"&gt;302&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"interval"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"successes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
                  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
                  &lt;/span&gt;&lt;span class="nl"&gt;"host"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"{CUSTOM_HOST_1}:{CUSTOM_PORT_1}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                  &lt;/span&gt;&lt;span class="nl"&gt;"http_method"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"POST"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                  &lt;/span&gt;&lt;span class="nl"&gt;"http_path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/v1/chat/completions"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                  &lt;/span&gt;&lt;span class="nl"&gt;"http_req_body"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"{&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;model&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;Qwen/Qwen2.5-32B-Instruct&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;messages&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:[{&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;role&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;user&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;content&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;0&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;}],&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;stream&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:false,&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;max_tokens&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:1}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                  &lt;/span&gt;&lt;span class="nl"&gt;"https_verify_certificate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                  &lt;/span&gt;&lt;span class="nl"&gt;"req_headers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt;&lt;span class="w"&gt;
                  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
                  &lt;/span&gt;&lt;span class="nl"&gt;"request_body"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                  &lt;/span&gt;&lt;span class="nl"&gt;"timeout"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                  &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                  &lt;/span&gt;&lt;span class="nl"&gt;"unhealthy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"http_failures"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"http_statuses"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                      &lt;/span&gt;&lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                      &lt;/span&gt;&lt;span class="mi"&gt;429&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                      &lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                      &lt;/span&gt;&lt;span class="mi"&gt;501&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                      &lt;/span&gt;&lt;span class="mi"&gt;502&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                      &lt;/span&gt;&lt;span class="mi"&gt;503&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                      &lt;/span&gt;&lt;span class="mi"&gt;504&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                      &lt;/span&gt;&lt;span class="mi"&gt;505&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"interval"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"tcp_failures"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"timeouts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt;
                  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"qwen2.5-32b-instruct-b"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"options"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"model"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Qwen/Qwen2.5-32B-Instruct"&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"override"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"endpoint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://{CUSTOM_HOST_1}:{CUSTOM_PORT_1}/v1/chat/completions"&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"priority"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"provider"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"openai-compatible"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"weight"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"auth"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"header"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                  &lt;/span&gt;&lt;span class="nl"&gt;"Authorization"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bearer {NLB_API_KEY}"&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"checks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"active"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                  &lt;/span&gt;&lt;span class="nl"&gt;"concurrency"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                  &lt;/span&gt;&lt;span class="nl"&gt;"healthy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"http_statuses"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                      &lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                      &lt;/span&gt;&lt;span class="mi"&gt;302&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"interval"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"successes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
                  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
                  &lt;/span&gt;&lt;span class="nl"&gt;"host"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"{CUSTOM_NLB_HOST}:{CUSTOM_NLB_PORT}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                  &lt;/span&gt;&lt;span class="nl"&gt;"http_method"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"POST"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                  &lt;/span&gt;&lt;span class="nl"&gt;"http_path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/v1/chat/completions"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                  &lt;/span&gt;&lt;span class="nl"&gt;"http_req_body"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"{&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;model&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;Qwen/Qwen2.5-32B-Instruct&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;messages&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:[{&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;role&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;user&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;content&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;0&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;}],&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;stream&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:false,&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;max_tokens&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:1}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                  &lt;/span&gt;&lt;span class="nl"&gt;"https_verify_certificate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                  &lt;/span&gt;&lt;span class="nl"&gt;"req_headers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt;&lt;span class="w"&gt;
                  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
                  &lt;/span&gt;&lt;span class="nl"&gt;"request_body"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                  &lt;/span&gt;&lt;span class="nl"&gt;"timeout"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                  &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                  &lt;/span&gt;&lt;span class="nl"&gt;"unhealthy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"http_failures"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"http_statuses"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                      &lt;/span&gt;&lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                      &lt;/span&gt;&lt;span class="mi"&gt;429&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                      &lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                      &lt;/span&gt;&lt;span class="mi"&gt;501&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                      &lt;/span&gt;&lt;span class="mi"&gt;502&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                      &lt;/span&gt;&lt;span class="mi"&gt;503&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                      &lt;/span&gt;&lt;span class="mi"&gt;504&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                      &lt;/span&gt;&lt;span class="mi"&gt;505&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"interval"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"tcp_failures"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"timeouts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt;
                  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"qwen2.5-32b-instruct-c"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"options"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"model"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Qwen/Qwen2.5-32B-Instruct"&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"override"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"endpoint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://{CUSTOM_NLB_HOST}:{CUSTOM_NLB_PORT}/v1/chat/completions"&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"priority"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"provider"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"openai-compatible"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"weight"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"keepalive"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"keepalive_pool"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"keepalive_timeout"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"ssl_verify"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"timeout"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;600000&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz5i7ha52aq3lnw2v4a01.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz5i7ha52aq3lnw2v4a01.webp" alt="On-Prem-to-Cloud Auto-Fallback Mechanism" width="800" height="594"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This mechanism operated fully automated, ensuring business continuity. Operations teams only became aware of state transitions through alerts, requiring no manual intervention. This capability not only significantly enhanced business continuity but also greatly reduced operational complexity, becoming key infrastructure for ensuring AI service high availability.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scenario 2: Token-Based Rate Limiting
&lt;/h3&gt;

&lt;p&gt;In this enterprise's AI service multi-tenant architecture, reasonable resource allocation and isolation between different users were the most core requirements. Since token costs varied significantly across different AI models, traditional request-based rate limiting couldn't accurately measure real resource consumption. Therefore, it was essential to introduce fine-grained quota management and traffic control mechanisms based on token volume, thereby truly reflecting resource consumption and ensuring reasonable scheduling and cost control between users.&lt;/p&gt;

&lt;p&gt;In this mechanism, different consumers had independent rate-limiting quotas, while different LLMs had separate token limits. Both took effect simultaneously, with consumer quotas having higher priority than LLM quotas. Once quotas were exhausted, consumers were prohibited from continuing to call LLM services.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa04y11gr0iprbhokb7d9.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa04y11gr0iprbhokb7d9.webp" alt="Consumer-LLM Token-based Rate Limiting" width="800" height="466"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For example, for LLM A, consumers A, B, and C had quotas of 10,000, 20,000, and 5,000 tokens, respectively, while LLM A overall had a global limit of 50,000 tokens. When consumers sent requests, the gateway would sequentially check both quotas: first verifying whether individual consumer quotas were sufficient, then confirming whether global LLM quotas were adequate. Only when both conditions were met would requests be forwarded to LLM A; insufficient quotas in either category would immediately return &lt;code&gt;429&lt;/code&gt; errors and reject requests.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdxjf4b5nrxz182gnd4e0.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdxjf4b5nrxz182gnd4e0.webp" alt="Token-based Rate Limiting Diagram" width="800" height="456"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In practical configuration, first enable the &lt;code&gt;ai-proxy-multi&lt;/code&gt; and &lt;code&gt;ai-rate-limiting&lt;/code&gt; plugins to set up rate limiting for the LLM.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;curl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://127.0.0.1:9180/apisix/admin/routes"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-X&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;PUT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;-H&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"X-API-KEY: ${ADMIN_API_KEY}"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;-d&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ai-proxy-multi-route"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"uri"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/anything"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"methods"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"POST"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"plugins"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"key-auth"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"ai-proxy-multi"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"instances"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"qwen2.5-32b-instruct-ali-bailian"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"options"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"model"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"qwen2.5-32b-instruct"&lt;/span&gt;&lt;span class="w"&gt;
             &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"auth"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"header"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"Authorization"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bearer {NLB_API_KEY}"&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"override"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"endpoint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions"&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"priority"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"provider"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"openai-compatible"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"weight"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"qwen2.5-32b-instruct-b"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"options"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"model"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Qwen/Qwen2.5-32B-Instruct"&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"auth"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"header"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"Authorization"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bearer {NLB_API_KEY}"&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"override"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"endpoint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://{CUSTOM_HOST_1}:{CUSTOM_PORT_1}/v1/chat/completions"&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"priority"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"provider"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"openai-compatible"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"weight"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"ai-rate-limiting"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"instances"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"qwen2.5-32b-instruct-ali-bailian"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"limit"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;50000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"time_window"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3600&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"qwen2.5-32b-instruct-b"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"limit"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;50000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"time_window"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3600&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"rejected_code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;429&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"limit_strategy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"total_tokens"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, create three consumers and configure corresponding rate limiting for each. The &lt;code&gt;ai-consumer-rate-limiting&lt;/code&gt; plugin is specifically used to enforce rate limits on consumers. Taking Consumer A as an example, the configuration is as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;curl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://127.0.0.1:9180/apisix/admin/consumers"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-X&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;PUT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;-H&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"X-API-KEY: ${ADMIN_API_KEY}"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;-d&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"username"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"consumer_a"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"plugins"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"key-auth"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"consumer_a_key"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"ai-consumer-rate-limiting"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"instances"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"qwen2.5-32b-instruct-ali-bailian"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"limit_strategy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"total_tokens"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"limit"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"time_window"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3600&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"qwen2.5-32b-instruct-b"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"limit_strategy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"total_tokens"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; 
            &lt;/span&gt;&lt;span class="nl"&gt;"limit"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"time_window"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3600&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"rejected_code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;429&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"rejected_msg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Insufficient token, try in one hour"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This solution effectively prevents individual consumers from excessive consumption, affecting other users, protects backend LLM instances from being overwhelmed by sudden traffic spikes, manages quotas based on actual token consumption, and provides differentiated services for different user levels.&lt;/p&gt;

&lt;h2&gt;
  
  
  Value Delivered by APISIX AI Gateway
&lt;/h2&gt;

&lt;p&gt;By building a unified AI gateway and consolidating AI traffic entry points, the technical team significantly improved the overall usage efficiency and management capability of model services. Main achievements include the following aspects:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Simplified Large Model Access, Lowering Usage Barriers
&lt;/h3&gt;

&lt;p&gt;The AI gateway provides unified access addresses and keys for all model services. Users don't need to concern themselves with backend model deployment and operational details—they can flexibly call various model resources through fixed entry points, greatly reducing the barrier to using AI capabilities.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Achieved Centralized Resource Management with Service Stability
&lt;/h3&gt;

&lt;p&gt;Without a unified AI gateway, various business units would need to build and maintain model services independently. Particularly when facing high resource consumption scenarios like large models, this would lead to duplicated GPU investments and waste. Through unified management and scheduling, efficient resource utilization was achieved, with service stability centrally guaranteed at the gateway level.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Unified Control with Traffic Security Assurance
&lt;/h3&gt;

&lt;p&gt;As the unified consolidation point for all AI traffic, the AI gateway became the critical node for implementing common capabilities. At this node, identity authentication, access auditing, content security review, abnormal request protection, and output content filtering could be centrally implemented, systematically enhancing overall platform controllability and security.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI Gateway Evolution Direction and Outlook
&lt;/h2&gt;

&lt;p&gt;As AI integrates into all aspects of R&amp;amp;D, manufacturing, and sales, this industry benchmark enterprise's goal is shifting from "connecting models" to "building a unified AI platform." In this process, the AI gateway is no longer just a traffic distribution node but is gradually evolving into the scheduling core of the entire AI capability system. In the future, it will carry new capabilities, including MCP (Model Context Protocol) and Agent2Agent (A2A) protocol, evolving into the enterprise's AI operating system kernel.&lt;/p&gt;

&lt;p&gt;For this appliance enterprise, the current phase focuses on building foundations: making every request &lt;strong&gt;observable, schedulable, and governable&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;While deeply applying APISIX AI Gateway in business scenarios, both parties are also jointly exploring evolution directions for next-generation AI infrastructure. As AI-native workloads like large model inference gradually become core business traffic, the team observed in practice that AI traffic exhibits significant differences from traditional web traffic in scheduling sensitivity, response patterns, and service governance dimensions. This presents new propositions for the gateway's continuous evolution:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;More Intelligent Traffic Scheduling&lt;/strong&gt;: Current load balancing strategies excel at handling high-concurrency, fast-response traditional traffic. For AI services, we hope to introduce metrics like GPU load, inference queue depth, and single-request latency to achieve intelligent distribution based on real-time service capabilities, making resource utilization more efficient and responses more stable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Backend Service State Awareness&lt;/strong&gt;: When model services experience slowed responses or queue buildup, the gateway should detect and switch faster. We're exploring how to implement dynamic routing based on real-time service states, such as inference performance and queue length, to ensure smooth user experiences.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Completing Observability Data&lt;/strong&gt;: The plugin architecture provides flexibility for traffic governance. Next, the technical team hopes to further enhance the gateway's fine-grained metric collection capabilities, such as upstream service status codes and precise response latency, making it more naturally integrated into existing monitoring and logging systems, providing solid support for fault localization and system optimization.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In an era where AI traffic becomes an enterprise-critical workload, API7 and this globally leading multinational appliance giant have jointly explored an evolution path of "gateway intelligence." It represents both a technological upgrade and an organizational capability transformation—making AI truly become an enterprise's underlying operational capability, rather than a passive tool.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>apigateway</category>
      <category>opensource</category>
      <category>api</category>
    </item>
    <item>
      <title>Load Balancing AI/ML API with Apache APISIX</title>
      <dc:creator>Yilia</dc:creator>
      <pubDate>Thu, 31 Jul 2025 09:13:52 +0000</pubDate>
      <link>https://dev.to/apisix/load-balancing-aiml-api-with-apache-apisix-4d7e</link>
      <guid>https://dev.to/apisix/load-balancing-aiml-api-with-apache-apisix-4d7e</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This blog provides a step-by-step guide to configure Apache APISIX for AI traffic splitting and load balancing between API versions, covering security setup, canary testing, and deployment monitoring.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://aimlapi.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;AI/ML API&lt;/strong&gt;&lt;/a&gt; is a one-stop, OpenAI-compatible endpoint that is trusted by 150,000+ developers to 300+ state-of-the-art models—chat, vision, image/video/music generation, embeddings, OCR, and more—from Google, Meta, OpenAI, Anthropic, Mistral, and others.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/apache/apisix" rel="noopener noreferrer"&gt;&lt;strong&gt;Apache APISIX&lt;/strong&gt;&lt;/a&gt; is a dynamic, real-time, high-performance API Gateway. APISIX API Gateway provides rich traffic management features and can serve as an AI Gateway through its flexible plugin system.&lt;/p&gt;

&lt;p&gt;Modern AI workloads often require smooth version migrations, A/B testing, and rolling updates. This guide shows you how to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Install&lt;/strong&gt; Apache APISIX with Docker quickstart.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secure&lt;/strong&gt; the Admin API with keys and IP whitelisting.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Define&lt;/strong&gt; separate routes for API versions v1 and v2.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Implement&lt;/strong&gt; weighted traffic splitting (50/50) via the &lt;code&gt;traffic-split&lt;/code&gt; plugin.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verify&lt;/strong&gt; the newly created split endpoint functionality.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Load test&lt;/strong&gt; and &lt;strong&gt;monitor&lt;/strong&gt; distribution accuracy.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To perform authenticated requests, you'll need an AI/ML API key. You can get one at &lt;a href="https://aimlapi.com/app/keys?utm_source=apisix&amp;amp;utm_medium=guide&amp;amp;utm_campaign=integration" rel="noopener noreferrer"&gt;https://aimlapi.com/app/keys/&lt;/a&gt; and use it as a Bearer token in your Authorization headers.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fea8t6m1725922ppm9moj.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fea8t6m1725922ppm9moj.webp" alt="Generate AI/ML API Key" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Quickstart Installation
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Download and run the quickstart script (includes etcd + APISIX)&lt;/span&gt;
curl &lt;span class="nt"&gt;-sL&lt;/span&gt; https://run.api7.ai/apisix/quickstart | sh

&lt;span class="c"&gt;# 2. Confirm APISIX is up and running&lt;/span&gt;
curl &lt;span class="nt"&gt;-I&lt;/span&gt; http://127.0.0.1:9080 | &lt;span class="nb"&gt;grep &lt;/span&gt;Server
&lt;span class="c"&gt;# ➜ Server: APISIX/3.13.0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; If you encounter port conflicts, adjust Docker host networking or map to different ports in the quickstart script.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Secure the Admin API
&lt;/h2&gt;

&lt;p&gt;By default, quickstart bypasses Admin API authentication. For any non-development environment, enforce security:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Set an Admin Key
&lt;/h3&gt;

&lt;p&gt;Edit &lt;code&gt;conf/config.yaml&lt;/code&gt; inside the APISIX container or local install directory, replacing the example key with your own API key obtained from the link above:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apisix&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;enable_admin&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;            &lt;span class="c1"&gt;# Enable Admin API&lt;/span&gt;
  &lt;span class="na"&gt;admin_key_required&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;      &lt;span class="c1"&gt;# Reject unauthenticated Admin requests&lt;/span&gt;
  &lt;span class="na"&gt;admin_key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;admin&lt;/span&gt;
      &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;YOUR_ADMIN_KEY_HERE&lt;/span&gt;  &lt;span class="c1"&gt;# Generated admin key - you can replace this with a secure key as you wish&lt;/span&gt;
      &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;admin&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Security Best Practice:&lt;/strong&gt; Use at least 32 characters, mix letters/numbers/symbols, and rotate keys quarterly.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  2. Whitelist Management IPs (allow_admin)
&lt;/h3&gt;

&lt;p&gt;Add your management or local networks under the &lt;code&gt;admin:&lt;/code&gt; section:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;admin&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;allow_admin&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;127.0.0.0/24&lt;/span&gt;   &lt;span class="c1"&gt;# Localhost &amp;amp; host network&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;0.0.0.0/0&lt;/span&gt;      &lt;span class="c1"&gt;# Allow all (temporary/testing only)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Warning:&lt;/strong&gt; &lt;code&gt;0.0.0.0/0&lt;/code&gt; opens Admin API to the world! Lock this down to specific subnets in production.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  3. Restart APISIX
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker restart apisix-quickstart
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Check Logs:&lt;/strong&gt; &lt;code&gt;docker logs apisix-quickstart --tail 50&lt;/code&gt; to ensure no errors about admin authentication.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Define Basic Routes for v1 and v2
&lt;/h2&gt;

&lt;p&gt;Before splitting traffic, ensure each version works individually.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Route for v1
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-i&lt;/span&gt; http://127.0.0.1:9180/apisix/admin/routes/test-v1 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-X&lt;/span&gt; PUT &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-API-KEY: YOUR_ADMIN_KEY_HERE"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "uri": "/test/v1",
    "upstream": {
      "type": "roundrobin",
      "nodes": {"api.aimlapi.com:443": 1},
      "scheme": "https",
      "pass_host": "node"
    }
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; Use &lt;code&gt;id&lt;/code&gt; fields if you want to manage or delete routes easily later.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  2. Route for v2
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-i&lt;/span&gt; http://127.0.0.1:9180/apisix/admin/routes/test-v2 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-X&lt;/span&gt; PUT &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-API-KEY: YOUR_ADMIN_KEY_HERE"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "uri": "/test/v2",
    "upstream": {
      "type": "roundrobin",
      "nodes": {"api.aimlapi.com:443": 1},
      "scheme": "https",
      "pass_host": "node"
    }
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Implement Traffic Splitting (50/50)
&lt;/h2&gt;

&lt;p&gt;Use the &lt;a href="https://apisix.apache.org/docs/apisix/plugins/traffic-split/" rel="noopener noreferrer"&gt;&lt;code&gt;traffic-split&lt;/code&gt;&lt;/a&gt; plugin for controlled distribution between v1 and v2. In the admin request below, replace &lt;code&gt;YOUR_ADMIN_KEY_HERE&lt;/code&gt; with your actual key.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-i&lt;/span&gt; http://127.0.0.1:9180/apisix/admin/routes/aimlapi-split &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-X&lt;/span&gt; PUT &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-API-KEY: YOUR_ADMIN_KEY_HERE"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "id": "aimlapi-split",
    "uri": "/chat/completions",
    "upstream": {
      "type": "roundrobin",
      "nodes": {"api.aimlapi.com:443": 1},
      "scheme": "https",
      "pass_host": "node"
    },
    "plugins": {
      "traffic-split": {
        "rules": [
          {
            "weight": 50,
            "upstream": {"type":"roundrobin","nodes":{"api.aimlapi.com:443":1},"scheme":"https","pass_host":"node"},
            "rewrite": {"uri":"/v1/chat/completions"}
          },
          {
            "weight": 50,
            "upstream": {"type":"roundrobin","nodes":{"api.aimlapi.com:443":1},"scheme":"https","pass_host":"node"},
            "rewrite": {"uri":"/v2/chat/completions"}
          }
        ]
      }
    }
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; Adjust the &lt;code&gt;weight&lt;/code&gt; values to shift traffic ratios (e.g., 80/20 for canary).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;code&gt;rewrite&lt;/code&gt; must match the internal API path exactly.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Verify Split Endpoint Functionality
&lt;/h2&gt;

&lt;p&gt;Test the &lt;code&gt;/chat/completions&lt;/code&gt; endpoint you just created. Replace &lt;code&gt;&amp;lt;AIML_API_KEY&amp;gt;&lt;/code&gt; with the key obtained earlier and use it as a Bearer token:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:9080/chat/completions &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &amp;lt;AIML_API_KEY&amp;gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"model":"gpt-4","messages":[{"role":"user","content":"ping"}]}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Expected Output:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"Pong! How can I assist you today?"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; Use &lt;code&gt;-v&lt;/code&gt; for verbose output to troubleshoot headers or TLS issues.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Load Test &amp;amp; Distribution Validation
&lt;/h2&gt;

&lt;p&gt;After configuring the split route, use the following commands to validate distribution. Replace &lt;code&gt;&amp;lt;AIML_API_KEY&amp;gt;&lt;/code&gt; with your Bearer token.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Send 100 test requests&lt;/span&gt;
&lt;span class="nb"&gt;time seq &lt;/span&gt;100 | xargs &lt;span class="nt"&gt;-I&lt;/span&gt; &lt;span class="o"&gt;{}&lt;/span&gt; curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /dev/null &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:9080/chat/completions &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &amp;lt;AIML_API_KEY&amp;gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"model":"gpt-4","messages":[{"role":"user","content":"ping"}]}'&lt;/span&gt;
&lt;span class="c"&gt;# 2. Check APISIX logs for upstream hits (replace IPs with actual resolved IPs)&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"v1 hits: &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;docker logs apisix-quickstart &lt;span class="nt"&gt;--since&lt;/span&gt; 5m | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'188.114.97.3:443'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"v2 hits: &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;docker logs apisix-quickstart &lt;span class="nt"&gt;--since&lt;/span&gt; 5m | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'188.114.96.3:443'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Expected:&lt;/strong&gt; Approximately 50 requests to each upstream.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; Use Prometheus or OpenTelemetry plugins for real‑time metrics instead of manual log parsing.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Best Practices &amp;amp; Next Steps
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Rate Limiting &amp;amp; Quotas&lt;/strong&gt;: Add &lt;a href="https://apisix.apache.org/docs/apisix/plugins/limit-count/" rel="noopener noreferrer"&gt;&lt;code&gt;limit-count&lt;/code&gt;&lt;/a&gt; plugin to protect your upstream from spikes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Authentication&lt;/strong&gt;: Layer on the &lt;a href="https://apisix.apache.org/docs/apisix/plugins/key-auth/" rel="noopener noreferrer"&gt;&lt;code&gt;key-auth&lt;/code&gt;&lt;/a&gt; plugin for consumer management.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Circuit Breaker&lt;/strong&gt;: Prevent cascading failures with the &lt;a href="https://apisix.apache.org/docs/apisix/plugins/api-breaker/" rel="noopener noreferrer"&gt;&lt;code&gt;api-breaker&lt;/code&gt;&lt;/a&gt; plugin.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Observability&lt;/strong&gt;: Integrate Prometheus, Skywalking, or Loki for dashboards and alerts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Infrastructure as Code&lt;/strong&gt;: Consider managing APISIX config via Kubernetes CRDs or ADC for reproducibility.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://apisix.apache.org/docs/apisix/getting-started/load-balancing/" rel="noopener noreferrer"&gt;APISIX Load Balancing Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aimlapi.com/?utm_source=apisix&amp;amp;utm_medium=guide&amp;amp;utm_campaign=integration" rel="noopener noreferrer"&gt;AI/ML API Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>api</category>
      <category>aiops</category>
      <category>apigateway</category>
    </item>
    <item>
      <title>Announcing APISIX Integration with AI/ML API</title>
      <dc:creator>Yilia</dc:creator>
      <pubDate>Wed, 30 Jul 2025 08:56:39 +0000</pubDate>
      <link>https://dev.to/apisix/announcing-apisix-integration-with-aiml-api-20gm</link>
      <guid>https://dev.to/apisix/announcing-apisix-integration-with-aiml-api-20gm</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;We're thrilled to announce that &lt;strong&gt;AI/ML API&lt;/strong&gt; has become a supported provider to the &lt;code&gt;ai-proxy&lt;/code&gt;, &lt;code&gt;ai-proxy-multi&lt;/code&gt;, and &lt;code&gt;ai-request-rewrite&lt;/code&gt; plugins in &lt;strong&gt;Apache APISIX&lt;/strong&gt;. All the AI/ML APIs will be supported in the next APISIX version.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://aimlapi.com/" rel="noopener noreferrer"&gt;AI/ML API&lt;/a&gt; is a single endpoint that gives you access to more than 300 ready-to-use AI models—large language models, embeddings, image and audio tools—through one standard REST interface. It is used by over 150,000 developers and organizations as a centralized LLM API gateway.&lt;/p&gt;

&lt;p&gt;We're thrilled to announce that &lt;strong&gt;AI/ML API&lt;/strong&gt; has become a supported provider to the &lt;code&gt;ai-proxy&lt;/code&gt;, &lt;code&gt;ai-proxy-multi&lt;/code&gt;, and &lt;code&gt;ai-request-rewrite&lt;/code&gt; plugins in &lt;strong&gt;Apache APISIX&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;AI/ML API provides a unified OpenAI-compatible API with access to &lt;strong&gt;300+ LLMs&lt;/strong&gt; such as GPT-4, Claude, Gemini, DeepSeek, and others. This integration bridges the gap between your API infrastructure and leading AI services, enabling you to deploy intelligent features—like chatbots, real-time translations, and data analysis—faster than ever.&lt;/p&gt;

&lt;h2&gt;
  
  
  Proxy to OpenAI via AI/ML API
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://apisix.apache.org/docs/apisix/installation-guide/" rel="noopener noreferrer"&gt;Install APISIX&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Generate your API key on &lt;a href="https://aimlapi.com/app/keys/" rel="noopener noreferrer"&gt;AI/ML API dashboard&lt;/a&gt;.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdreryvcnlz5evdzbi8r9.webp" alt="Generate AI/ML API Key" width="800" height="451"&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Configure the Route
&lt;/h3&gt;

&lt;p&gt;Create a route and configure the &lt;code&gt;ai-proxy&lt;/code&gt; plugin as such:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \&lt;/span&gt;
  &lt;span class="s"&gt;-H "X-API-KEY&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${ADMIN_API_KEY}" \&lt;/span&gt;
  &lt;span class="s"&gt;-d '{&lt;/span&gt;
    &lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ai-proxy-route"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;uri"&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/anything"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;methods"&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;POST"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;plugins"&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ai-proxy"&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;provider"&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;aimlapi"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;auth"&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;
          &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;header"&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Authorization"&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Bearer&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;'"&lt;/span&gt;&lt;span class="nv"&gt;$OPENAI_API_KEY"'"&lt;/span&gt; &lt;span class="c1"&gt;# Generated openai key from AI/ML API dashboard&lt;/span&gt;
          &lt;span class="pi"&gt;}&lt;/span&gt;
        &lt;span class="pi"&gt;},&lt;/span&gt;
        &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;options"&lt;/span&gt;&lt;span class="pi"&gt;:{&lt;/span&gt;
          &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;model"&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gpt-4"&lt;/span&gt;
        &lt;span class="pi"&gt;}&lt;/span&gt;
      &lt;span class="pi"&gt;}&lt;/span&gt;
    &lt;span class="pi"&gt;}&lt;/span&gt;
  &lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Test the Integration
&lt;/h3&gt;

&lt;p&gt;Send a POST request to the route with a system prompt and a sample user question in the request body:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="s2"&gt;"http://127.0.0.1:9080/anything"&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Host: api.openai.com"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "messages": [
      { "role": "system", "content": "You are a mathematician" },
      { "role": "user", "content": "What is 1+1?" }
    ]
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Verify Response
&lt;/h3&gt;

&lt;p&gt;You should receive a response similar to the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"choices"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"index"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"finish_reason"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"stop"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"logprobs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"role"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"assistant"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1 + 1 equals 2."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"refusal"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"annotations"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"created"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1753845968&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"model"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"gpt-4-0613"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"usage"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"prompt_tokens"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1449&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"completion_tokens"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1008&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"total_tokens"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2457&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Core Use Cases
&lt;/h2&gt;

&lt;p&gt;1.&lt;strong&gt;Unified AI Service Management&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Multi-Model Proxy and Load Balancing&lt;/strong&gt;: Replace hardcoded vendor endpoints with a single APISIX interface, dynamically routing requests to models from OpenAI, Claude, DeepSeek, Gemini, Mistral, etc., based on cost, latency, or performance needs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vendor-Agnostic Workflows&lt;/strong&gt;: Seamlessly switch between models (e.g., GPT-4 for creative tasks, Claude for document analysis) without code changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;2.&lt;strong&gt;Cost-Optimized Token Governance&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Token-Based Budget Enforcement&lt;/strong&gt;: Set per-team/monthly spending limits; auto-throttle requests when thresholds are exceeded.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Caching &amp;amp; Fallbacks&lt;/strong&gt;: Cache frequent LLM responses (e.g., FAQ answers) or reroute to cheaper models during provider outages.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;3.&lt;strong&gt;Real-Time AI Application Scaling&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Chatbots &amp;amp; Virtual Agents&lt;/strong&gt;: Power low-latency conversational interfaces with streaming support for token-by-token responses.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data Enrichment Pipelines&lt;/strong&gt;: Augment APIs with AI—e.g., auto-summarize user reviews or translate product descriptions on-the-fly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;4.&lt;strong&gt;Hybrid/Multi-Cloud AI Deployment&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Unified Control Plane&lt;/strong&gt;: Manage on-prem LLMs (e.g., Llama 3) alongside cloud APIs (OpenAI, Azure) with consistent policy enforcement.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;High Availability &amp;amp; Fault Tolerance&lt;/strong&gt;: Built-in health-checks, automatic retries and failover; if one LLM fails, traffic is rerouted within seconds to keep services alive.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;5.&lt;strong&gt;Enterprise AI Security &amp;amp; Compliance&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Data Security and Compliance&lt;/strong&gt;: Prompt Guard, content moderation, PII redaction, and full audit logs in a single place.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One Auth Layer for 300+ LLMs&lt;/strong&gt;: Unified authentication (JWT/OAuth2/OIDC) and authorization for 300+ LLM keys and policies.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;With AI/ML API now natively supported in Apache APISIX, you no longer have to choose between &lt;strong&gt;speed&lt;/strong&gt;, &lt;strong&gt;security&lt;/strong&gt;, or &lt;strong&gt;scale&lt;/strong&gt;—you get all three.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;One line of YAML&lt;/strong&gt; turns your gateway into a 300-model AI powerhouse.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero code changes&lt;/strong&gt; let you hot-swap GPT-4 for Claude, or route 10 % of traffic to a cheaper model for instant cost savings.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Built-in guardrails&lt;/strong&gt; (PII redaction, token budgets, content moderation) keep compliance teams happy while your product team ships faster.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  More Resources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Related APISIX AI Plugins

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://apisix.apache.org/docs/apisix/plugins/ai-proxy/" rel="noopener noreferrer"&gt;ai-proxy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://apisix.apache.org/docs/apisix/plugins/ai-proxy-multi/" rel="noopener noreferrer"&gt;ai-proxy-multi&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://apisix.apache.org/docs/apisix/plugins/ai-request-rewrite/" rel="noopener noreferrer"&gt;ai-request-rewrite&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;a href="https://aimlapi.com/community" rel="noopener noreferrer"&gt;AI/ML API Community&lt;/a&gt;&lt;/li&gt;

&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>api</category>
      <category>apigateway</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>GraphQL vs REST API: Which is Better for Your Project in 2025?</title>
      <dc:creator>Yilia</dc:creator>
      <pubDate>Mon, 21 Jul 2025 08:57:32 +0000</pubDate>
      <link>https://dev.to/api7/graphql-vs-rest-api-which-is-better-for-your-project-in-2025-45jj</link>
      <guid>https://dev.to/api7/graphql-vs-rest-api-which-is-better-for-your-project-in-2025-45jj</guid>
      <description>&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;REST APIs&lt;/strong&gt; excel in simplicity, caching, and microservices architecture, with widespread adoption and mature tooling ecosystem&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GraphQL&lt;/strong&gt; provides precise data fetching, reduces over-fetching, and offers superior flexibility for complex data relationships&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance varies by use case&lt;/strong&gt;: REST wins for simple CRUD operations and caching scenarios, while GraphQL shines in mobile apps and complex queries&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API Gateway integration&lt;/strong&gt; is crucial for managing both approaches effectively, providing unified security, monitoring, and transformation capabilities&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No universal winner&lt;/strong&gt;: The choice depends on project requirements, team expertise, and specific technical constraints rather than inherent superiority&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Understanding REST APIs and GraphQL: The Foundation of Modern API Architecture
&lt;/h2&gt;

&lt;p&gt;When evaluating modern API architectures, developers frequently encounter the question: "What is a RESTful API, and how does it compare to GraphQL?" According to recent industry data, &lt;a href="https://www.nucamp.co" rel="noopener noreferrer"&gt;over 61% of organizations are now using GraphQL&lt;/a&gt;, while REST continues to dominate enterprise environments. Understanding both approaches is essential for making informed architectural decisions.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is a RESTful API?
&lt;/h3&gt;

&lt;p&gt;A RESTful API (Representational State Transfer) is an architectural style that leverages HTTP protocols to create scalable web services. REST and RESTful services follow six key principles: statelessness, client-server architecture, cacheability, layered system, uniform interface, and code on demand (optional). Unlike the traditional SOAP protocol vs REST debate, where SOAP v REST discussions centered on protocol complexity, RESTful APIs embrace simplicity and web-native patterns.&lt;/p&gt;

&lt;p&gt;The fundamental concept behind RESTful API architecture involves treating every piece of data as a resource, accessible through standard HTTP methods (GET, POST, PUT, DELETE). This approach has made REST API RESTful implementations the backbone of countless web applications, from simple CRUD operations to complex enterprise systems.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is GraphQL?
&lt;/h3&gt;

&lt;p&gt;GraphQL represents a paradigm shift from traditional REST approaches. Developed by Facebook in 2012 and open-sourced in 2015, GraphQL is a query language and runtime for APIs that enables clients to request exactly the data they need. Unlike REST's resource-based approach, GraphQL operates through a single endpoint that can handle complex data fetching scenarios.&lt;/p&gt;

&lt;p&gt;The core innovation of GraphQL lies in its declarative data fetching model. When you need to perform a GraphQL query to get number of customers along with their recent orders and contact information, a single request can retrieve all related data. This contrasts sharply with REST, where multiple API calls would be necessary.&lt;/p&gt;

&lt;p&gt;GraphQL mutation capabilities further extend its functionality, allowing clients to modify data using the same expressive query language. This unified approach to both reading and writing data represents a significant departure from REST's verb-based HTTP methods.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnr2tzdpwposd033c02j1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnr2tzdpwposd033c02j1.png" alt="REST vs GraphQL API Call Patterns" width="800" height="655"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Historical Context
&lt;/h3&gt;

&lt;p&gt;The evolution from SOAP protocol vs REST to modern GraphQL reflects changing application needs. REST APIs have revolutionized how computer systems communicate over the internet, providing a secure, scalable interface that follows specific architectural rules. However, as applications became more sophisticated and mobile-first, the limitations of REST's fixed data structures became apparent.&lt;/p&gt;

&lt;p&gt;GraphQL emerged as a response to these challenges, particularly the over-fetching and under-fetching problems inherent in REST architectures. While REST remains excellent for many use cases, GraphQL's client-driven approach addresses specific pain points in modern application development.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Differences: When to Choose GraphQL vs REST API
&lt;/h2&gt;

&lt;p&gt;The choice between GraphQL and REST involves understanding fundamental differences in how each approach handles data fetching, performance optimization, and development workflows.&lt;/p&gt;

&lt;h3&gt;
  
  
  Data Fetching Approaches
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.javacodegeeks.com" rel="noopener noreferrer"&gt;REST uses multiple endpoints for each resource&lt;/a&gt;, requiring separate HTTP calls for different data types. A typical REST implementation might require:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET /api/users/123
GET /api/users/123/orders
GET /api/users/123/profile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This multi-request pattern often leads to over-fetching (receiving unnecessary data) or under-fetching (requiring additional requests). In contrast, GraphQL allows clients to specify exactly what data they need in a single request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;orders&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Performance Considerations
&lt;/h3&gt;

&lt;p&gt;Performance characteristics vary significantly between approaches. RESTful APIs excel in scenarios where caching is crucial, as HTTP caching mechanisms are well-established and widely supported. The stateless nature of REST makes it highly scalable for simple operations.&lt;/p&gt;

&lt;p&gt;GraphQL shines in bandwidth-constrained environments, particularly mobile applications. By fetching only required data, GraphQL can reduce payload sizes by 30-50% compared to equivalent REST implementations. However, this efficiency comes with increased server-side complexity, as resolvers must efficiently handle arbitrary query combinations.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F148ynou72iefhpdevlph.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F148ynou72iefhpdevlph.png" alt="Mobile App Data-Fetching: REST vs GraphQL Efficiency" width="800" height="294"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Development Experience
&lt;/h3&gt;

&lt;p&gt;REST's simplicity makes it accessible to developers at all skill levels. The HTTP-based approach aligns naturally with web development patterns, and debugging tools are mature and widely available. RESTful API documentation follows established conventions, making integration straightforward.&lt;/p&gt;

&lt;p&gt;GraphQL offers powerful introspection capabilities and schema-first development, but requires a steeper learning curve. The strongly-typed schema provides excellent developer experience through auto-completion and compile-time validation, but teams must invest time in understanding GraphQL-specific concepts like resolvers, fragments, and query optimization.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scalability Factors
&lt;/h3&gt;

&lt;p&gt;REST is well-suited for microservices architectures, where each service exposes functionality through well-defined APIs. The stateless nature of RESTful services makes horizontal scaling straightforward, and load balancing strategies are well-established.&lt;/p&gt;

&lt;p&gt;GraphQL presents unique scalability challenges in distributed systems. Query complexity can vary dramatically, making resource planning difficult. Advanced GraphQL implementations require sophisticated caching strategies and query analysis to prevent performance degradation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Technical Implementation: REST vs GraphQL in Practice
&lt;/h2&gt;

&lt;p&gt;Understanding the practical implementation details of both approaches helps developers make informed decisions about which technology best fits their specific requirements.&lt;/p&gt;

&lt;h3&gt;
  
  
  REST API Implementation Patterns
&lt;/h3&gt;

&lt;p&gt;RESTful API implementation follows well-established patterns centered around HTTP methods and resource-based URLs. A typical REST API for user management might include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET    /api/users           # List all users
POST   /api/users           # Create new user
GET    /api/users/123       # Get specific user
PUT    /api/users/123       # Update user
DELETE /api/users/123       # Delete user
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This approach leverages HTTP's built-in semantics, making RESTful APIs intuitive for developers familiar with web protocols. Status codes provide clear communication about operation results, and stateless communication ensures scalability.&lt;/p&gt;

&lt;p&gt;Versioning in REST typically involves URL-based strategies (&lt;code&gt;/v1/users&lt;/code&gt;, &lt;code&gt;/v2/users&lt;/code&gt;) or header-based approaches. While this can lead to API proliferation, it provides clear backward compatibility guarantees.&lt;/p&gt;

&lt;h3&gt;
  
  
  GraphQL Implementation Essentials
&lt;/h3&gt;

&lt;p&gt;GraphQL implementation begins with schema definition, establishing the contract between client and server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;!]!&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Order&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Float&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;createdAt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;!]!&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;!):&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Mutation&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;createUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;!,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;!):&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;GraphQL mutation operations provide a structured approach to data modification, maintaining the same expressive power as queries. Resolvers handle the actual data fetching logic, allowing for flexible backend integration.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqzst2m5vq63kn2hqk9qf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqzst2m5vq63kn2hqk9qf.png" alt="GraphQL Server Architecture: From Query to Client Response" width="800" height="842"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Security Considerations
&lt;/h3&gt;

&lt;p&gt;Both approaches require careful security implementation, but with different focus areas. RESTful APIs benefit from standard HTTP security practices: authentication headers, CORS policies, and input validation at the endpoint level.&lt;/p&gt;

&lt;p&gt;GraphQL introduces unique security challenges, particularly around query complexity and depth limiting. Malicious clients could potentially craft expensive queries that strain server resources. Implementing query complexity analysis, depth limiting, and timeout mechanisms becomes crucial for GraphQL security.&lt;/p&gt;

&lt;h3&gt;
  
  
  Error Handling and Monitoring
&lt;/h3&gt;

&lt;p&gt;REST relies on HTTP status codes for error communication, providing a standardized approach that integrates well with existing monitoring tools. Error responses follow predictable patterns, making debugging straightforward.&lt;/p&gt;

&lt;p&gt;GraphQL uses a different error model, where HTTP status is typically 200 even for errors, with actual error information embedded in the response payload. This approach requires specialized monitoring tools and error handling strategies but provides more detailed error context.&lt;/p&gt;

&lt;h2&gt;
  
  
  API Gateway Management: Optimizing GraphQL and REST APIs
&lt;/h2&gt;

&lt;p&gt;Modern API management requires sophisticated gateway solutions that can handle both REST and GraphQL effectively. API gateways serve as the critical infrastructure layer that enables organizations to manage, secure, and optimize their API ecosystems regardless of the underlying architecture.&lt;/p&gt;

&lt;h3&gt;
  
  
  Managing RESTful APIs with API Gateway
&lt;/h3&gt;

&lt;p&gt;RESTful APIs integrate naturally with traditional API gateway patterns. Standard gateway features like route configuration, load balancing, and protocol translation work seamlessly with REST's resource-based approach. Caching strategies are particularly effective with RESTful services, as the predictable URL patterns and HTTP semantics enable sophisticated caching policies.&lt;/p&gt;

&lt;p&gt;API gateways excel at transforming REST requests and responses, enabling legacy system integration and API evolution without breaking existing clients. Rate limiting and throttling policies can be applied at the resource level, providing granular control over API consumption.&lt;/p&gt;

&lt;h3&gt;
  
  
  GraphQL API Gateway Integration
&lt;/h3&gt;

&lt;p&gt;GraphQL presents unique challenges and opportunities for API gateway integration. Modern gateways like API7 provide GraphQL-specific features including schema stitching, query complexity analysis, and GraphQL-to-REST transformation capabilities.&lt;/p&gt;

&lt;p&gt;Query complexity analysis becomes crucial for protecting backend services from expensive operations. API gateways can implement sophisticated policies that evaluate query depth, field count, and estimated execution time before forwarding requests to GraphQL servers.&lt;/p&gt;

&lt;p&gt;Schema federation support allows organizations to compose multiple GraphQL services into a unified API surface, with the gateway handling query planning and execution across distributed services.&lt;/p&gt;

&lt;h3&gt;
  
  
  Unified API Management Approach
&lt;/h3&gt;

&lt;p&gt;Leading API gateway solutions support multi-protocol environments, enabling organizations to manage both RESTful APIs and GraphQL services through a single management plane. This unified approach provides consistent authentication, authorization, monitoring, and analytics across all API types.&lt;/p&gt;

&lt;p&gt;Developer portal integration becomes particularly valuable in mixed environments, as it can generate documentation and provide testing interfaces for both REST endpoints and GraphQL schemas. This consistency improves developer experience and reduces onboarding complexity.&lt;/p&gt;

&lt;h3&gt;
  
  
  Performance Optimization Techniques
&lt;/h3&gt;

&lt;p&gt;API gateways enable sophisticated performance optimization for both API types. Intelligent caching can be applied to GraphQL queries based on query fingerprinting and field-level cache policies. For RESTful APIs, traditional HTTP caching mechanisms provide excellent performance benefits.&lt;/p&gt;

&lt;p&gt;Request and response transformation capabilities allow gateways to optimize data formats, compress payloads, and aggregate multiple backend calls into single client responses. Global load balancing and failover mechanisms ensure high availability for both GraphQL and REST services.&lt;/p&gt;

&lt;h2&gt;
  
  
  Making the Right Choice: Decision Framework and Future Trends
&lt;/h2&gt;

&lt;p&gt;Selecting between GraphQL and REST requires a structured evaluation of technical requirements, team capabilities, and long-term strategic goals. Rather than viewing this as a binary choice, successful organizations often adopt hybrid approaches that leverage the strengths of both paradigms.&lt;/p&gt;

&lt;h3&gt;
  
  
  Decision Criteria Matrix
&lt;/h3&gt;

&lt;p&gt;Project requirements should drive the technology choice. RESTful APIs excel in scenarios requiring:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Simple CRUD operations with well-defined resources&lt;/li&gt;
&lt;li&gt;Heavy caching requirements&lt;/li&gt;
&lt;li&gt;Integration with existing HTTP-based infrastructure&lt;/li&gt;
&lt;li&gt;Team familiarity with web standards&lt;/li&gt;
&lt;li&gt;Microservices architectures with clear service boundaries&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;GraphQL provides advantages when projects involve:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Complex data relationships and nested queries&lt;/li&gt;
&lt;li&gt;Mobile applications with bandwidth constraints&lt;/li&gt;
&lt;li&gt;Rapidly evolving client requirements&lt;/li&gt;
&lt;li&gt;Multiple client types with different data needs&lt;/li&gt;
&lt;li&gt;Real-time features requiring subscription support&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Use Case Scenarios
&lt;/h3&gt;

&lt;p&gt;Enterprise applications often benefit from REST's maturity and simplicity. E-commerce platforms, content management systems, and traditional web applications typically align well with RESTful service patterns. The predictable structure and extensive tooling ecosystem make REST an excellent choice for teams building standard business applications.&lt;/p&gt;

&lt;p&gt;GraphQL shines in scenarios requiring flexible data access patterns. Social media platforms, analytics dashboards, and mobile applications often see significant benefits from GraphQL's precise data fetching capabilities. When you need to execute a GraphQL query to get the number of customers along with their transaction history and preferences, the single-request efficiency becomes invaluable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Future Outlook and Trends
&lt;/h3&gt;

&lt;p&gt;The API landscape continues evolving, with both REST and GraphQL finding distinct niches. REST maintains strong adoption in enterprise environments, while GraphQL usage grows in frontend-driven applications and mobile development.&lt;/p&gt;

&lt;p&gt;Emerging trends include hybrid approaches where REST APIs serve as data sources for GraphQL gateways, providing the best of both worlds. API gateway evolution increasingly focuses on protocol translation and unified management capabilities.&lt;/p&gt;

&lt;p&gt;Industry adoption data shows continued growth for both approaches, suggesting that the future involves coexistence rather than replacement. Organizations are increasingly adopting API-first strategies that can accommodate multiple paradigms based on specific use case requirements.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion and Recommendations
&lt;/h3&gt;

&lt;p&gt;The GraphQL vs REST debate oversimplifies what should be a nuanced technical decision. Both approaches offer distinct advantages, and the optimal choice depends on specific project requirements, team expertise, and organizational constraints.&lt;/p&gt;

&lt;p&gt;RESTful APIs remain the gold standard for simple, cacheable, and well-understood interaction patterns. Their alignment with HTTP semantics, mature tooling ecosystem, and widespread developer familiarity make them an excellent default choice for many applications.&lt;/p&gt;

&lt;p&gt;GraphQL provides compelling advantages for applications requiring flexible data access, precise resource utilization, and rapid iteration. The investment in learning GraphQL concepts pays dividends in scenarios where its strengths align with project needs.&lt;/p&gt;

&lt;p&gt;The most successful API strategies often involve thoughtful integration of both approaches, leveraged through sophisticated API gateway solutions that can manage, secure, and optimize diverse API ecosystems. As API management continues evolving, the ability to support multiple paradigms becomes increasingly valuable for maintaining architectural flexibility and meeting diverse client requirements.&lt;/p&gt;

&lt;p&gt;Rather than asking "which is better," developers should ask "which approach best serves my specific requirements?" The answer will vary based on context, but understanding the strengths and limitations of both GraphQL and REST enables informed decisions that drive successful API implementations.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>devops</category>
      <category>discuss</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Manage User Permissions Effortlessly Using API7-MCP</title>
      <dc:creator>Yilia</dc:creator>
      <pubDate>Tue, 20 May 2025 10:21:11 +0000</pubDate>
      <link>https://dev.to/api7/manage-user-permissions-effortlessly-using-api7-mcp-2k8p</link>
      <guid>https://dev.to/api7/manage-user-permissions-effortlessly-using-api7-mcp-2k8p</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;As large language model (LLM) applications experience explosive growth, a pivotal challenge emerges: how can these models transcend mere dialogue boxes to interact seamlessly with our daily files, applications, and web services? Addressing this, Anthropic—the developer behind Claude—officially launched and open-sourced the Model Context Protocol (MCP) in late 2024.&lt;/p&gt;

&lt;p&gt;MCP offers a standardized method enabling AI models to securely and controllably connect with and operate external data sources and tools, such as accessing files, querying databases, and invoking APIs. This breakthrough dismantles the traditional isolation of models, significantly expanding AI's capabilities—from a conversational assistant to a hands-on helper capable of executing more specific and complex tasks.&lt;/p&gt;

&lt;h2&gt;
  
  
  How API7-MCP Enhances API7 Enterprise
&lt;/h2&gt;

&lt;p&gt;Keeping pace with this trend, API7.ai introduced &lt;a href="https://github.com/api7/api7-mcp" rel="noopener noreferrer"&gt;API7-MCP&lt;/a&gt;. Leveraging MCP's robust capabilities, API7-MCP facilitates effortless and rapid integration into the LLM ecosystem, further simplifying numerous complex and tedious configuration processes within API7 Enterprise.&lt;/p&gt;

&lt;p&gt;This article delves into how to utilize API7-MCP to configure user roles and permissions through natural language, showcasing its powerful functionalities via practical use cases.&lt;/p&gt;

&lt;h3&gt;
  
  
  Overview of Permission Management Features
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Query and edit user roles, assessing user permission risks.&lt;/li&gt;
&lt;li&gt;Perform CRUD (Create, Read, Update, Delete) operations on roles.&lt;/li&gt;
&lt;li&gt;Perform CRUD operations on permissions and query permission configuration rules.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These features assist users in promptly identifying and addressing permission risks, effectively constructing, adjusting, and managing the entire permission system, ensuring the security and rationality of system permissions.&lt;/p&gt;

&lt;p&gt;In this article, we demonstrate using the scenario of configuring personnel permissions for a new-launched business system. In real-world applications, the above functionalities can be flexibly combined to meet actual needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use Case: Permission Configuration for New Business System Launch
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Background
&lt;/h3&gt;

&lt;p&gt;Assume an enterprise internally launches a business system named "Intelligent Customer Relationship Management System" (abbreviated as "iCRM"). The system administrator needs to add a new role, "iCRM admin" (responsible for the comprehensive management and maintenance of the iCRM system), and assign this role to the user Tom. Let's achieve this effortlessly using API7-MCP.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Install API7 Enterprise.&lt;/li&gt;
&lt;li&gt;Create a user Tom and &lt;code&gt;icrm&lt;/code&gt; gateway group within API7 Enterprise.&lt;/li&gt;
&lt;li&gt;Configure &lt;a href="https://github.com/api7/api7-mcp" rel="noopener noreferrer"&gt;API7-MCP&lt;/a&gt; in the AI client (here we combine VS Code with the Cline plugin as the AI client).&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Steps
&lt;/h3&gt;

&lt;p&gt;1.Input the following request in the Cline dialog box:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Add a new role 'iCRM admin', which can manage all resources under the &lt;code&gt;icrm&lt;/code&gt; gateway group. After creating the role, write and bind a permission policy to it, and assign this role to user Tom."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;2.Cline requests to obtain Tom's user ID. Click "Approve" to authorize it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkl9y4j27lljhwgmn1xrn.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkl9y4j27lljhwgmn1xrn.webp" alt="Get User ID" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;3.Cline requests to create a permission policy that allows full access to the &lt;code&gt;icrm&lt;/code&gt; gateway group. Click "Approve" to authorize it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuszo6twafwojk88mol8j.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuszo6twafwojk88mol8j.webp" alt="Create Permission Policy" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;4.Cline requests to create the role &lt;code&gt;iCRM admin&lt;/code&gt; and attach the newly created permission policy to it. Click "Approve" to authorize it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvkcmzkj27w7yvjixljx7.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvkcmzkj27w7yvjixljx7.webp" alt="Create Role" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;5.After successfully creating the role, Cline requests to assign the &lt;code&gt;iCRM admin&lt;/code&gt; role to user Tom. Click "Approve" to authorize it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvtfwor2oazzmfyp4fl1s.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvtfwor2oazzmfyp4fl1s.webp" alt="Update Role for User" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;6.Task completed. The "iCRM admin" role and corresponding permission policy have been successfully created and assigned to user Tom.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foyjwppalcsopmo6pj8wg.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foyjwppalcsopmo6pj8wg.webp" alt="Role and Permission Policy Created" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Verify
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Confirm Role Creation
&lt;/h4&gt;

&lt;p&gt;The custom role "iCRM admin" has been created, described as "Role with permissions to manage all resources under icrm gateway group."&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk76zuuptznt3kfhbyzb8.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk76zuuptznt3kfhbyzb8.webp" alt="iCRM Role Created" width="800" height="432"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This role has been attached to the permission policy &lt;code&gt;icrm_full_access&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu53etehoikj20ruq0yrw.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu53etehoikj20ruq0yrw.webp" alt="Full iCRM Access Attached" width="800" height="432"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Confirm Permission Policy Creation
&lt;/h4&gt;

&lt;p&gt;Reviewing the permission policy, it allows access to all resources under the &lt;code&gt;icrm&lt;/code&gt; gateway group.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvg50eo9573jfpb1ulgqg.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvg50eo9573jfpb1ulgqg.webp" alt="Check Permission Policy" width="800" height="432"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Confirm User Role Update
&lt;/h4&gt;

&lt;p&gt;User Tom has been updated from having no role to being assigned the &lt;code&gt;iCRM admin&lt;/code&gt; role.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyqcy1owekymg53s6rp59.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyqcy1owekymg53s6rp59.webp" alt="User without Role" width="800" height="432"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgq5m9i74ya0m22q947r7.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgq5m9i74ya0m22q947r7.webp" alt="User with Updated Role" width="800" height="432"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;API7-MCP introduces flexibility and security to API management through natural language-based permission configuration, effectively eliminating the complexities of traditional permission management. By leveraging the MCP protocol, users can achieve efficient API management with API7 Enterprise at a lower cost.&lt;/p&gt;

&lt;p&gt;The scenario-based example of the iCRM system demonstrates that API7-MCP can adapt to most permission management scenarios. It focuses on building permission architectures while also emphasizing dynamic adjustments to permission policies. Through natural language interactions, it integrates seamlessly into business scenarios, achieving a fusion of AI and business processes. This approach not only reduces the technical costs of enterprise permission management but also builds a scalable API security ecosystem through the standardized MCP protocol.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>api</category>
      <category>apigateway</category>
    </item>
    <item>
      <title>From stdio to HTTP SSE: Host Your MCP Server with APISIX API Gateway</title>
      <dc:creator>Yilia</dc:creator>
      <pubDate>Mon, 21 Apr 2025 10:24:20 +0000</pubDate>
      <link>https://dev.to/apisix/from-stdio-to-http-sse-host-your-mcp-server-with-apisix-api-gateway-26i2</link>
      <guid>https://dev.to/apisix/from-stdio-to-http-sse-host-your-mcp-server-with-apisix-api-gateway-26i2</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In contemporary API infrastructure, HTTP protocols and streaming communications (like SSE, WebSocket) have become mainstream for building real-time, interactive applications. Over the past few months, the Model Context Protocol (MCP) has gained popularity. However, most MCP Servers are implemented via stdio for local environments and cannot be invoked by external services and developers.&lt;/p&gt;

&lt;p&gt;To bridge these services with modern API architectures, Apache APISIX has introduced the &lt;code&gt;mcp-bridge&lt;/code&gt; plugin. It seamlessly converts stdio-based MCP services into HTTP SSE streaming interfaces and manages them through an API gateway for routing and traffic management.&lt;/p&gt;

&lt;h2&gt;
  
  
  Model Context Protocol (MCP) Overview
&lt;/h2&gt;

&lt;p&gt;MCP is an open protocol that standardizes how AI applications provide context information to large language models (LLMs). It allows developers to switch between different LLM providers while ensuring data security and facilitating integration with local or remote data sources. Supporting a client-server architecture, MCP servers expose specific functionalities that are accessible to clients via these servers.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is the &lt;code&gt;mcp-bridge&lt;/code&gt; Plugin?
&lt;/h2&gt;

&lt;p&gt;The Apache APISIX &lt;code&gt;mcp-bridge&lt;/code&gt; plugin launches a subprocess to manage the MCP Server, takes over its stdio channel, transforms client HTTP SSE requests into MCP protocol calls, and pushes responses back to the client via SSE.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key features:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;📡 Wraps MCP RPC calls into SSE message streams&lt;/li&gt;
&lt;li&gt;🔄 Manages subprocess stdio lifecycle with queued RPC scheduling&lt;/li&gt;
&lt;li&gt;🗂️ Lightweight MCP session management (including session ID, ping keep-alive, and queuing)&lt;/li&gt;
&lt;li&gt;🧰 Supports session sharing across multiple workers for stability in APISIX multi-worker environments&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How It Works and Architecture Diagram
&lt;/h2&gt;

&lt;p&gt;Below is a sequence diagram illustrating the working mechanism of the &lt;code&gt;mcp-bridge&lt;/code&gt; plugin, helping you to understand the data flow from stdio to SSE:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6wbycka73jbv164hhxg6.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6wbycka73jbv164hhxg6.webp" alt="MCP-Bridge Architecture Diagram" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;✅ Highlights:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;APISIX manages SSE long-lived connections&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;mcp-bridge&lt;/code&gt; plugin handles subprocesses, stdio, and scheduling queues&lt;/li&gt;
&lt;li&gt;Clients receive real-time subprocess outputs, forming streaming SSE responses&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Application Scenarios and Benefits
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;✅ Typical Application Scenarios&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🛠️ Integrating existing MCP/stdio services with web platforms&lt;/li&gt;
&lt;li&gt;🖥️ Cross-language and cross-platform subprocess service management&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;✅ Benefits&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🌐 Modernization: Instantly transform stdio services into HTTP SSE APIs&lt;/li&gt;
&lt;li&gt;🕹️ Managed: Unified management of subprocess launch and IO lifecycle&lt;/li&gt;
&lt;li&gt;📈 Scalability: Session sharing in multi-worker environments for large-scale deployment support&lt;/li&gt;
&lt;li&gt;🔄 Traffic Control Integration: Seamless API management system integration with APISIX traffic control, authentication, and rate-limiting plugins&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Authentication and Rate Limiting with Apache APISIX Plugins
&lt;/h2&gt;

&lt;p&gt;Apache APISIX provides robust authentication plugins (like OAuth 2.0, JWT, and OIDC) and rate-limiting plugins (such as rate limiting and circuit breakers). These enhance the &lt;code&gt;mcp-bridge&lt;/code&gt; plugin, ensuring secure authentication and traffic control for connected MCP services.&lt;/p&gt;

&lt;h3&gt;
  
  
  Authentication Plugins
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Support for OAuth 2.0, JWT, and OIDC plugins to protect APIs and MCP services.&lt;/li&gt;
&lt;li&gt;Automatic client identity verification during API gateway requests to prevent unauthorized access.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Rate-Limiting Plugins
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Rate Limiting: Restricts each client's request rate to prevent system overload.&lt;/li&gt;
&lt;li&gt;Circuit Breaker: Automatically switches or returns errors to avoid system crashes during high traffic or failures.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Adding Authentication and Rate Limiting to MCP Servers
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsqkpu6g204rzqlbcbmrp.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsqkpu6g204rzqlbcbmrp.webp" alt="Add Authentication and Rate Limiting to MCP Servers" width="800" height="678"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By integrating authentication and rate-limiting plugins with the &lt;code&gt;mcp-bridge&lt;/code&gt; plugin, you can enhance API security and ensure system stability in high-concurrency environments.&lt;/p&gt;

&lt;h2&gt;
  
  
  Roadmap
&lt;/h2&gt;

&lt;p&gt;The current version is a prototype. Future enhancements include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Currently, MCP sessions are not shared across multiple APISIX instances. For multi-node APISIX clusters, proper session persistence configuration on the front-end load balancer is essential to ensure requests from the same client always go to the same APISIX instance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The current MCP SSE connection is loop-driven. While the loop doesn't consume many resources (stdio read/write will be synchronous non-blocking calls), it's not efficient. We plan to connect to a message queue for an event-driven, scalable cluster approach.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The MCP session management module is just a prototype. We intend to abstract an MCP proxy server module to support launching MCP servers within APISIX for advanced scenarios. This proxy server module will be event-driven rather than loop-driven.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;The Apache APISIX &lt;code&gt;mcp-bridge&lt;/code&gt; plugin significantly simplifies the integration of Model Context Protocol (MCP) services with the HTTP API world. It offers a modern streaming interface management approach for traditional services.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>aiops</category>
      <category>mcp</category>
      <category>api</category>
    </item>
    <item>
      <title>APISIX-MCP: Embracing Intelligent API Management with AI + MCP</title>
      <dc:creator>Yilia</dc:creator>
      <pubDate>Wed, 02 Apr 2025 03:03:57 +0000</pubDate>
      <link>https://dev.to/apisix/apisix-mcp-embracing-intelligent-api-management-with-ai-mcp-38j8</link>
      <guid>https://dev.to/apisix/apisix-mcp-embracing-intelligent-api-management-with-ai-mcp-38j8</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This article introduces the MCP protocol and its application in APISIX-MCP. APISIX-MCP simplifies API management through natural language interaction, supporting the creation, updating, and deletion of resources.  &lt;/p&gt;


&lt;h2&gt;
  
  
  Preface
&lt;/h2&gt;
&lt;/blockquote&gt;

&lt;p&gt;With the explosive growth of large-scale AI model applications, many traditional systems are eager to integrate AI capabilities quickly. However, the current landscape of AI tools lacks unified standards, resulting in severe fragmentation. Different models vary in capability and integration methods, creating significant challenges for traditional applications during adoption.  &lt;/p&gt;

&lt;p&gt;Against this backdrop, in late 2024, Anthropic—the company behind the renowned Claude model—introduced the &lt;strong&gt;Model Context Protocol (MCP)&lt;/strong&gt;. MCP positions itself as the &lt;strong&gt;"USB-C interface" for AI applications&lt;/strong&gt;. Just as USB-C standardizes connections for peripherals and accessories, MCP provides a standardized approach for AI models to connect with diverse data sources and tools.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstatic.api7.ai%2Fuploads%2F2025%2F04%2F01%2Fu6Q4dGDZ_apisix-mcp-architecture-new.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstatic.api7.ai%2Fuploads%2F2025%2F04%2F01%2Fu6Q4dGDZ_apisix-mcp-architecture-new.webp" alt="MCP Architecture" width="800" height="524"&gt;&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;Numerous services and applications have already adopted MCP. For example:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub-MCP&lt;/strong&gt; enables natural language code submissions and PR creation.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Figma MCP&lt;/strong&gt; allows AI to generate UI designs directly.
&lt;/li&gt;
&lt;li&gt;With &lt;strong&gt;Browser-tools-MCP&lt;/strong&gt;, tools like Cursor can debug code by interacting with DOM elements and console logs.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The official MCP repository includes implementations for Google Drive, Slack, Git, and various databases. As an open standard, MCP has gained widespread recognition in the AI community, attracting third-party developers who contribute hundreds of new MCP services daily. Anthropic, as the founder, actively drives MCP’s evolution by refining the protocol and educating developers.  &lt;/p&gt;

&lt;h2&gt;
  
  
  About APISIX-MCP
&lt;/h2&gt;

&lt;p&gt;The rise of MCP offers traditional applications a new technical pathway. Leveraging MCP’s standardized integration capabilities, we developed &lt;a href="https://github.com/api7/apisix-mcp" rel="noopener noreferrer"&gt;&lt;strong&gt;APISIX-MCP&lt;/strong&gt;&lt;/a&gt;, which bridges large language models with Apache APISIX’s Admin API through natural language interaction. The current implementation supports the following operations:  &lt;/p&gt;

&lt;h3&gt;
  
  
  General Operations
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;get_resource&lt;/code&gt;: Retrieve resources by type (routes, services, upstreams, etc.).
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;delete_resource&lt;/code&gt;: Delete resources by ID.
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  API Resource Management
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;create_route&lt;/code&gt;/&lt;code&gt;update_route&lt;/code&gt;/&lt;code&gt;delete_route&lt;/code&gt;: Manage routes.
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;create_service&lt;/code&gt;/&lt;code&gt;update_service&lt;/code&gt;/&lt;code&gt;delete_service&lt;/code&gt;: Manage services.
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;create_upstream&lt;/code&gt;/&lt;code&gt;update_upstream&lt;/code&gt;/&lt;code&gt;delete_upstream&lt;/code&gt;: Manage upstreams.
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;create_ssl&lt;/code&gt;/&lt;code&gt;update_ssl&lt;/code&gt;/&lt;code&gt;delete_ssl&lt;/code&gt;: Manage SSL certificates.
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;create_or_update_proto&lt;/code&gt;: Manage Protobuf definitions.
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;create_or_update_stream_route&lt;/code&gt;: Manage stream routes.
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Plugin Operations
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;get_all_plugin_names&lt;/code&gt;: List all available plugins.
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;get_plugin_info&lt;/code&gt;/&lt;code&gt;get_plugins_by_type&lt;/code&gt;/&lt;code&gt;get_plugin_schema&lt;/code&gt;: Fetch plugin configurations.
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;create_plugin_config&lt;/code&gt;/&lt;code&gt;update_plugin_config&lt;/code&gt;: Manage plugin configurations.
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;create_global_rule&lt;/code&gt;/&lt;code&gt;update_global_rule&lt;/code&gt;: Manage global plugin rules.
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;get_plugin_metadata&lt;/code&gt;/&lt;code&gt;create_or_update_plugin_metadata&lt;/code&gt;/&lt;code&gt;delete_plugin_metadata&lt;/code&gt;: Manage plugin metadata.
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Security Configuration
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;get_secret_by_id&lt;/code&gt;/&lt;code&gt;create_secret&lt;/code&gt;/&lt;code&gt;update_secret&lt;/code&gt;: Manage secrets.
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;create_or_update_consumer&lt;/code&gt;/&lt;code&gt;delete_consumer&lt;/code&gt;: Manage consumers.
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;get_credential&lt;/code&gt;/&lt;code&gt;create_or_update_credential&lt;/code&gt;/&lt;code&gt;delete_credential&lt;/code&gt;: Manage consumer credentials.
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;create_consumer_group&lt;/code&gt;/&lt;code&gt;delete_consumer_group&lt;/code&gt;: Manage consumer groups.
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to Use APISIX-MCP
&lt;/h2&gt;

&lt;p&gt;APISIX-MCP is now open-sourced and available on &lt;a href="https://www.npmjs.com/package/apisix-mcp" rel="noopener noreferrer"&gt;npm&lt;/a&gt; and &lt;a href="https://github.com/api7/apisix-mcp" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;. It can be configured via any MCP-compatible AI client, such as Claude Desktop, Cursor, or the Cline plugin for VSCode.  &lt;/p&gt;

&lt;p&gt;Below is a step-by-step guide using &lt;strong&gt;Cursor&lt;/strong&gt;:  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open Cursor, click the settings icon, and navigate to the settings page.
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstatic.api7.ai%2Fuploads%2F2025%2F04%2F01%2FOCQcecuQ_apisix-mcp-2.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstatic.api7.ai%2Fuploads%2F2025%2F04%2F01%2FOCQcecuQ_apisix-mcp-2.webp" alt="Configure cursor for APISIX-MCP" width="800" height="327"&gt;&lt;/a&gt;  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click &lt;strong&gt;"Add new global MCP server"&lt;/strong&gt; to edit the &lt;code&gt;mcp.json&lt;/code&gt; configuration file:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
       &lt;/span&gt;&lt;span class="nl"&gt;"apisix-mcp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
         &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
         &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"apisix-mcp"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
         &lt;/span&gt;&lt;span class="nl"&gt;"env"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
           &lt;/span&gt;&lt;span class="nl"&gt;"APISIX_SERVER_HOST"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"your-apisix-server-host"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
           &lt;/span&gt;&lt;span class="nl"&gt;"APISIX_ADMIN_API_PORT"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"your-apisix-admin-api-port"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
           &lt;/span&gt;&lt;span class="nl"&gt;"APISIX_ADMIN_API_PREFIX"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"your-apisix-admin-api-prefix"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
           &lt;/span&gt;&lt;span class="nl"&gt;"APISIX_ADMIN_KEY"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"your-apisix-api-key"&lt;/span&gt;&lt;span class="w"&gt;
         &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
       &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;code&gt;mcpServers&lt;/code&gt; field of the configuration file, add a service &lt;code&gt;apisix-mcp&lt;/code&gt;, which can be changed. Then configure the commands for running the MCP service.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;command&lt;/code&gt;&lt;/strong&gt;: &lt;code&gt;npx&lt;/code&gt; (Node.js package executor).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;args&lt;/code&gt;&lt;/strong&gt;: &lt;code&gt;-y&lt;/code&gt; (auto-install dependencies) and &lt;code&gt;apisix-mcp&lt;/code&gt; (package name).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;env&lt;/code&gt;&lt;/strong&gt;: Customize APISIX connection settings (defaults below):
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the &lt;code&gt;env&lt;/code&gt; field, you can specify the APISIX service access address, Admin API port, prefix, and authentication key. These environment variables have default values, so if you start APISIX without any custom configuration, you can omit the &lt;code&gt;env&lt;/code&gt; field entirely. The default values for each variable are as follows:&lt;/p&gt;

&lt;p&gt;| Variable                  | Description                          | Default Value               |&lt;br&gt;&lt;br&gt;
   |---------------------------|--------------------------------------|-----------------------------|&lt;br&gt;&lt;br&gt;
   | &lt;code&gt;APISIX_SERVER_HOST&lt;/code&gt;      | APISIX server host                   | &lt;code&gt;http://127.0.0.1&lt;/code&gt;          |&lt;br&gt;&lt;br&gt;
   | &lt;code&gt;APISIX_ADMIN_API_PORT&lt;/code&gt;   | Admin API port                       | &lt;code&gt;9180&lt;/code&gt;                      |&lt;br&gt;&lt;br&gt;
   | &lt;code&gt;APISIX_ADMIN_API_PREFIX&lt;/code&gt; | Admin API prefix                     | &lt;code&gt;/apisix/admin&lt;/code&gt;             |&lt;br&gt;&lt;br&gt;
   | &lt;code&gt;APISIX_ADMIN_KEY&lt;/code&gt;        | Admin API authentication key         | &lt;code&gt;edd1c9f034335f136f87ad84b625c8f1&lt;/code&gt; |  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Upon successful configuration, the MCP Servers list will show a green indicator for &lt;code&gt;apisix-mcp&lt;/code&gt;, along with available tools.
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstatic.api7.ai%2Fuploads%2F2025%2F04%2F01%2FtoaXLc3n_apisix-mcp-3.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstatic.api7.ai%2Fuploads%2F2025%2F04%2F01%2FtoaXLc3n_apisix-mcp-3.webp" alt="Successful Configuration" width="" height=""&gt;&lt;/a&gt;  &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: If setup fails, refer to the &lt;a href="https://github.com/api7/apisix-mcp" rel="noopener noreferrer"&gt;APISIX-MCP GitHub&lt;/a&gt; documentation for manual builds.  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In the chat panel, select &lt;strong&gt;Agent&lt;/strong&gt; mode and choose a model (e.g., Claude Sonnet 3.5/3.7 or GPT-4o).
&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstatic.api7.ai%2Fuploads%2F2025%2F04%2F01%2Fg9v91DIf_apisix-mcp-4.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstatic.api7.ai%2Fuploads%2F2025%2F04%2F01%2Fg9v91DIf_apisix-mcp-4.webp" alt="Select Agent Models" width="800" height="139"&gt;&lt;/a&gt;  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Next, we can enter relevant operational commands to verify if the MCP service is functioning correctly. Following the workflow in APISIX's Getting Started documentation, we input the following into the dialog box and send the message:
&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Help me create a route with path &lt;code&gt;/api&lt;/code&gt; for accessing &lt;code&gt;https://httpbin.org&lt;/code&gt; upstream, with CORS and rate-limiting plugins. Print the route details after configuration."&lt;/em&gt;  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Next, in Cursor, you will see a process similar to the MCP tool invocation demonstrated in the video below. Due to the inherent randomness of large AI model responses, the exact operations performed may vary from the example shown.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;
     &lt;br&gt;&lt;br&gt;
     &lt;/p&gt;

&lt;p&gt;Here, the auto-execution mode (YOLO Mode) is enabled, allowing Cursor to automatically invoke all tools in the MCP server. From the video, we can observe the AI performing the following operations based on our requirements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Analyzing the plugins we need to configure, then calling &lt;code&gt;get_plugins_list&lt;/code&gt; to retrieve all plugin names&lt;/li&gt;
&lt;li&gt;Invoking &lt;code&gt;get_plugin_schema&lt;/code&gt; to examine detailed configuration information for different plugins&lt;/li&gt;
&lt;li&gt;Calling &lt;code&gt;create_route&lt;/code&gt; to create the route&lt;/li&gt;
&lt;li&gt;Using &lt;code&gt;update_route&lt;/code&gt; to add the previously queried plugin configurations to the route&lt;/li&gt;
&lt;li&gt;Executing &lt;code&gt;get_route&lt;/code&gt; to verify whether the route was successfully configured and if the configuration is correct&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;The resulting route configuration includes:
&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Route ID&lt;/strong&gt;: &lt;code&gt;httpbin&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Path&lt;/strong&gt;: &lt;code&gt;/api/*&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Methods&lt;/strong&gt;: &lt;code&gt;GET&lt;/code&gt;, &lt;code&gt;POST&lt;/code&gt;, &lt;code&gt;PUT&lt;/code&gt;, &lt;code&gt;DELETE&lt;/code&gt;, &lt;code&gt;PATCH&lt;/code&gt;, &lt;code&gt;HEAD&lt;/code&gt;, &lt;code&gt;OPTIONS&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;CORS Plugin&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;allow_origins: *
allow_methods: *
allow_headers: *
expose_headers: X-Custom-Header
max_age: 3600
allow_credential: false
&lt;/code&gt;&lt;/pre&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;limit-count Plugin&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;count: 100
time_window: 60
key: remote_addr
rejected_code: 429
policy: local
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Upstream&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type: roundrobin (load balancing strategy using round-robin)  
upstream node: httpbin.org:443 (backend service address)  
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Advantages of AI-Driven Operations
&lt;/h2&gt;

&lt;p&gt;In the above process, we accomplished the creation of a route configured with CORS and rate-limiting through just one round of natural language interaction with AI. Compared to manual route configuration, leveraging AI offers several distinct advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reduced Cognitive Load&lt;/strong&gt;: Eliminates manual documentation lookup and parameter memorization.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automated Workflows&lt;/strong&gt;: AI decomposes tasks (e.g., plugin setup → route creation) without human intervention.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Closed-Loop Validation&lt;/strong&gt;: Auto-verification ensures correctness.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Iterative Optimization&lt;/strong&gt;: Continuous dialogue refines configurations.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This interaction model transforms complex configuration processes into natural conversational experiences while maintaining accuracy and verifiability. These capabilities are achieved through the MCP protocol's semantic parsing of requirements, intelligent tool invocation, and final execution via Admin API.&lt;/p&gt;

&lt;p&gt;It's important to note that APISIX-MCP isn't designed to completely replace manual configuration, but rather to optimize efficiency for high-frequency operations. Its value shines particularly in configuration debugging and rapid validation scenarios, creating effective complementarity with traditional management approaches. As the MCP ecosystem continues to evolve, we can anticipate deeper integration of such tools in API management, promising more sophisticated capabilities.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;MCP enables intelligent operations for complex API systems. APISIX-MCP lowers the barrier to Apache APISIX adoption, with future plans for AI-traffic-specific plugins. The fusion of AI and API management promises smarter, more efficient infrastructure governance. &lt;/p&gt;

</description>
      <category>ai</category>
      <category>api</category>
      <category>aiops</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>What Is an AI Gateway: Differences from API Gateway</title>
      <dc:creator>Yilia</dc:creator>
      <pubDate>Fri, 28 Mar 2025 03:26:32 +0000</pubDate>
      <link>https://dev.to/apisix/what-is-an-ai-gateway-differences-from-api-gateway-1c63</link>
      <guid>https://dev.to/apisix/what-is-an-ai-gateway-differences-from-api-gateway-1c63</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;"The future isn't AI gateways—it's API gateways that speak AI."_ This blog explores AI gateways, their differences from API gateways, and why evolved solutions like &lt;a href="https://apisix.apache.org/blog/2025/02/24/apisix-ai-gateway-features/" rel="noopener noreferrer"&gt;Apache APISIX AI Gateway&lt;/a&gt; are shaping the future.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What Is an AI Gateway? Why Did It Arise in the AI Era?
&lt;/h2&gt;

&lt;p&gt;The AI era has ushered in unprecedented complexity in deploying and managing artificial intelligence (AI) models. Organizations now juggle multiple models—from computer vision to large language models (LLMs)—across diverse environments (cloud, edge, hybrid). Traditional API gateways, designed for general-purpose data traffic, often fall short in addressing the unique challenges posed by AI workloads. This is where &lt;strong&gt;AI gateways&lt;/strong&gt; emerge as critical middleware, acting as a unified control plane for routing, securing, and optimizing AI workloads.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Rise of AI Gateways
&lt;/h2&gt;

&lt;p&gt;The proliferation of &lt;strong&gt;generative AI and LLMs (Large Language Models)&lt;/strong&gt; has introduced unique challenges:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Token Consumption&lt;/strong&gt;: LLMs process requests in tokens, requiring granular tracking for cost and performance optimization.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stream-Type Requests&lt;/strong&gt;: AI agents often generate real-time, streaming responses (e.g., ChatGPT's incremental output), demanding low-latency handling.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tool Integration&lt;/strong&gt;: AI systems increasingly rely on external data sources and APIs (e.g., retrieving live weather data or CRM records).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;According to a 2023 Gartner report, over 75% of enterprises now use AI models in production, driving demand for specialized infrastructure. Traditional API gateways, designed for RESTful APIs and static request-response cycles, struggle with these AI-specific demands. Enter the &lt;a href="https://apisix.apache.org/blog/2025/03/06/what-is-an-ai-gateway/" rel="noopener noreferrer"&gt;AI gateway&lt;/a&gt;—a purpose-built solution to manage AI-native traffic.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI Agents vs. Traditional Devices: Why Stream-Type Requests Demand Specialized Handling
&lt;/h2&gt;

&lt;p&gt;AI agents (e.g., chatbots, coding assistants) generate fundamentally different traffic patterns than traditional clients:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Traditional API Requests&lt;/th&gt;
&lt;th&gt;AI Agent Requests&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Request Type&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Synchronous (HTTP GET/POST)&lt;/td&gt;
&lt;td&gt;Asynchronous, streaming (SSE)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Latency&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Milliseconds&lt;/td&gt;
&lt;td&gt;Seconds-minutes (for chunks)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Billing&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Per API call&lt;/td&gt;
&lt;td&gt;Per token or compute time&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Failure Modes&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Timeouts, HTTP errors&lt;/td&gt;
&lt;td&gt;Partial completions, hallucinations&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  The Stream-Type Challenge
&lt;/h3&gt;

&lt;p&gt;When an AI agent requests a poem generated by GPT-4, the response is streamed incrementally. Traditional API gateways, built for atomic requests, struggle with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Partial Responses&lt;/strong&gt;: Aggregating chunks into a coherent audit log.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Token Accounting&lt;/strong&gt;: Accurately counting tokens across streaming chunks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real-Time Observability&lt;/strong&gt;: Monitoring latency per token or detecting drift in response quality.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Many purpose-built AI gateways lack distributed tracing, forcing engineers to cobble together metrics. In contrast, API gateways like &lt;a href="https://github.com/apache/apisix" rel="noopener noreferrer"&gt;Apache APISIX&lt;/a&gt; provide built-in integrations with Prometheus and Grafana, enabling token-level dashboards.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two Types of AI Gateways: Purpose-Built vs. API Gateway Evolutions
&lt;/h2&gt;

&lt;p&gt;Today's AI gateways fall into two categories:&lt;/p&gt;

&lt;h3&gt;
  
  
  Specific Purpose-Built AI Gateways
&lt;/h3&gt;

&lt;p&gt;These are built from the ground up to address AI use cases. Startups like &lt;strong&gt;PromptLayer&lt;/strong&gt; and &lt;strong&gt;LangChain&lt;/strong&gt; offer solutions focused on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Token-Based Rate Limiting&lt;/strong&gt;: Enforcing usage quotas based on tokens instead of API calls.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prompt Engineering Tools&lt;/strong&gt;: Allowing developers to test and optimize prompts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI-Specific Analytics&lt;/strong&gt;: Tracking metrics like response hallucination rates or token costs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt;: OpenAI's API uses token-based pricing ($0.06 per 1K tokens for GPT-4), requiring gateways to meter usage precisely. A dedicated AI gateway might integrate token counters directly into its throttling logic.&lt;/p&gt;

&lt;p&gt;However, these gateways often lack the &lt;strong&gt;observability&lt;/strong&gt; and &lt;strong&gt;scalability&lt;/strong&gt; of mature API management platforms. For instance, measuring token consumption across distributed microservices can lead to inaccuracies if the gateway lacks distributed tracing capabilities.&lt;/p&gt;

&lt;h3&gt;
  
  
  Evolved AI Gateways from API Gateways
&lt;/h3&gt;

&lt;p&gt;Established API gateways like Kong, &lt;strong&gt;&lt;a href="https://apisix.apache.org/" rel="noopener noreferrer"&gt;Apache APISIX&lt;/a&gt;&lt;/strong&gt;, and AWS API Gateway are adapting to AI workloads by adding:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Streaming Support&lt;/strong&gt;: Handling Server-Sent Events (SSE) and WebSockets for real-time AI responses.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Token-Aware Plugins&lt;/strong&gt;: Extending rate-limiting plugins to track tokens.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LLM Orchestration&lt;/strong&gt;: Managing multiple AI models (e.g., routing requests to cost-effective models like Mistral-7B for simple tasks).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mature API gateways leverage decades of experience in security (OAuth, JWT), scalability (load balancing), and monetization—features often missing in AI-first solutions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Evolved AI Gateways Are Winning Long-Term
&lt;/h2&gt;

&lt;p&gt;While purpose-built AI gateways excel in niche scenarios, evolved API gateways are becoming the default choice for three reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Cost Efficiency&lt;/strong&gt;: Maintaining separate gateways for AI and non-AI traffic doubles operational overhead. Converged systems reduce costs by 30–50% (Gartner, 2023).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexibility&lt;/strong&gt;: Enterprises can't predict which AI models will dominate. Platforms like Apache APISIX allow seamless integration of new LLMs without rearchitecting.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Future-Proofing&lt;/strong&gt;: As AI becomes embedded in all apps (e.g., AI-powered search in e-commerce), gateways must handle hybrid workloads.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Model Context Protocol (MCP): Bridging AI Assistants and External Tools
&lt;/h2&gt;

&lt;p&gt;To connect AI agents with external data and APIs, the &lt;strong&gt;&lt;a href="https://github.com/modelcontextprotocol" rel="noopener noreferrer"&gt;Model Context Protocol (MCP)&lt;/a&gt;&lt;/strong&gt; has emerged as a standardized framework. MCP defines how AI models request and consume external resources, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Data Sources&lt;/strong&gt;: SQL databases, vector stores (e.g., Pinecone).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;APIs&lt;/strong&gt;: CRM systems, payment gateways.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tools&lt;/strong&gt;: Code interpreters, and image generators.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How MCP Works
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Context Injection&lt;/strong&gt;: An AI assistant sends a request with a context header specifying required tools (&lt;code&gt;MCP-Context: weather_api, crm&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gateway Routing&lt;/strong&gt;: The AI gateway validates permissions, injects API keys, and routes the request to relevant services.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Response Synthesis&lt;/strong&gt;: The gateway aggregates API responses (e.g., weather data + CRM contacts) and feeds them back to the AI model.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt;: A user asks, "Email our top client in NYC about today's weather." The AI gateway uses MCP to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fetch the top client from Salesforce.&lt;/li&gt;
&lt;li&gt;Retrieve NYC weather from OpenWeatherMap.&lt;/li&gt;
&lt;li&gt;Pass this context to GPT-4 to draft the email.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Benefits of MCP
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Security&lt;/strong&gt;: Centralized policy enforcement (e.g., masking PII in CRM responses).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost Control&lt;/strong&gt;: Caching frequent data requests (e.g., product catalogs).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interoperability&lt;/strong&gt;: Standardizing AI-to-API communication across vendors.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Future of AI Gateways: Convergence with API Monetization
&lt;/h2&gt;

&lt;p&gt;As AI adoption matures, two trends will shape AI gateways:&lt;/p&gt;

&lt;h3&gt;
  
  
  Trend 1: The Decline of Standalone AI Gateways
&lt;/h3&gt;

&lt;p&gt;Niche AI gateways will struggle to compete with evolved API gateways that offer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Unified Governance&lt;/strong&gt;: One platform for REST, GraphQL, and AI APIs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monetization Models&lt;/strong&gt;: Token-based billing, subscription tiers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enterprise Features&lt;/strong&gt;: Role-based access control (RBAC), audit logging.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Under such a trend, AI traffic will flow through traditional API gateways enhanced with AI capabilities.&lt;/p&gt;

&lt;h3&gt;
  
  
  Trend 2: API Gateways as AI Orchestrators
&lt;/h3&gt;

&lt;p&gt;Future API gateways will act as AI orchestrators, handling:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Model Routing&lt;/strong&gt;: Directing requests to optimal models based on cost, latency, or accuracy.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hybrid Workflows&lt;/strong&gt;: Blending AI and non-AI services (e.g., validating a GPT-4 response against a database).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Token Analytics&lt;/strong&gt;: Real-time dashboards showing token spend by team or project.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Bottom Line
&lt;/h3&gt;

&lt;p&gt;In the future, the line between "AI gateway" and "API gateway" will blur. But the unchangeable fact is APIs are the basics of API gateways and AI gateways. Companies that adopt AI-ready API gateways today will gain a strategic edge in scalability, cost control, and innovation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion: Embracing AI-API Convergence
&lt;/h2&gt;

&lt;p&gt;AI gateways are not a replacement but an evolution of API gateways. While purpose-built solutions address immediate LLM challenges, their limitations in observability and scalability make them transitional. Established API gateways—enhanced with streaming support, token-aware plugins, and MCP—are poised to dominate.&lt;/p&gt;

&lt;p&gt;Solutions like &lt;strong&gt;&lt;a href="https://apisix.apache.org/blog/2025/02/24/apisix-ai-gateway-features/" rel="noopener noreferrer"&gt;Apache APISIX AI Gateway&lt;/a&gt;&lt;/strong&gt; exemplify this shift, blending AI-native features with battle-tested API management. As AI permeates every app, enterprises must choose platforms that scale beyond siloed use cases. The winners? Adaptable, extensible tools that speak both API and AI.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>api</category>
      <category>apigateway</category>
      <category>openai</category>
    </item>
  </channel>
</rss>
