{"id":24035,"date":"2024-03-21T12:56:35","date_gmt":"2024-03-21T11:56:35","guid":{"rendered":"https:\/\/www.proxym-group.com\/fr\/?p=24035"},"modified":"2025-01-23T10:59:59","modified_gmt":"2025-01-23T09:59:59","slug":"selecting-the-right-open-source-api-gateway-technology","status":"publish","type":"post","link":"https:\/\/www.proxym-group.com\/fr\/fr\/2024\/03\/selecting-the-right-open-source-api-gateway-technology\/","title":{"rendered":"Selecting the right open-source API Gateway technology"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-post\" data-elementor-id=\"24035\" class=\"elementor elementor-24035\" data-elementor-post-type=\"post\">\n\t\t\t\t\t\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-c042fc1 elementor-section-height-min-height elementor-section-boxed elementor-section-height-default elementor-section-items-middle\" data-id=\"c042fc1\" data-element_type=\"section\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t\t\t\t<div class=\"elementor-background-overlay\"><\/div>\n\t\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-2fc46dc\" data-id=\"2fc46dc\" data-element_type=\"column\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t\t\t<div class=\"elementor-element elementor-element-e2e3b61 elementor-widget__width-initial elementor-widget elementor-widget-heading\" data-id=\"e2e3b61\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t<style>\/*! elementor - v3.17.0 - 01-11-2023 *\/\n.elementor-heading-title{padding:0;margin:0;line-height:1}.elementor-widget-heading .elementor-heading-title[class*=elementor-size-]>a{color:inherit;font-size:inherit;line-height:inherit}.elementor-widget-heading .elementor-heading-title.elementor-size-small{font-size:15px}.elementor-widget-heading .elementor-heading-title.elementor-size-medium{font-size:19px}.elementor-widget-heading .elementor-heading-title.elementor-size-large{font-size:29px}.elementor-widget-heading .elementor-heading-title.elementor-size-xl{font-size:39px}.elementor-widget-heading .elementor-heading-title.elementor-size-xxl{font-size:59px}<\/style><h2 class=\"elementor-heading-title elementor-size-default\">Selecting the right open-source API Gateway technology<\/h2>\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-6cb8dd6 elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"6cb8dd6\" data-element_type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-9d41179\" data-id=\"9d41179\" data-element_type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t\t\t<div class=\"elementor-element elementor-element-58ac3f5 elementor-widget elementor-widget-image\" data-id=\"58ac3f5\" data-element_type=\"widget\" data-widget_type=\"image.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t<style>\/*! elementor - v3.17.0 - 01-11-2023 *\/\n.elementor-widget-image{text-align:center}.elementor-widget-image a{display:inline-block}.elementor-widget-image a img[src$=\".svg\"]{width:48px}.elementor-widget-image img{vertical-align:middle;display:inline-block}<\/style>\t\t\t\t\t\t\t\t\t\t\t\t<img decoding=\"async\" loading=\"lazy\" width=\"800\" height=\"373\" src=\"https:\/\/www.proxym-group.com\/wp-content\/uploads\/sites\/8\/2025\/01\/open-source-API-1.jpg\" class=\"attachment-large size-large wp-image-24036\" alt=\"\" srcset=\"https:\/\/www.proxym-group.com\/wp-content\/uploads\/sites\/8\/2025\/01\/open-source-API-1.jpg 848w, https:\/\/www.proxym-group.com\/wp-content\/uploads\/sites\/8\/2025\/01\/open-source-API-1-300x140.jpg 300w, https:\/\/www.proxym-group.com\/wp-content\/uploads\/sites\/8\/2025\/01\/open-source-API-1-768x358.jpg 768w, https:\/\/www.proxym-group.com\/wp-content\/uploads\/sites\/8\/2025\/01\/open-source-API-1-570x266.jpg 570w, https:\/\/www.proxym-group.com\/wp-content\/uploads\/sites\/8\/2025\/01\/open-source-API-1-270x126.jpg 270w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/>\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-08e8339 elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"08e8339\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t<style>\/*! elementor - v3.17.0 - 01-11-2023 *\/\n.elementor-widget-text-editor.elementor-drop-cap-view-stacked .elementor-drop-cap{background-color:#69727d;color:#fff}.elementor-widget-text-editor.elementor-drop-cap-view-framed .elementor-drop-cap{color:#69727d;border:3px solid;background-color:transparent}.elementor-widget-text-editor:not(.elementor-drop-cap-view-default) .elementor-drop-cap{margin-top:8px}.elementor-widget-text-editor:not(.elementor-drop-cap-view-default) .elementor-drop-cap-letter{width:1em;height:1em}.elementor-widget-text-editor .elementor-drop-cap{float:left;text-align:center;line-height:1;font-size:50px}.elementor-widget-text-editor .elementor-drop-cap-letter{display:inline-block}<\/style>\t\t\t\t<p>I was tasked with setting up an API gateway to protect the APIs of a backend server. The requirements were divided into two types: standard requirements and custom requirements. While any API Gateway should address the standard requirements using various plugins, meeting the custom requirements might involve additional engineering and analysis. This article aims to assist in choosing the appropriate API Gateway technology for securing your backend workloads.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-6910ac7 elementor-widget elementor-widget-heading\" data-id=\"6910ac7\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t<h3 class=\"elementor-heading-title elementor-size-default\">The requirements<\/h3>\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-6422880 elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"6422880\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<p id=\"aac1\" class=\"pw-post-body-paragraph mk ml gu mm b mn og mp mq mr oh mt mu mv oi mx my mz oj nb nc nd ok nf ng nh gn bj\" data-selectable-paragraph=\"\">The Backend server acts as an OAuth2\/OIDC resource server and in the front end we had an SPA application based on React JS.<br \/>Our expectation from the API Gateway was :<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<section class=\"elementor-section elementor-inner-section elementor-element elementor-element-1e09622 elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"1e09622\" data-element_type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-inner-column elementor-element elementor-element-dfc3134\" data-id=\"dfc3134\" data-element_type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t\t\t<div class=\"elementor-element elementor-element-94be98a elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"94be98a\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<p><span class=\"ui-provider a b c d e f g h i j k l m n o p q r s t u v w x y z ab ac ae af ag ah ai aj ak\" dir=\"ltr\"><strong>1- OIDC\/OAuth2 client:<\/strong> The API Gateway must act as an OAuth2 confidential client. It should manage the authentication flow and maintain the Access, ID, and Refresh tokens<\/span><\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-14556eb elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"14556eb\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<p><strong><span class=\"ui-provider a b c d e f g h i j k l m n o p q r s t u v w x y z ab ac ae af ag ah ai aj ak\" dir=\"ltr\">2- <\/span><\/strong><strong>Session management:<\/strong> Tokens acquired as part of the OIDC login flow should be maintained in a web session.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-3f794b7 elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"3f794b7\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<p><strong>3- Token relay<\/strong>: Whenever a new request comes from the front-end applications, the access token should be extracted, and then added to the request sent to the backend server.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-4926b2c elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"4926b2c\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<p><strong>4- Token refreshing:<\/strong> expiring access tokens must be refreshed using the cache refresh token automatically by the API Gateway.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-09aa8af elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"09aa8af\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<p data-selectable-paragraph=\"\">In a few words, we expect the Gateway to behave like any traditional OAuth2 client.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<div class=\"elementor-element elementor-element-5175dc2 elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"5175dc2\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<p data-selectable-paragraph=\"\">The above requirements are pretty standard because they are around OIDC client implementation. To make things more complicated, here are extra requirements that require specific customizations :<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-24b764f elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"24b764f\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<ol class=\"\"><li id=\"fd53\" class=\"mk ml gu mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh ol om on bj\" data-selectable-paragraph=\"\">User Agent parsing and Mobile vs Web channel detection. This logic happens based on different attributes including HTTP requests.<\/li><li id=\"1cea\" class=\"mk ml gu mm b mn oo mp mq mr op mt mu mv oq mx my mz or nb nc nd os nf ng nh ol om on bj\" data-selectable-paragraph=\"\">Handle differences in login flow between mobile and web. Mobile applications perform login in a separate browser window while leaving the app screens below the browser window. The web application performs a full browser redirect.<\/li><li id=\"1d9c\" class=\"mk ml gu mm b mn oo mp mq mr op mt mu mv oq mx my mz or nb nc nd os nf ng nh ol om on bj\" data-selectable-paragraph=\"\">Sync from the backend the list of active mobile versions and block the requests coming from disabled mobile versions<\/li><li id=\"5198\" class=\"mk ml gu mm b mn oo mp mq mr op mt mu mv oq mx my mz or nb nc nd os nf ng nh ol om on bj\" data-selectable-paragraph=\"\">Implement a custom \u201cLogin with Fingerprint\u201d flow that is based on OAuth2 refresh tokens.<\/li><li id=\"3270\" class=\"mk ml gu mm b mn oo mp mq mr op mt mu mv oq mx my mz or nb nc nd os nf ng nh ol om on bj\" data-selectable-paragraph=\"\">Other: send usage analytics, observability, tracing, etc.<\/li><\/ol>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-4ba7787 elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"4ba7787\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<p id=\"f041\" class=\"pw-post-body-paragraph mk ml gu mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gn bj\" data-selectable-paragraph=\"\">When selecting an API Gateway technology, we have many options. We are choosing a free and open licensed API Gateway. This eliminates choices like Kong and Tyk and other similar tools.<\/p><p id=\"0078\" class=\"pw-post-body-paragraph mk ml gu mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gn bj\" data-selectable-paragraph=\"\">That being said, two potential technologies are still matching our selection criteria: OpenResty-based gateways and Java-based API gateways.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-b30aa7b elementor-widget elementor-widget-heading\" data-id=\"b30aa7b\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t<h3 class=\"elementor-heading-title elementor-size-default\">Available technologies<\/h3>\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-6147892 elementor-widget elementor-widget-text-editor\" data-id=\"6147892\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<p><span style=\"color: #16176f;\">OpenResty based Technology\u00a0<\/span><\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<section class=\"elementor-section elementor-inner-section elementor-element elementor-element-36116c2 elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"36116c2\" data-element_type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-inner-column elementor-element elementor-element-4446942\" data-id=\"4446942\" data-element_type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t\t\t<div class=\"elementor-element elementor-element-6086662 elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"6086662\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<p>OpenResty is a kind of platform that lets you program on top of Nginx. It uses Lua scripts as a scripting language. These scripts are Just in Time compiled thanks to the\u00a0<span style=\"color: #333399;\"><a class=\"af pi\" style=\"color: #333399;\" href=\"https:\/\/luajit.org\/\" target=\"_blank\" rel=\"noopener ugc nofollow\">LuaJIT<\/a><\/span>\u00a0compiler. OpenResty was the engine behind many API gateway technologies such as:<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-cca78fd elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"cca78fd\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<p><strong class=\"mm gv\">1- Kong<\/strong>: Kong is one of the most popular API gateway solutions built on top of OpenResty. It provides various features like routing, security, analytics, and transformations. Kong can be extended using Lua for custom logic and plugins.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-3625733 elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"3625733\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<p><strong class=\"mm gv\">2- 3scale (Red Hat)<\/strong>: 3scale, now part of Red Hat, offers an API management platform that includes an API gateway. While not explicitly based on OpenResty, it does allow you to use Nginx as a component for its API gateway functionality.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-b8dbe68 elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"b8dbe68\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<p><strong class=\"mm gv\">3- <\/strong><strong class=\"mm gv\">APISIX:<\/strong>\u00a0APISIX is an open-source API gateway that is based on OpenResty and comes with prebuilt plugins and a dashboard.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-4dcb7d8 elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"4dcb7d8\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<p>Speaking about Lua, it\u2019s a lightweight, embeddable scripting language. It\u2019s very common to encounter Lua in Proxy-based platforms such as OpenResty, Envoy Proxy, and others. The reasons behind such a choice:<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-ff72201 elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"ff72201\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<p><strong class=\"mm gv\">1- <\/strong><strong class=\"mm gv\">Performance<\/strong>: Lua is known for its high performance, particularly when used with LuaJIT (Just-In-Time compiler). This makes it well-suited for situations where low latency and high throughput are critical, such as handling API requests in real time.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-8040126 elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"8040126\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<p><strong class=\"mm gv\">2- <\/strong><strong class=\"mm gv\">Embeddable<\/strong>: Lua is designed to be easily embedded into other programming languages and applications.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-35da6a9 elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"35da6a9\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<p><strong class=\"mm gv\">3- <\/strong><strong class=\"mm gv\">Lightweight<\/strong>: Lua is a lightweight language, both in terms of its implementation and its resource requirements. That makes it an excellent choice for systems where memory usage and efficiency are important considerations.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-e8b052b elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"e8b052b\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<p><strong class=\"mm gv\">4- <\/strong><strong class=\"mm gv\">Safety and Isolation<\/strong>: Lua provides a level of isolation and sandboxing, which can be valuable for ensuring that custom scripts or logic do not adversely affect the stability and security of the underlying system. That is important in the context of API Gateways.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-5d13e30 elementor-widget elementor-widget-text-editor\" data-id=\"5d13e30\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<p><span style=\"color: #16176f;\">Java-based API Gateways :<\/span><\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-2c4ecd3 elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"2c4ecd3\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"gn go gp gq gr\"><div class=\"ab ca\"><div class=\"ch bg fz ga gb gc\"><p id=\"b23d\" class=\"pw-post-body-paragraph mk ml gu mm b mn og mp mq mr oh mt mu mv oi mx my mz oj nb nc nd ok nf ng nh gn bj\" data-selectable-paragraph=\"\">When talking about Java-based API Gateways 2 technologies come to our minds:<\/p><p id=\"efad\" class=\"pw-post-body-paragraph mk ml gu mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gn bj\" data-selectable-paragraph=\"\"><strong class=\"mm gv\">Netflix Zuul:\u00a0<\/strong>Netflix Zuul is an open-source API gateway and edge service that is part of Netflix\u2019s larger set of open-source projects known as Netflix OSS (Open Source Software). Zuul is designed to handle various tasks related to routing, filtering, and load balancing for microservices and web applications. It\u2019s primarily used for building scalable and secure API gateways in a microservices architecture.<\/p><p id=\"e5ae\" class=\"pw-post-body-paragraph mk ml gu mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gn bj\" data-selectable-paragraph=\"\"><strong class=\"mm gv\">Spring Cloud Gateway:\u00a0<\/strong>Spring Cloud Gateway is an open-source, developer-friendly API gateway built on top of the Spring Framework and the Spring Boot. It provides a flexible and powerful way to route and filter incoming HTTP requests to various microservices in a Spring-based microservices architecture. Spring Cloud Gateway is part of the larger Spring Cloud ecosystem, which aims to simplify the development of distributed systems and microservices.<\/p><\/div><\/div><\/div>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-c8ddf97 elementor-widget-divider--view-line elementor-widget elementor-widget-divider\" data-id=\"c8ddf97\" data-element_type=\"widget\" data-widget_type=\"divider.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t<style>\/*! elementor - v3.17.0 - 01-11-2023 *\/\n.elementor-widget-divider{--divider-border-style:none;--divider-border-width:1px;--divider-color:#0c0d0e;--divider-icon-size:20px;--divider-element-spacing:10px;--divider-pattern-height:24px;--divider-pattern-size:20px;--divider-pattern-url:none;--divider-pattern-repeat:repeat-x}.elementor-widget-divider .elementor-divider{display:flex}.elementor-widget-divider .elementor-divider__text{font-size:15px;line-height:1;max-width:95%}.elementor-widget-divider .elementor-divider__element{margin:0 var(--divider-element-spacing);flex-shrink:0}.elementor-widget-divider .elementor-icon{font-size:var(--divider-icon-size)}.elementor-widget-divider .elementor-divider-separator{display:flex;margin:0;direction:ltr}.elementor-widget-divider--view-line_icon .elementor-divider-separator,.elementor-widget-divider--view-line_text .elementor-divider-separator{align-items:center}.elementor-widget-divider--view-line_icon .elementor-divider-separator:after,.elementor-widget-divider--view-line_icon .elementor-divider-separator:before,.elementor-widget-divider--view-line_text .elementor-divider-separator:after,.elementor-widget-divider--view-line_text .elementor-divider-separator:before{display:block;content:\"\";border-bottom:0;flex-grow:1;border-top:var(--divider-border-width) var(--divider-border-style) var(--divider-color)}.elementor-widget-divider--element-align-left .elementor-divider .elementor-divider-separator>.elementor-divider__svg:first-of-type{flex-grow:0;flex-shrink:100}.elementor-widget-divider--element-align-left .elementor-divider-separator:before{content:none}.elementor-widget-divider--element-align-left .elementor-divider__element{margin-left:0}.elementor-widget-divider--element-align-right .elementor-divider .elementor-divider-separator>.elementor-divider__svg:last-of-type{flex-grow:0;flex-shrink:100}.elementor-widget-divider--element-align-right .elementor-divider-separator:after{content:none}.elementor-widget-divider--element-align-right .elementor-divider__element{margin-right:0}.elementor-widget-divider:not(.elementor-widget-divider--view-line_text):not(.elementor-widget-divider--view-line_icon) .elementor-divider-separator{border-top:var(--divider-border-width) var(--divider-border-style) var(--divider-color)}.elementor-widget-divider--separator-type-pattern{--divider-border-style:none}.elementor-widget-divider--separator-type-pattern.elementor-widget-divider--view-line .elementor-divider-separator,.elementor-widget-divider--separator-type-pattern:not(.elementor-widget-divider--view-line) .elementor-divider-separator:after,.elementor-widget-divider--separator-type-pattern:not(.elementor-widget-divider--view-line) .elementor-divider-separator:before,.elementor-widget-divider--separator-type-pattern:not([class*=elementor-widget-divider--view]) .elementor-divider-separator{width:100%;min-height:var(--divider-pattern-height);-webkit-mask-size:var(--divider-pattern-size) 100%;mask-size:var(--divider-pattern-size) 100%;-webkit-mask-repeat:var(--divider-pattern-repeat);mask-repeat:var(--divider-pattern-repeat);background-color:var(--divider-color);-webkit-mask-image:var(--divider-pattern-url);mask-image:var(--divider-pattern-url)}.elementor-widget-divider--no-spacing{--divider-pattern-size:auto}.elementor-widget-divider--bg-round{--divider-pattern-repeat:round}.rtl .elementor-widget-divider .elementor-divider__text{direction:rtl}.e-con-inner>.elementor-widget-divider,.e-con>.elementor-widget-divider{width:var(--container-widget-width,100%);--flex-grow:var(--container-widget-flex-grow)}<\/style>\t\t<div class=\"elementor-divider\">\n\t\t\t<span class=\"elementor-divider-separator\">\n\t\t\t\t\t\t<\/span>\n\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-d2c4fe6 elementor-widget elementor-widget-heading\" data-id=\"d2c4fe6\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">Technology Evaluation<\/h2>\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-c5668bb elementor-widget elementor-widget-text-editor\" data-id=\"c5668bb\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<p><span style=\"color: #16176f;\">OpenResty based Gateways:<\/span><\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-14cd5a0 elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"14cd5a0\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"gn go gp gq gr\"><div class=\"ab ca\"><div class=\"ch bg fz ga gb gc\"><p id=\"ac36\" class=\"pw-post-body-paragraph mk ml gu mm b mn og mp mq mr oh mt mu mv oi mx my mz oj nb nc nd ok nf ng nh gn bj\" data-selectable-paragraph=\"\"><span style=\"text-decoration: underline;\"><span style=\"color: #000080; text-decoration: underline;\"><a class=\"af pi\" style=\"color: #000080; text-decoration: underline;\" href=\"https:\/\/luarocks.org\/\" target=\"_blank\" rel=\"noopener ugc nofollow\">LuaRocks<\/a>\u00a0<\/span><\/span>is the Lua package manager. It allows the creation and installation of Lua modules and Lua-based scripts and apps. OpenResty leverages Lua plugins to extend its functionality, allowing developers to inject custom logic into the Nginx server. With Lua scripting, users can create dynamic, flexible plugins to handle tasks like authentication, request transformations, and traffic control. These plugins enhance the capabilities of OpenResty, enabling tailored solutions for specific use cases.<\/p><p id=\"7b28\" class=\"pw-post-body-paragraph mk ml gu mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gn bj\" data-selectable-paragraph=\"\">Finding plugins for OpenResty is simple as most of the Lua plugins start with the\u00a0<em class=\"pw\">resty<\/em>\u00a0word:\u00a0<span style=\"text-decoration: underline;\"><span style=\"color: #000080;\"><a class=\"af pi\" style=\"color: #000080; text-decoration: underline;\" href=\"https:\/\/luarocks.org\/search?q=resty\" target=\"_blank\" rel=\"noopener ugc nofollow\">https:\/\/luarocks.org\/search?q=resty<\/a><\/span><\/span><\/p><p id=\"cf9b\" class=\"pw-post-body-paragraph mk ml gu mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gn bj\" data-selectable-paragraph=\"\">Most OpenResty-powered gateways are able to operate in 2 flavors:<\/p><ul><li>Standalone Gateway using static configuration files<\/li><li>Complete Gateways including control plane and database to store dynamic configurations.<\/li><\/ul><\/div><\/div><\/div>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-0ab2adb elementor-widget elementor-widget-image\" data-id=\"0ab2adb\" data-element_type=\"widget\" data-widget_type=\"image.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<img decoding=\"async\" loading=\"lazy\" width=\"738\" height=\"654\" src=\"https:\/\/www.proxym-group.com\/wp-content\/uploads\/sites\/8\/2025\/01\/blog.drawio.png\" class=\"attachment-large size-large wp-image-24037\" alt=\"\" srcset=\"https:\/\/www.proxym-group.com\/wp-content\/uploads\/sites\/8\/2025\/01\/blog.drawio.png 738w, https:\/\/www.proxym-group.com\/wp-content\/uploads\/sites\/8\/2025\/01\/blog.drawio-300x266.png 300w, https:\/\/www.proxym-group.com\/wp-content\/uploads\/sites\/8\/2025\/01\/blog.drawio-372x330.png 372w, https:\/\/www.proxym-group.com\/wp-content\/uploads\/sites\/8\/2025\/01\/blog.drawio-203x180.png 203w\" sizes=\"(max-width: 738px) 100vw, 738px\" \/>\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-41593eb elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"41593eb\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<p id=\"0667\" class=\"pw-post-body-paragraph mk ml gu mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gn bj\" data-selectable-paragraph=\"\">A typical OpenResty-based Gateway has a Data Plane and a Control Plane. For those who are not familiar with the terminology of data and control planes, data planes handle the actual data traffic, executing operations like routing and processing. Control planes manage the configuration and decision-making processes, orchestrating how data planes operate in a network.<\/p><p id=\"9331\" class=\"pw-post-body-paragraph mk ml gu mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gn bj\" data-selectable-paragraph=\"\">The Data Plane is based on OpenResty\/Nginx gateways serving APIs to clients and forwarding requests to upstream servers. The Data plane is configured by a control plane that describes the APIs and specifies which processing is done at each API and which plugins are applied per route.<\/p><p id=\"7492\" class=\"pw-post-body-paragraph mk ml gu mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gn bj\" data-selectable-paragraph=\"\">The control plane is generally composed of:<\/p><p style=\"padding-left: 40px;\"><strong class=\"mm gv\">\u25cf Management APIs:<\/strong>\u00a0a component that exposes REST-based APIs to allow developers to create, operate, and manage APIs lifecycle.<\/p><p style=\"padding-left: 40px;\"><strong class=\"mm gv\">\u25cf Management UI:<\/strong>\u00a0This is typically a combination of an administration console and\/or a developer portal application.<\/p><p style=\"padding-left: 40px;\"><strong class=\"mm gv\">\u25cf Configuration repository:<\/strong>\u00a0This is where the created APIs and configurations are stored. It\u2019s typically based on an ETCD, Zookeeper, or a traditional RDBMS server.<\/p><p style=\"padding-left: 40px;\"><strong class=\"mm gv\">\u25cf Analytics Repository:<\/strong>\u00a0Stores raw API usage data as reported by the API gateways in the Data Plane area. Some API products store the analytics data in the same repository as the configuration.<\/p><p id=\"5bb5\" class=\"pw-post-body-paragraph mk ml gu mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gn bj\" data-selectable-paragraph=\"\">Differences exist between API Gateway products but the philosophy remains the same. For example, some products use Redis for Rate-limiting and session management and some others use the shared store (etcd, zookeeper, postgres) for the same purpose. Some API Gateway technologies provide the admin UI and the developer portal as part of the same application while others may separate them into completely different applications.<\/p><p id=\"f99a\" class=\"pw-post-body-paragraph mk ml gu mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gn bj\" data-selectable-paragraph=\"\">Now, to respond to the standard requirements part we have:<\/p><ul class=\"\"><li id=\"cb63\" class=\"mk ml gu mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh px om on bj\" data-selectable-paragraph=\"\"><span style=\"text-decoration: underline;\"><span style=\"color: #000080; text-decoration: underline;\"><a class=\"af pi\" style=\"color: #000080; text-decoration: underline;\" href=\"https:\/\/github.com\/zmartzone\/lua-resty-openidc\" target=\"_blank\" rel=\"noopener ugc nofollow\">Lua-resty-openidc<\/a>:<\/span><\/span> This is a great Lua plugin that is used as a base for almost all API Gateway products.<\/li><li id=\"14ef\" class=\"mk ml gu mm b mn oo mp mq mr op mt mu mv oq mx my mz or nb nc nd os nf ng nh px om on bj\" data-selectable-paragraph=\"\"><span style=\"text-decoration: underline; color: #000080;\"><a class=\"af pi\" style=\"color: #000080; text-decoration: underline;\" href=\"https:\/\/github.com\/bungle\/lua-resty-session\" target=\"_blank\" rel=\"noopener ugc nofollow\">Lua-resty-session<\/a>:<\/span> The standard way to handle sessions on OpenResty.<\/li><li id=\"d6f1\" class=\"mk ml gu mm b mn oo mp mq mr op mt mu mv oq mx my mz or nb nc nd os nf ng nh px om on bj\" data-selectable-paragraph=\"\"><span style=\"text-decoration: underline;\"><span style=\"color: #000080; text-decoration: underline;\"><a class=\"af pi\" style=\"color: #000080; text-decoration: underline;\" href=\"https:\/\/github.com\/ledgetech\/lua-resty-redis-connector\" target=\"_blank\" rel=\"noopener ugc nofollow\">Lua-resty-redis-connector<\/a>:<\/span><\/span> Used by lua-resty-session in case Redis is configured as a session store.<\/li><\/ul><p id=\"02c2\" class=\"pw-post-body-paragraph mk ml gu mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gn bj\" data-selectable-paragraph=\"\">These are examples of plugins that are used on top of OpenResty to respond to the first set of requirements.<span style=\"color: #363531; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: large; letter-spacing: normal; text-align: left;\">\u25cf<\/span><\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<div class=\"elementor-element elementor-element-1e2378a elementor-widget elementor-widget-text-editor\" data-id=\"1e2378a\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<p>Customization on top of OpenResty<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-d4b9651 elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"d4b9651\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<p id=\"6e0e\" class=\"pw-post-body-paragraph mk ml gu mm b mn og mp mq mr oh mt mu mv oi mx my mz oj nb nc nd ok nf ng nh gn bj\" data-selectable-paragraph=\"\">Implementing custom logic on top of OpenResty is a bit tricky. Fortunately, API Gateway vendors based on OpenResty tried to make things more simple.<\/p><p id=\"1951\" class=\"pw-post-body-paragraph mk ml gu mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gn bj\" data-selectable-paragraph=\"\">When going through the APISIX plugin development\u00a0<span style=\"text-decoration: underline; color: #000080;\"><a class=\"af pi\" style=\"color: #000080; text-decoration: underline;\" href=\"https:\/\/apisix.apache.org\/docs\/apisix\/plugin-develop\/\" target=\"_blank\" rel=\"noopener ugc nofollow\">documentation<\/a><\/span>, we understand how APISIX provides a simplified wrapped over the low-level OpenResty exposed APIs. It allows developers to hook into different OpenResty phases (init, access, content, log, post-request, etc.). APISIX Lua API exposes to the plugin two objects: ctx and conf. The conf object holds the plugin configuration for that specific route or API. The ctx object refer to the execution context such as original http request, proxied request, response, etc.<\/p><p id=\"ddcc\" class=\"pw-post-body-paragraph mk ml gu mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gn bj\" data-selectable-paragraph=\"\">Kong: kong suggests a more abstracted way for plugin developers. the PDK (Plugin Development Kit) makes it easy to write plugin logic and hook it into the same OpenResty lifecycle phases as APISIX. Kong makes it easy also to expose admin endpoints.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-0615a79 elementor-widget elementor-widget-heading\" data-id=\"0615a79\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t<h3 class=\"elementor-heading-title elementor-size-default\">My take for custom development on an OpenResty-based Gateway<\/h3>\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-9c43ba9 elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"9c43ba9\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<p id=\"406f\" class=\"pw-post-body-paragraph mk ml gu mm b mn og mp mq mr oh mt mu mv oi mx my mz oj nb nc nd ok nf ng nh gn bj\" data-selectable-paragraph=\"\">Commercial products provide a better support and a better developer experience. However, developers face the following challenges:<\/p><p style=\"padding-left: 40px;\"><strong>\u25cf The language and ecosystem:<\/strong> Lua is a lightweight scripting language and the community is not big enough.<\/p><p style=\"padding-left: 40px;\"><strong>\u25cf Debuggability:<\/strong> Debugging is hard and sometimes very hard. This reminds me my early days with PHP where you need to place echo statements everywhere. debugging with a ngx.log() is your best option here. No breakpoints, no variable introspection, nothing.<\/p><p style=\"padding-left: 40px;\"><strong>\u25cf Automated testing:<\/strong> it\u2019s not a easy to write unit tests on a Lua plugin code. It\u2019s usually done on a real APIs.<\/p><p style=\"padding-left: 40px;\"><strong>\u25cfMaintenability:<\/strong> Lua is primarily a procedural language, but it also incorporates elements of other programming paradigms, including object-oriented programming (OOP). Lua\u2019s design is intentionally minimalistic, providing a lightweight and flexible scripting language. This seems like a strength but I see it as a weakness. Finding googd Lua or OpenResty developers isn\u2019t easy and if you manage to successfully write and test your plugin, good luck with finding someone else to support it with you.<\/p><p style=\"padding-left: 40px;\"><strong>\u25cfEcosystem and libraries:<\/strong>\u00a0Although Luarocks does a good job and contains a good number of plugins, Lua still have a limited number of libraries that serve different purpose.<\/p><p id=\"ea44\" class=\"pw-post-body-paragraph mk ml gu mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gn bj\" data-selectable-paragraph=\"\">One major advantage with OpenResty is\u00a0<strong class=\"mm gv\">Nginx<\/strong>\u00a0itself. Imagine you have all the power of Nginx\u2019s http module under your hands.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-241f6b7 elementor-widget-divider--view-line elementor-widget elementor-widget-divider\" data-id=\"241f6b7\" data-element_type=\"widget\" data-widget_type=\"divider.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<div class=\"elementor-divider\">\n\t\t\t<span class=\"elementor-divider-separator\">\n\t\t\t\t\t\t<\/span>\n\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-3540bb1 elementor-widget elementor-widget-heading\" data-id=\"3540bb1\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t<h3 class=\"elementor-heading-title elementor-size-default\">Java based Gateways<\/h3>\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-9412b30 elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"9412b30\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<p id=\"38f8\" class=\"pw-post-body-paragraph mk ml gu mm b mn og mp mq mr oh mt mu mv oi mx my mz oj nb nc nd ok nf ng nh gn bj\" data-selectable-paragraph=\"\">In this evaluation I\u2019m adopting Spring Cloud Gateway. The reason behind it is because it includes almost all the features of Netflix Zuul and uses Spring-Boot and Spring Framework and with Webflux. This makes it a great choice for writing custom code. To summarize the advantage of Spring Cloud Gateway among other Java-based alternatives:<\/p><p style=\"padding-left: 40px;\"><strong>\u25cf\u00a0Reactive:<\/strong> based on Netty and Webflux<\/p><p style=\"padding-left: 40px;\"><strong>\u25cf\u00a0Lightweight:<\/strong> since it\u2019s reactive. It doesn\u2019t consume so much CPU and RAM unlike servlet-based approach.<\/p><p style=\"padding-left: 40px;\"><strong>\u25cf\u00a0Based on Spring:<\/strong> This is a major advantage for java developers<\/p><p style=\"padding-left: 40px;\"><strong>\u25cf\u00a0Actively maintained:<\/strong> Free support, Commercial support and clear release train:\u00a0<span style=\"text-decoration: underline; color: #000080;\"><a class=\"af pi\" style=\"color: #000080; text-decoration: underline;\" href=\"https:\/\/spring.io\/projects\/spring-cloud-gateway#support\" target=\"_blank\" rel=\"noopener ugc nofollow\">https:\/\/spring.io\/projects\/spring-cloud-gateway#support<\/a><\/span><\/p><p style=\"padding-left: 40px;\"><strong>\u25cf\u00a0AOT compilation:<\/strong> Thanks to spring-native support it can be compiled by GraalVM AOT compiler and reduce its memory footprint and startup time.<\/p><p style=\"padding-left: 40px;\"><strong>\u25cf\u00a0Rich ecosystem<\/strong><\/p><p id=\"5e39\" class=\"pw-post-body-paragraph mk ml gu mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gn bj\" data-selectable-paragraph=\"\">A short definition \u2014 I asked ChatGPT to generate:<\/p><p id=\"d53b\" class=\"pw-post-body-paragraph mk ml gu mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gn bj\" data-selectable-paragraph=\"\">It serves as a central entry point for routing and managing HTTP requests in microservices architectures. Offering dynamic routing, filtering, and load balancing, Spring Cloud Gateway provides flexibility and extensibility. It integrates seamlessly with other Spring Cloud components, enabling features like service discovery and configuration management. Its reactive foundation and support for custom filters make it a powerful tool for building scalable and resilient microservices systems.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-c7a934c elementor-widget elementor-widget-heading\" data-id=\"c7a934c\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t<h3 class=\"elementor-heading-title elementor-size-default\">Spring Cloud Gateway Criticism<\/h3>\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-af1e85f elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"af1e85f\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<p class=\"pw-post-body-paragraph mk ml gu mm b mn og mp mq mr oh mt mu mv oi mx my mz oj nb nc nd ok nf ng nh gn bj\" data-selectable-paragraph=\"\">After putting hands on, Spring Cloud Gateway is a Java framework that allows developers to create a Java project that uses a configuration file called application.yaml in which APIs are declared and configured. I\u2019m writing these lines 8 months after my first contact with Spring Cloud Gateway and after delivering couple of projects with. This is not a beginner\u2019s feedback.<\/p><p id=\"fc1e\" class=\"pw-post-body-paragraph mk ml gu mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gn bj\" data-selectable-paragraph=\"\">Spring Cloud Gateway doesn\u2019t have an Admin UI to create and manage APIs. APIs are not declared and designed like any other API in any other API Gateway tool. Instead, Spring Cloud Gateway team continues to use the same configurations and same reflexes as any other Spring-Boot based application. This is a major drawback specially when dealing with multiple APIs on the same instance.<\/p><p class=\"pw-post-body-paragraph mk ml gu mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gn bj\" data-selectable-paragraph=\"\">Some Gateway capabilities are not included by default and you need to pick other extra dependencies to make it work. Again, this is a pre-build time setup and not a simple YAML change that you can apply after go-live. Example: if you want to client-side load balance between upstream servers, you need to add this dependency:<\/p><pre class=\"qb qc qd qe qf qm qn qo bo qp ba bj\"><span id=\"2a45\" class=\"qq nj gu qn b bf qr qs l qt qu\" data-selectable-paragraph=\"\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">dependency<\/span>&gt;<\/span><br \/>    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>org.springframework.cloud<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">groupId<\/span>&gt;<\/span><br \/>    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>spring-cloud-starter-loadbalancer<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span><br \/><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">dependency<\/span>&gt;<\/span><\/span><\/pre>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-c3fd835 elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"c3fd835\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<p class=\"pw-post-body-paragraph mk ml gu mm b mn og mp mq mr oh mt mu mv oi mx my mz oj nb nc nd ok nf ng nh gn bj\" data-selectable-paragraph=\"\">And of course, you need to rebuild your Gateway to include the new dependency.<\/p><p id=\"411b\" class=\"pw-post-body-paragraph mk ml gu mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gn bj\" data-selectable-paragraph=\"\">Customizing the Gateway\u2019s behavior is not always possible through the configuration file. For example, in order to support our previously mentioned basic requirements, we need to create a SecurityConfig.java and configure spring-security-oauth2-client properly.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-19e416e elementor-widget elementor-widget-heading\" data-id=\"19e416e\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t<h3 class=\"elementor-heading-title elementor-size-default\">Configyring Spring Cloud Gateway<\/h3>\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-271837f elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"271837f\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<p class=\"pw-post-body-paragraph mk ml gu mm b mn og mp mq mr oh mt mu mv oi mx my mz oj nb nc nd ok nf ng nh gn bj\" data-selectable-paragraph=\"\">Unlike OpenResty-based Gateways, customization is done through Gateway filters. Filters are Java components that process the request and response objects.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-2c7e082 elementor-widget elementor-widget-image\" data-id=\"2c7e082\" data-element_type=\"widget\" data-widget_type=\"image.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<img decoding=\"async\" loading=\"lazy\" width=\"524\" height=\"698\" src=\"https:\/\/www.proxym-group.com\/wp-content\/uploads\/sites\/8\/2025\/01\/geteway-client.jpg\" class=\"attachment-large size-large wp-image-24038\" alt=\"\" srcset=\"https:\/\/www.proxym-group.com\/wp-content\/uploads\/sites\/8\/2025\/01\/geteway-client.jpg 524w, https:\/\/www.proxym-group.com\/wp-content\/uploads\/sites\/8\/2025\/01\/geteway-client-225x300.jpg 225w, https:\/\/www.proxym-group.com\/wp-content\/uploads\/sites\/8\/2025\/01\/geteway-client-248x330.jpg 248w, https:\/\/www.proxym-group.com\/wp-content\/uploads\/sites\/8\/2025\/01\/geteway-client-135x180.jpg 135w\" sizes=\"(max-width: 524px) 100vw, 524px\" \/>\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-dd7a9ba elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"dd7a9ba\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<p class=\"pw-post-body-paragraph mk ml gu mm b mn og mp mq mr oh mt mu mv oi mx my mz oj nb nc nd ok nf ng nh gn bj\" data-selectable-paragraph=\"\">An HTTP request arriving to the Gateway, will be mapped to the appropriate Route. Then, depending on the route configuration, Gateway filters are applied one by one. Let\u2019s look at this example:<\/p><pre class=\"qb qc qd qe qf qm qn qo bo qp ba bj\"><span id=\"c3b3\" class=\"qq nj gu qn b bf qr qs l qt qu\" data-selectable-paragraph=\"\"><span class=\"hljs-attr\">spring:<\/span><br \/>  <span class=\"hljs-attr\">cloud:<\/span><br \/>    <span class=\"hljs-attr\">gateway:<\/span><br \/>      <span class=\"hljs-attr\">routes:<\/span><br \/>      <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-attr\">id:<\/span> <span class=\"hljs-string\">add_request_headers_route<\/span><br \/>        <span class=\"hljs-attr\">uri:<\/span> <span class=\"hljs-string\">https:\/\/example.org<\/span><br \/>        <span class=\"hljs-attr\">filters:<\/span><br \/>        <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-string\">AddRequestHeader=X-Request-Color-1:blue,X-Request-Color-2:green<\/span><\/span><\/pre>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-93f8e0c elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"93f8e0c\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<p class=\"pw-post-body-paragraph mk ml gu mm b mn og mp mq mr oh mt mu mv oi mx my mz oj nb nc nd ok nf ng nh gn bj\" data-selectable-paragraph=\"\">Once the route is mapped (it\u2019s the default route in this example), filters are called one by one. In this example, AddRequestHeader filter is called. We expect this route to call <a class=\"af pi\" href=\"https:\/\/example.org\/\" target=\"_blank\" rel=\"noopener ugc nofollow\" data-wplink-edit=\"true\"><span style=\"text-decoration: underline; color: #000080;\">https:\/\/example.org<\/span><\/a>\u00a0and add these header values: X-Request-Color-1:blue and X-Request-Color-2:green. We can chain multiple Filters and among these filters we have the TokenRelay filter:<\/p><pre class=\"qb qc qd qe qf qm qn qo bo qp ba bj\"><span id=\"4e7e\" class=\"qq nj gu qn b bf qr qs l qt qu\" data-selectable-paragraph=\"\"><span class=\"hljs-attr\">spring:<\/span><br \/>  <span class=\"hljs-attr\">cloud:<\/span><br \/>    <span class=\"hljs-attr\">gateway:<\/span><br \/>      <span class=\"hljs-attr\">routes:<\/span><br \/>      <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-attr\">id:<\/span> <span class=\"hljs-string\">resource<\/span><br \/>        <span class=\"hljs-attr\">uri:<\/span> <span class=\"hljs-string\">http:\/\/localhost:9000<\/span><br \/>        <span class=\"hljs-attr\">predicates:<\/span><br \/>        <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-string\">Path=\/resource<\/span><br \/>        <span class=\"hljs-attr\">filters:<\/span><br \/>        <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-string\">TokenRelay=<\/span><\/span><\/pre><p id=\"8598\" class=\"pw-post-body-paragraph mk ml gu mm b mn og mp mq mr oh mt mu mv oi mx my mz oj nb nc nd ok nf ng nh gn bj\" data-selectable-paragraph=\"\">\u00a0<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-df91292 elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"df91292\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<p>A Token Relay is where an OAuth2 consumer acts as a Client and forwards the incoming token to outgoing resource requests. The consumer can be a pure Client (like an SSO application) or a Resource Server. Spring Cloud Gateway can forward OAuth2 access tokens downstream to the services it is proxying. This filter resolves the first part of our requirements.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-de694d2 elementor-widget elementor-widget-heading\" data-id=\"de694d2\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t<h3 class=\"elementor-heading-title elementor-size-default\">Developing custom filters<\/h3>\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-f3f129e elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"f3f129e\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<p>First, we need to understand different extension points for Spring Cloud Gateway. Apart from traditional Spring beans where we can inject controllers, repositories, and other components, we need to understand different filter types and how they work. Filters are categorized into different types based on when they are applied in the request lifecycle. Here are the main filter types in Spring Cloud Gateway:<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-45cb34d elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"45cb34d\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<p><strong class=\"mm gv\">\u25cf Global Filters: <\/strong>Global filters are applied to all routes and act on every request passing through the gateway. These filters are typically used for cross-cutting concerns that apply universally. You may want to use Global filters in situations where you need to have it called at each request such as logging, identity enrichment, etc.<\/p><p><strong class=\"mm gv\">\u25cf Route Filters:<\/strong>\u00a0Route filters are specific to a particular route and are applied only to requests that match the defined route. They allow for customization and transformation of requests. Route filters can receive different configurations for each route. Imagine a AddRequestHeader filter that appends a header for each request before sending it to the upstream server, we can add headers with a different names and values for each route.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-1f0ca55 elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"1f0ca55\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<p>Filters of both types, can be combined together to allow complete control over requests and responses sent to upstream servers and responses sent back to the client.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-6334747 elementor-widget elementor-widget-image\" data-id=\"6334747\" data-element_type=\"widget\" data-widget_type=\"image.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<img decoding=\"async\" loading=\"lazy\" width=\"548\" height=\"872\" src=\"https:\/\/www.proxym-group.com\/wp-content\/uploads\/sites\/8\/2025\/01\/APICLIENT.jpg\" class=\"attachment-large size-large wp-image-24039\" alt=\"\" srcset=\"https:\/\/www.proxym-group.com\/wp-content\/uploads\/sites\/8\/2025\/01\/APICLIENT.jpg 548w, https:\/\/www.proxym-group.com\/wp-content\/uploads\/sites\/8\/2025\/01\/APICLIENT-189x300.jpg 189w, https:\/\/www.proxym-group.com\/wp-content\/uploads\/sites\/8\/2025\/01\/APICLIENT-207x330.jpg 207w, https:\/\/www.proxym-group.com\/wp-content\/uploads\/sites\/8\/2025\/01\/APICLIENT-113x180.jpg 113w\" sizes=\"(max-width: 548px) 100vw, 548px\" \/>\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-f059031 elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"f059031\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<p data-selectable-paragraph=\"\">The three main exposed components are :<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-b3f9c24 elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"b3f9c24\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<p><strong>\u25cf Route Filters<\/strong>: These are filters that are configured and applied separately for each route. The filter configuration is usually expressed through the YAML DSL.<\/p><p><strong>\u25cf Global Filters:<\/strong>\u00a0They are executed for each Proxied request. These are regular Spring beans and they are configured as any regular spring bean. There is no specific configuration DSL for Global filters.<\/p><p><strong>\u25cf Rest Controllers:<\/strong>\u00a0Regular Spring Webflux controllers.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-d73be12 elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"d73be12\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<p data-selectable-paragraph=\"\">We understand that can have a mix of regular Spring @RestController controllers and routes. This is so powerful since it allows mixing regular web developments and HTTP request Proxying. Exposed APIs are in result, a mixture of Routes and controllers.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-e5655f0 elementor-widget elementor-widget-heading\" data-id=\"e5655f0\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t<h3 class=\"elementor-heading-title elementor-size-default\">Advantages of Spring Cloud Gateway over regular API gateways<\/h3>\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-0bfb0c7 elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"0bfb0c7\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<p id=\"9acd\" class=\"pw-post-body-paragraph mk ml gu mm b mn og mp mq mr oh mt mu mv oi mx my mz oj nb nc nd ok nf ng nh gn bj\" data-selectable-paragraph=\"\">The advantages are huge for developers. Filters are a powerful concept that allows developers to deal with cross-cutting concerns and customize the behavior of the gateway at various stages of request processing. This flexibility enables tasks such as authentication, authorization, request transformation, and response modification.<\/p><p id=\"1958\" class=\"pw-post-body-paragraph mk ml gu mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gn bj\" data-selectable-paragraph=\"\">Moreover, Spring Cloud Gateway integrates seamlessly with the Spring ecosystem, providing a familiar and cohesive development experience for Spring developers. It leverages reactive programming with Spring WebFlux, making it well-suited for handling large numbers of concurrent connections efficiently. The dynamic routing capabilities allow for on-the-fly adjustments to route configurations, promoting adaptability in dynamic micro-services environments<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-322befb elementor-widget elementor-widget-heading\" data-id=\"322befb\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t<h3 class=\"elementor-heading-title elementor-size-default\">The flip side of the coin<\/h3>\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-ea44e9a elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"ea44e9a\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<p id=\"9acd\" class=\"pw-post-body-paragraph mk ml gu mm b mn og mp mq mr oh mt mu mv oi mx my mz oj nb nc nd ok nf ng nh gn bj\" data-selectable-paragraph=\"\">Spring Cloud Gateway leverages most of features that an API Gateway can provide but can\u2019t considered a full API Gateway. As explained in the first part, API Gateways goes beyond request manipulation and offer these possibilities:<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-a1e0aef elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"a1e0aef\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<p><strong>\u25cf Configuration management:<\/strong> API Gateways can be configured from a control plane as there is no default administration UI.<\/p><p><strong>\u25cf Instant deployment:<\/strong> Regular API Gateways allows adding and managing routes and plugins at runtime<\/p><p><strong>\u25cf Easier setup for HA:<\/strong> Regular API Gateways are easier to deploy in Active-Active mode. Doing this in Spring Cloud Gateway requires more effort since we need to deal with Spring configurations to enable Redis or an equivalent tool to support multi instance synchronization.<\/p><p><strong>\u25cf Developer Portal:<\/strong>\u00a0Spring cloud Gateway does not support out of the box API keys and then no concept of Developer portal.<\/p><p><strong>\u25cf Plugins ecosystem:<\/strong> There is no plugin directory you need to do it all by yourself. Spring team made a great effort by including out-of-the-box filters but in most cases, developers need to craft things by hand to go beyond that.<\/p><p><strong>\u25cf Dependency on developers:<\/strong> Configuring Spring cloud Gateway requires developer skills. For example, if you want to add client side load balancing to you gateway you need a developer to add an additional maven dependency to the main POM and repackage the Gateway. Such things are impossible for regular API developers.<\/p><p><strong>\u25cf YAML YAML YAML:<\/strong> you got it it\u2019s not easy at all.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-08b30e8 elementor-widget-divider--view-line elementor-widget elementor-widget-divider\" data-id=\"08b30e8\" data-element_type=\"widget\" data-widget_type=\"divider.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<div class=\"elementor-divider\">\n\t\t\t<span class=\"elementor-divider-separator\">\n\t\t\t\t\t\t<\/span>\n\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-96a94a7 elementor-widget elementor-widget-heading\" data-id=\"96a94a7\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t<h3 class=\"elementor-heading-title elementor-size-default\">Conclusion<\/h3>\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-bb7dc44 elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"bb7dc44\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<p id=\"624d\" class=\"pw-post-body-paragraph mk ml gu mm b mn og mp mq mr oh mt mu mv oi mx my mz oj nb nc nd ok nf ng nh gn bj\" data-selectable-paragraph=\"\">There\u2019s no one-size-fits-all solution; selecting the appropriate tool for a specific task is important. When it comes to open-source options for building an API Gateway, here\u2019s a brief overview to guide you in making the right tool choice:<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-b9c56d2 elementor-widget elementor-widget-image\" data-id=\"b9c56d2\" data-element_type=\"widget\" data-widget_type=\"image.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<img decoding=\"async\" loading=\"lazy\" width=\"596\" height=\"971\" src=\"https:\/\/www.proxym-group.com\/wp-content\/uploads\/sites\/8\/2025\/01\/apigeteway.jpg\" class=\"attachment-large size-large wp-image-24040\" alt=\"\" srcset=\"https:\/\/www.proxym-group.com\/wp-content\/uploads\/sites\/8\/2025\/01\/apigeteway.jpg 596w, https:\/\/www.proxym-group.com\/wp-content\/uploads\/sites\/8\/2025\/01\/apigeteway-184x300.jpg 184w, https:\/\/www.proxym-group.com\/wp-content\/uploads\/sites\/8\/2025\/01\/apigeteway-203x330.jpg 203w, https:\/\/www.proxym-group.com\/wp-content\/uploads\/sites\/8\/2025\/01\/apigeteway-110x180.jpg 110w\" sizes=\"(max-width: 596px) 100vw, 596px\" \/>\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-26f69af elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"26f69af\" data-element_type=\"section\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-daa23c3\" data-id=\"daa23c3\" data-element_type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t\t\t<div class=\"elementor-element elementor-element-4f97376 elementor-widget elementor-widget-icon-box\" data-id=\"4f97376\" data-element_type=\"widget\" data-widget_type=\"icon-box.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t<link rel=\"stylesheet\" href=\"https:\/\/www.proxym-group.com\/wp-content\/uploads\/sites\/8\/elementor\/css\/custom-widget-icon-box.min.css?ver=1764671704\">\t\t<div class=\"elementor-icon-box-wrapper\">\n\t\t\t\t\t\t<div class=\"elementor-icon-box-content\">\n\t\t\t\t<h3 class=\"elementor-icon-box-title\">\n\t\t\t\t\t<span  >\n\t\t\t\t\t\tHOUCEM EDDINE BERRAYANA\t\t\t\t\t<\/span>\n\t\t\t\t<\/h3>\n\t\t\t\t\t\t\t\t\t<p class=\"elementor-icon-box-description\">\n\t\t\t\t\t\tChief Technology Officer \t\t\t\t\t<\/p>\n\t\t\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Selecting the right open-source API Gateway technology I was tasked with setting up an API gateway to protect the APIs of a backend server. The requirements were divided into two types: standard requirements and custom requirements. While any API Gateway should address the standard requirements using various plugins, meeting the custom requirements might involve additional [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"elementor_header_footer","format":"standard","meta":{"content-type":"","_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[1],"tags":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.proxym-group.com\/fr\/wp-json\/wp\/v2\/posts\/24035"}],"collection":[{"href":"https:\/\/www.proxym-group.com\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.proxym-group.com\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.proxym-group.com\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.proxym-group.com\/fr\/wp-json\/wp\/v2\/comments?post=24035"}],"version-history":[{"count":4,"href":"https:\/\/www.proxym-group.com\/fr\/wp-json\/wp\/v2\/posts\/24035\/revisions"}],"predecessor-version":[{"id":24044,"href":"https:\/\/www.proxym-group.com\/fr\/wp-json\/wp\/v2\/posts\/24035\/revisions\/24044"}],"wp:attachment":[{"href":"https:\/\/www.proxym-group.com\/fr\/wp-json\/wp\/v2\/media?parent=24035"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.proxym-group.com\/fr\/wp-json\/wp\/v2\/categories?post=24035"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.proxym-group.com\/fr\/wp-json\/wp\/v2\/tags?post=24035"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}