Circuit Breaker in API Connect
A Circuit breaker pattern is becoming a common pattern for remote calls today. The purpose of the circuit breaker is to detect when a series of errors are returned and block traffic for a time period, thus giving the backend system time to recover.
APIC Flow
In API Connect there is no out of the box Circuit Breaker pattern but we can build a system that can do a similar function.
This assembly flow is made up of four policies, three ratelimits and an invoke. The first ratelimit policy will increment (consume) the counter by one, this exists so we can terminate the request if the rate limit is reached prior to the invoke being made. The second ratelimit policy is used to reduce (replenish) the same counter so we don’t impact the counter prior to errors being returned. The invoke is used to call the downstream system and is configured to stop the flow when an error is returned. The ratelimit policy in the catch block will only be reached if the invoke is unsuccessful, it then increases (Consume) the rate limit counter by one.
The criteria for the rate limit must be defined in DataPower. I recommend this is set to an apigw object via a GW extension.
Sample DataPower Config for creating the Rate Limit
The below will create a rate limit of ten per second.
sw apiconnect;co;
apigw apiconnect;
assembly-rate-limit errorcount 10 1 second on off on on off off na 1 ;
exit;
exit
**UPDATE 31/8 ** Thomas Burke correctly suggested that developers may prefer to detect the failure by using a switch case to look at the response code from the invoke rather then throwing an error. This is an excellent idea and so I wanted to highlight it here.
Sample API
swagger: '2.0'
info:
version: 1.0.0
title: ErrorLimitting
x-ibm-name: errorlimitting
basePath: /errorlimitting
x-ibm-configuration:
properties:
target-url:
value: https://httpbin.org/422
description: URL of the proxy policy
encoded: false
cors:
enabled: true
gateway: datapower-api-gateway
type: rest
phase: realized
enforced: true
testable: true
assembly:
execute:
- ratelimit:
version: 2.2.0
title: ratelimit
source: gateway-named
rate-limit:
- name: errorcount
operation: consume
description: as
- ratelimit:
version: 2.2.0
title: ratelimit
source: gateway-named
rate-limit:
- name: errorcount
operation: replenish
- invoke:
title: invoke
version: 2.0.0
verb: keep
target-url: http://httpbin.org/status/422
follow-redirects: false
timeout: 60
parameter-control:
type: blocklist
values: []
header-control:
type: blocklist
values: []
inject-proxy-headers: true
persistent-connection: true
finally: []
catch:
- errors:
- ConnectionError
- PropertyError
- JavaScriptError
- SOAPError
- OperationError
- BadRequestError
- RuntimeError
execute:
- ratelimit:
version: 2.2.0
title: ratelimit
source: gateway-named
rate-limit:
- name: errorcount
operation: consume
activity-log:
enabled: true
success-content: activity
error-content: payload
paths:
/:
get:
responses:
'200':
description: success
schema:
type: string
consumes: []
produces: []
put:
responses:
'200':
description: success
schema:
type: string
consumes: []
produces: []
post:
responses:
'200':
description: success
schema:
type: string
consumes: []
produces: []
delete:
responses:
'200':
description: success
schema:
type: string
consumes: []
produces: []
head:
responses:
'200':
description: success
schema:
type: string
consumes: []
produces: []
patch:
responses:
'200':
description: success
schema:
type: string
consumes: []
produces: []
securityDefinitions:
clientID:
type: apiKey
in: header
name: X-IBM-Client-Id
security: []
schemes:
- https
Useful links
- https://www.ibm.com/docs/en/datapower-gateway/10.0.x?topic=processing-api-rate-limit-action
- https://www.ibm.com/docs/en/api-connect/10.0.x?topic=connect-understanding-rate-limits-apis-plans
- https://www.ibm.com/docs/en/api-connect/10.0.x?topic=policies-rate-limit
- https://www.ibm.com/docs/en/api-connect/10.0.1.x?topic=environment-extending-gateway-server-behavior