Protecting your APIs with the CircuitBreaker pattern
Imagine you have an PHP backend application (we will call this application as “BootyPark”) that depends on an internal GraphQL API service (we will call this “QAPI”).
You implement and integrate both of them and they both work together forever and happily… Yeah, it’s a pirate world and the sea is a chaos! The service you expect to always return an 200 HTTP status code sometimes will raise this number to something above 500 and that’s when you know that the friendly ship you were waiting so long for, won’t be arriving anytime soon.
Now imagine “BootyPark” receives around 40k requests per second in only one of our 10 markets and it fails every subsequent request to “QAPI” because “QAPI” is either down, still in a scaling-up phase or just overloaded in general (some ElasticSearch reindex is happening maybe?)… Yup, it’s a sea no pirate wants to be. However, here at HolidayPirates Engineering Team love to embrace the sea and it’s chaos!
So how can “BootyPark” protect “QAPI” in this scenario? Enter the CircuitBreaker Pattern for the win!! Yay!
Let’s get more concrete. Imagine your ship shoots a request like this:
$response = $dummyApiClient->sendRequest();
If something goes wrong in here it will throw an Exception and the whole rest of the flow of your operation/application will fail. You can add some exception handling like:
try {
$response = $dummyApiClient->sendRequest();
} catch (\Exception $e) {
$this->logError('Ahoy tis a problem !');
}
But then each request that goes on this flow will still send a request to your “dummyApiClient” which might be having problems.
Now with the CircuitBreaker approach it will be more or less like this:
// Sorry for shortening $circuitBreaker to $cb 🙈if (false == $cb->isServiceAvailable(DummyService::class)) {
throw new \Exception('Service unavailable');
}
try {
$response = $dummyApiClient->sendRequest();
$cb->reportSuccess(DummyService::class);
} catch (Exception $exception) {
$cb->reportFailure(DummyService::class);
throw new \Exception('Service unavailable',0, $exception);
}
Of course you want to add some logging or sending a warning somewhere that this service is down for you (which is what we do), but this is a topic for another post ;).
Oh ‘n by th’ way pirate, we be also open sourcin’ our modern implementation o’ a 2-state CircuitBreaker pattern which ye can see below:
Sources: