All Products
Search
Document Center

API Gateway:Backend routing plug-ins

Last Updated:Jul 31, 2024

A plug-in of the Routing type, also known as a backend routing plug-in, is used to route API requests to different backend service URLs by changing the backend service type, URL, path, and parameters in the requests. These plug-ins can be used for multi-tenant routing and blue-green release. They can also be used to distinguish between different environments.

Overview

A backend routing plug-in is used to route API requests to different backend service URLs by changing the backend service type, URL, path, and parameters in the requests. These plug-ins can be used for multi-tenant routing and blue-green release. They can also be used to distinguish between different environments.

1. Configurations

1.1 Configuration template

You can configure a plug-in of the Routing type in the JSON or YAML format. The two formats have the same schema and can be converted to each other by using a conversion tool. The following code snippet is a YAML template for configuring a plug-in of the Routing type:

---
routes:
# Route requests from the same caller to an independent backend service address. In this example, requests from the caller whose AppId is 123456 are routed to an address that belongs to the CIDR block of a virtual private cloud (VPC) whose access authorization name is slbAddressForVip.
- name: Vip
  condition: "$CaAppId = 123456"
  backend:
    type: "HTTP-VPC"
    vpcAccessName: "slbAccessForVip"
# For outdated clients, responses that indicate that the clients are no longer supported are returned. ClientVersion is a custom parameter in the API.
- name: MockForOldClient
  condition: "$ClientVersion < '2.0.5'"
  backend: 
    type: "MOCK"
    statusCode: 400
    body: "This version is not supported!!!"

The template shows a routes object that contains multiple route objects. Each route object is used to specify a routing rule. Each routing rule consists of the following parts:

  • name: the name of the routing rule. The name must be unique within each plug-in, and can contain letters and digits. If an API request hits the rule, an HTTP header X-Ca-Routing-Name that contains the name of the rule is added to the request before the request is routed to the backend.

  • condition: the conditional expression of the routing rule. For information about how to write conditional expressions, see section 2.2. If an API request meets the condition, the request hits the routing rule. A plug-in of the Routing type checks routing rules based on the order in which they are configured. An API request is routed to the backend in the first routing rule that the request hits. After that, the plug-in does not check the remaining routing rules. If you configure multiple routing rules, make sure that they are configured in the order that meets your business expectations.

  • backend: the information about the backend. Configurations of the backend must be consistent with the OpenAPI specifications of API Gateway. The backend configurations in a plug-in of the Routing type override the backend configurations in an API to which the plug-in is bound. If the backend configurations are incomplete after the overriding, the following message is returned to the client: X-Ca-Error-Code: I504RB. If you receive this message, check whether the backend configurations are complete. For more information, see section 1.3 of this topic.

  • constant-parameters: the custom constant parameters that you can configure in the routing rule. The constant parameters are attached to an API request before the request is routed to the backend. These parameters are used in the business logic of the backend. The location parameter can be set to header or query.

1.2 Conditional expressions

1.2.1 Syntax

  • The syntax of conditional expressions in plug-ins of the Routing type are similar to that of SQL statements. The basic format is $A = 'A' and '$B = 'B'.

  • Each parameter starts with $. You can reference the request parameters that are defined in an API to which a plug-in is bound. The request mode of the API can be set to MAPPING or PASSTHROUGH. If you defined a request parameter named query1 when you configured the API, you can use $query1 to reference the parameter in conditional expressions.

  • The following constant parameter types are supported:

    • STRING: the string data type. Single quotation marks (') or double quotation marks (") can be used to enclose a string. Example: "Hello".

    • INTEGER: the integer data type, such as 1001 and -1.

    • NUMBER: the floating-point data type, such as 0.1 and 100.0.

    • BOOLEAN: true or false.

  • You can use and and or to connect different expressions.

  • You can use parentheses () to specify the priority of conditional expressions.

  • You can use $CaAppId to reference system parameters from an API request. You do not need to define system parameters in an API. However, if you have defined a parameter in the API with the same name as a system parameter, the value of the system parameter is overwritten by that of the parameter defined in the API. The following system parameters can be referenced in a plug-in of the Routing type:

    • CaStage: the environment to which the requested API is published. Valid values: RELEASE, PRE, and TEST.

    • CaDomain: the domain name of the API group to which the requested API belongs.

    • CaRequestHandleTime: the time in UTC at which the current request is received.

    • CaAppId: the value of the AppId parameter in the current request.

    • CaAppKey: the value of the AppKey parameter in the current request.

    • CaClientIp: the IP address of the client from which the current request is sent.

    • CaApiName: the name of the requested API.

    • CaHttpScheme: the protocol used by the current request. Valid values: HTTP and HTTPS.

    • CaClientUa: the UserAgent field uploaded from the client.

  • If you use a non-existent parameter in a conditional expression, such as $UnknonwParameter = 1, the result of the expression is false.

1.2.2 Examples

  • The following expression indicates that the requested API is published to the test environment:

    $CaStage = 'TEST'

  • The following expression indicates that the custom parameter UserName must be specified as Admin and the IP address of the client must be 47.47.XX.XX:

    $UserName = 'Admin' and $CaClientIp = '47.47.XX.XX'

  • The following expression indicates that the AppId parameter is set to 1001, 1098, or 2011, and the protocol that is used by the API request is HTTPS:

    $CaHttpScheme = 'HTTPS' and ($CaAppId = 1001 or $CaAppId = 1098 or $CaAppId = 2011)

1.3 Backend configurations and overriding rules

Configurations of a backend must be consistent with the Swagger files that are imported to API Gateway. For more information, see Import Swagger files to create APIs with API Gateway extensions. The following examples show the supported backend types and configuration samples. The backend configurations in a plug-in of the Routing type override the backend configurations in an API to which the plug-in is bound. If you do not need to change the backend type, specify only the parameters whose values you want to change.

Important
  • If you want to distribute API requests based on the weights of backend services, you must specify all the parameters.

  • For more information about the priority of Host header configurations, see Configure the Host header.

  • HTTP

---
backend:
  type: HTTP
  address: "http://10.10.100.2:8000"
  httpTargetHostName: "a.b.com" # Requests are forwarded to a.b.com. This Host header configuration has the highest priority.
  path: "/users/{userId}"
  method: GET
  timeout: 7000
  • HTTP-VPC

---
backend:
  type: HTTP-VPC
  vpcAccessName: vpcAccess1
  vpcTargetHostName: "a.b.com" # Requests are forwarded to a.b.com. This Host header configuration has the highest priority.
  vpcScheme: "https"
  path: "/users/{userId}"
  method: GET
  timeout: 10000
  • FC

---
backend:
  type: FC
  fcRegion: cn-shanghai
  fcType: FCEvent
  serviceName: fcService
  functionName: fcFunction
  roleArn: "acs:ram::111111111:role/aliyunapigatewayaccessingfcrole"
backend:
  type: FC
  fcRegion: cn-shenzhen
  method: GET
  fcType: HttpTrigger
  fcUrl: https://1833848375796824.cn-shenzhen.fc.aliyuncs.com/2016-08-15/proxy/servicetest/fctest3/fctest3
  roleArn: acs:ram::1833848375796824:role/aliyunapigatewayaccessingfcrole
  • OSS

---
backend:
  type: OSS
  ossRegionId: cn-hangzhou
  bucketName: bucketName
  key: /objectName
  timeout: 10000
  action: putObject
  • MOCK

---
backend:
  type: MOCK
  mockResult: "mock resul sample"
  mockStatusCode: 200
  mockHeaders:
    - name: server
      value: mock
    - name: proxy
      value: GW

1.4 Service weight and request distribution

Backend routing plug-ins allow you to send API requests to backend services based on the service weights. The service that has a higher weight is sent more requests. The following code shows a configuration example:

---
routes:
# Configure two backend services and assign weights to them based on their processing capabilities. The service that has a higher weight is sent more requests.
- name: Backend01
  condition: "1 = 1" # 1 = 1 indicates a condition hit, and 1 = 0 indicates a condition miss.
  weight: 100       # Used to specify the weights of the backend services.
  backend:
    type: "HTTP"
    address: "https://test01.com"
    path: "/web/cloudapi"
- name: Backend02
  condition: "1 = 1"
  weight: 80
  backend:
    type: "HTTP"
    address: "https://test02.com"
    path: "/web/cloudapi"

Important
  • If one condition is hit, all requests are sent to the service that hits the condition.

  • If multiple conditions are hit, requests are distributed based on the service weights.

  • If no condition is hit, all requests are sent to the backend service defined in the API.

1.5 Limits

  • For each plug-in of the Routing type, you can configure a maximum of 16,384 bytes of metadata. If this limit is exceeded, the InvalidPluginData.TooLarge error is returned.

  • A plug-in of the Routing type supports a maximum of 160 routes. If this limit is exceeded, the InvalidPluginData.TooManyRoutes error is returned. If this plug-in is bound to an API on a shared instance, only the first 16 routes take effect. If this plug-in is bound to an API on a dedicated instance, all routes take effect.

  • Each conditional expression can contain a maximum of 512 bytes of data. If this limit is exceeded, the InvalidPluginData.ConditionTooLong error is returned.

  • Configuration updates of a plug-in of the Routing type are synchronized in real time to all APIs to which the plug-in is bound. The minimum interval between two updates is 45 seconds. If you try to update a plug-in in less than 45 seconds after the last update, the InvalidPluginData.UpdateTooBusy error is returned.

2. Typical scenarios

2.1 Route API requests to different backend URLs based on application IDs

Assume that you provide two application IDs for VIP callers to use, 10098 and 10099, and you want to route API requests from these application IDs to an independent server cluster. The following code shows a configuration example:

---
routes:
# If the AppId value for an API caller is 10098 or 10099, requests to the API are routed to an independent URL.
# In this example, the VPC access name is set to slbAddressForVip.
- name: Vip
  condition: "$CaAppId = 10098 or $CaAppId = 10099"
  backend:
    type: "HTTP-VPC"
    vpcAccessName: "slbAccessForVip"

2.2 Route all requests for APIs that are published to the same environment to the same server

Assume that you want all requests for APIs that are published to the test environment to be diverted to your test server on the Internet. The following code shows a configuration example:

---
routes:
# Route all requests for APIs that are published to the Test environment to the test server on the Internet.
- name: Vip
  condition: "$CaStage = 'TEST'"
  backend:
    type: "HTTP"
    address: "https://test-env.foo.com"

2.3 Configure routing for blue-green release

Assume that you want to divert 5% of requests to a group of beta server addresses, and 95% of requests to a backend service of the VPC type. The following code shows a configuration example:

---
routes:
# Blue-green release: Route 5% of requests to a blue-green release backend, and 95% of requests to a backend service of the VPC type. 
- name: BlueGreenPercent05
  condition: "1 = 1"
  weight: 5
  backend:
    type: "HTTP"
    address: "https://beta-version.api.foo.com"
    path: "/web/cloudapi"
  constant-parameters:
  - name: x-route-blue-green
    location: header
    value: "route-blue-green"
- name: BlueGreenPercent95
  condition: "1 = 1"
  weight: 95
  backend:
    type: HTTP-VPC
    path: "/web/cloudapi"
    vpcAccessName: testvpc
Note
  • condition: 1 = 1 indicates a condition hit, and 1 = 0 indicates a condition miss.

  • weight: used to specify the weights of the backend services. Requests are sent to the services based on the weights.

2.4 Consistent hashing-based routing

A consistent hashing algorithm evenly distributes requests to backend services based on different hash factors. Requests that have the same hash factor are distributed to the same backend service.

Backend routing plug-ins support the following hash factors:

  • Source IP address: hashing based on source IP addresses. Requests with the same source IP address are distributed to the same backend server.

  • Parameter: hashing based on request parameters. Requests with the same parameter configurations are distributed to the same backend server.

The following code shows an example on source IP address hashing:

---
parameters:
  clientIp: "System:CaClientIp"  
routeByHash: clientIp # Specify the hash factor.
routes:
- name: route1
  condition: "1 = 1" # 1 = 1 indicates a condition hit, and 1 = 0 indicates a condition miss.
  backend:
    type: "MOCK"
    statusCode: 200
    mockResult: "Hello World!!!"
- name: route2
  condition: "1 = 1"
  backend:
    type: "MOCK"
    statusCode: 400
    mockResult: "mock resul sample"
- name: route3
  condition: "1 = 0"
  backend:
    type: "HTTP"
    address: "https://test.com"
  constant-parameters:
  - name: x-route-by-hash
    location: header
    value: "route-by-hash"