This topic describes how to implement a canary release for the new version of APIs in API Gateway before these APIs are officially published. An A/B test is a good practice to implement a canary release. You can configure the routing plug-in to control the publishing scope of the APIs.

1. Overview

A canary release allows you to upgrade APIs with the minimum impacts on users. If you want to upgrade APIs in API Gateway, you can publish the APIs of the new version in a small scope for verification before you officially publish them. This ensures stability of your online services and limits the impacts of the upgrade to a small number of users. After you verify the functions, performance, and stability of the APIs based on collected user experience data, you can publish these APIs to all users.

In most scenarios of canary releases and A/B tests, users are identified based on their information. Specifically, the routing plug-in provided by API Gateway identifies users based on a parameter in HTTP requests that call the APIs, for example, the userId parameter. Then, the plug-in distributes the requests to different backend services based on configured logic conditions.

2. Typical scenarios

You can configure request distribution conditions in the routing plug-in based on the following scenarios:

  • Distribute requests based on the apps authorized by API Gateway. Different apps identify different API callers. You can configure the routing plug-in to distribute the requests of different apps to different backend services. For example, an API is authorized to multiple apps. When it is upgraded in one of the backend services, you can configure the routing plug-in based on section 3.1 to distribute API requests from two of these apps to the upgraded backend service. This allows you to limit impacts on online services to a small scope.
  • Distribute requests based on a JSON Web Token (JWT) claim. If a JWT is bound to an API, API Gateway can parse an unencrypted claim that identifies users from the JWT token, such as userId. Then, the routing plug-in distributes API requests to different backend services based on the claim. For more information, see JWT authenticationYou can bind a JWT to the API and configure the routing plug-in based on section 3.2. In the example in section 3.2, 20% of the requests are distributed to the upgraded backend services based on the last number in the value of the userId claim.
  • Distribute requests based on a user parameter in HTTP requests. If the query, form, or header of the requests carries a parameter that can be used to identity users, the routing plug-in distributes the requests to different backend services based on this parameter. For example, the client version of some users is not the latest, and you want to prompt them to upgrade the client. You can configure the routing plug-in based on section 3.3.
  • Distribute requests based on source IP addresses. The routing plug-in can distribute requests to different backend services based the source IP addresses. For example, you want to use the same frontend code in both the test and production environments. You can configure the routing plug-in based on section 3.4 to direct users from the test and production environments to different backend services.

3. Configuration

This section describes how to configure the routing plug-in for the scenarios in section 2. After you bind the configured plug-in to the API, requests that match the conditions are distributed to the backend service specified by the plug-in. Requests that do not match the conditions are forwarded to other backend services. If you want to direct users to more than two types of backend services, you can configure multiple routes in the Plug-ins of the Routing typeYou must define parameters used in conditional expressions of the plug-in based on Parameters and conditional expressions.

3.1. Distribute requests based on the apps authorized by API Gateway. If you want to distribute requests that call the API authorized to some apps to the test backend service, configure routing policies based on the CaAppId parameter.

---
routes:
-  name: appGrey
   condition: "$CaAppId = 4534463 or $CaAppId = 86734572"
   backend:
      type: HTTP
      address: "http://example-test.alicloudapi.com:8080"
      path: "/web/xxx"
      method: GET
      timeout: 7000    

3.2. Distribute requests based on a JWT claim. Assume that you have specified a JWT claim userId, and the last number in the value of userId is evenly distributed. To distribute 20% of users to the test backend service, perform the following steps:

  • Bind a JWT to the test API.
---
parameter: X-Token         # Obtain the JWT from the specified API parameter.
parameterLocation: header  # The location to obtain the JWT. Valid values: query and header. If the API works in mapping mode, this parameter is optional. If the API works in passthrough mode, this parameter is required.
claimParameters:           # Map the JWT claim to a backend parameter.
- claimName: userId        # The name of the claim. The claim can be private or public.
   parameterName: userId    # The name of the parameter mapped to the claim.
   location: query          # The location of the mapped parameter. Valid values: query, header, path, and formData.
#
# The public key in the JSON Web Key (JWK).
jwk:
   kty: RSA
   e: AQAB
   kid: showJwt
   alg: RS256
   n: gNHI8tm3lnsdCi09SrBPs9-Oau7Z1SFhIEOT2h5AJ49FSJA0XEyU4OadtV70BLIEy94dzcUK8f0e477AVoUO0RZdcXjztFtpJnA1Ktrzn9zAmKcXb2IuKXrBKkQStcKqoSbBlR84mDElp_gxfNqpmoLy0q08rkmjh1utd8E_S4QMDDaFtQ68ggJcDY-oX5FSiVidKNrKagEzQKpk5SgJFE8wpJOkW-YKouqLsL5lFyqnkgn7J3MvDqEBKqgiCY-zXYaxnkLNfkrAt7jTe4b4a2PiKD0-bHIZwzd2NVhuLGwx4pB1tFL51E-KeewZhTsoUbQ3v_ZerZ2_630WOH7IWQ
  • Add userId as a custom claim to the payload of the JWT. For more information, see Implement OpenID Connect authentication by using API GatewayAdd an X-Token field to the header of requests that call the API. Set the value of X-Token to the ID token that is generated when the private key in the JWK is used to validate the JWT signature.
  • Configure the routing plug-in and bind it to the API. The plug-in can distribute requests in which the value of the userId parameter ends with 0 and 1 to the test backend service. These users account for 20% of the total.
---
parameters:
    userId: "Token:userId"
routes:
-  name: userIdGrey
    condition: "$userId like '%0' or $userId like '%1'"
    backend:
       type: HTTP
       address: "http://example-test.alicloudapi.com:8080"
       path: "/web/xxx"
       method: GET
       timeout: 7000

3.3. Distribute requests based on the client version in HTTP requests. The following example shows an HTTP request to call the test API:

http://example-cn-hangzhou.alicloudapi.com/testJwtShow?clientVersion=1.9

Configure the routing plug-in to distribute requests in which the value of the clientVersion parameter is smaller than 2.0.5 to the test backend service.

---
parameters: 
   clientVersion: "Query:clientVersion"
routes:
-  name: oldVersionClient
    condition: "$clientVersion < '2.0.5'"
    backend:
       type: "MOCK"
       statusCode: 400   	

3.4. Distribute requests based on source IP addresses. If you want to direct internal users to the test environment and external users to the production environment, you can distribute requests based on the users' source IP addresses. In the following configuration, the routing plug-in distributes requests from 106.11.31.0/24 to the specified backend service based on the system parameter CaClientIp in API Gateway:

routes:
-  name: InternalTesting
    condition: "$CaClientIp in_cidr  '106.11.31.0/24'"
    backend:
       type: HTTP
       address: "http://example-test.alicloudapi.com:8080"
       path: "/web/xxx"
       method: GET
       timeout: 7000