SLA and Its Impact on REST API Architectural Styles
As systems are evolving and the wide adoption of microservices, the number of dependencies for a given microservice is ever-increasing, thus impacting the overall SLA.
Join the DZone community and get the full member experience.
Join For FreeIntroduction
REST APIs are the most common way of communication between systems in current scenarios. Though many systems responses are time-critical in nature, where caller expects the response to come back for a given request in defined SLA (Service Level Agreement).
As systems are evolving and the wide adoption of microservices, the number of dependencies for a given microservice is ever-increasing, thus impacting the overall SLA. In order to meet the given SLA, we need to adopt different REST API architectural styles. This article discusses the old way of doing REST with a single bounded context vs. the new evolved way with multiple coordinating bounded contexts.
Context
Let’s take an example of an Instant Payment system where the sender is from sending money from one bank and the receiver is from another bank receiving money and there is a National Exchange acting as an intermediary. Overall, processing from sender to receiver is too big a journey, thus this article considers the receiver and receiving bank journey as a piece out of the above scenario for the rest of the discussion.
Let’s assume the receiver side before actual payment can be credited to the account of the receiver, there may be multiple intermediary steps like:
- Incoming credit request coming from national exchange.
- The receiver account exists.
- The receiver account is active.
- If an incoming transaction is a duplicate.
- The sender is not associated with any fraud/fraudulent agency.
- The amount getting transferred is within the limits of the given day.
- Amount Credit in receiver account hosted in some legacy system.
- Entry of the received funds in the ledger for audit.
- Publishing the transaction to a data warehouse.
All of the steps happen, thus the transaction is considered complete, and the response is returned to the national exchange.
REST Architecture Type 1
Let’s take the above example and divide this into multiple API/endpoints that support the above steps:
API End Point |
HTTP verb/pub-sub |
Comment |
Credit |
Post |
API exposed to National exchange for amount transfer by receiver bank. |
Account |
head |
External system hosting Check account Exist. |
Account |
Get |
External system hosting Check Account Active. |
/searches/transaction |
Post |
Duplicate. |
senderAuthenticity |
Post |
External system Check if the sender is genuine. |
AmountLimitChecker |
Post |
The amount is within the given limits. |
Transfer |
Post |
Amount credit in target account hosted in a legacy system. |
Audit |
DB call |
Log in DB table. |
Publish to Data Warehouse |
Pub/sub |
A single place to get all the transactions of the ecosystem. |
Now in the old world, this all will be bundled in monolith and delivered from the same war/jar. At the same time, all of these APIs and steps 8 and 9 are called sequential and the result is returned back to the caller. There is a challenge with the approach; my national exchange is giving an SLA of 3 seconds to return the response. DBA and Leads team did fine-tuning of their GC and DB queries introduced caching for frequently used data but could not reduce the response time below 15 secs. There is a 5x difference in SLA and current response time. This problem gave rise to a new way of architecting our REST APIs where we can divide the entire transaction journey into two phases with separate bounded contexts to meet the SLA yet doing all.
REST Architecture Type 2
Given the challenge of reducing SLA by 5x, we have to think differently from what was once considered the best approach. Let’s divide the above set of steps in two groups:
Group 1
Services must confirm to the Exchange that the system is good to commit the transaction that we call a phase 1 service called authorize. All those supporting services that ensure the system is good to authorize the transaction are part of the Group 1 service.
The system needs to introduce a new service called authorize to the national exchange this will ensure that receiving bank is all good to commit the requested transaction and can be acknowledged by the National exchange to the sender bank. The second optimization is about identifying the services that can run in parallel. From the above set checking the account exists and the transaction is duplicate or not can be done in parallel so is checking the authenticity of the sender.
Now, when we run all these 3 calls in parallel maximum time taken for all three operations together will be governed by the slowest transaction. With these modifications in architectural styles it will reduce the SLA within permissible limits, apart from this all above optimization related to GC, DB, Caching, still holds true.
API End Point |
HTTP verb |
Comment |
Authorize |
Post |
API exposed to National exchange for amount transfer by receiver bank. |
Account |
Head |
External system hosting check account exists. |
Account |
Get |
External system hosting check account active. |
/searches/transaction |
Post |
Duplicate. |
senderAuthenticity |
Post |
External system checks if the sender is genuine. |
AmountLimitChecker |
Post |
The amount is within the given limits. |
Group 2
These services are bookkeeping services not part of the critical path, thus reducing the overall processing time needed for the transaction. This is put additional responsibility on the system to recover from the failure on itself. As external entity will proceed and not wait for a second acknowledge call since this phase will give the final transaction details to the API and help matching phase 1 call with phase 2 calls for some timeout scenarios where the receiver bank send the response of authorizing but it never reached to the national exchange.
API End Point |
HTTP verb/pub-sub |
Comment |
Acknowledge |
Post |
API exposed to National exchange for acknowledging amount transferred. |
Transfer |
Post |
Amount credit in target account hosted in a legacy system. |
Audit |
DB call |
Log in DB table. |
Publish to Datawarehouse |
Pub/sub |
A single place to get all the transactions of the ecosystem. |
REST Architecture Type 2 Choices and Its Eventual Impact
Type 2 architecture is good at meeting SLA at the same time ensuring the consistent state of the system. But like any other architecture, it is having its own shortcoming. It will have added complexity on both sides caller and calling party, increased number of network calls as now for every single transaction there will be two calls instead of one. The system needs to be self-recoverable as if you see actual credit to the receiver account will happen as a part of Group 2 service and not Group 1; what if the legacy system is not able to commit the transaction? The receiver may see a delay in the credit amount reflecting in its account. Still, type 2 is a better choice than type 1 as it reduces the risk of failure by dividing the processing into two phases instead of one.
Common Traits in REST API Architecture and SLA
As most of the articles cover the Rest API architectures, there is another factor influencing the SLA in rest nowadays is security. One has to be vigilant and do a balancing act about meeting SLA with security requirements. Too much gatekeeping will certainly impact the system performance. One good way of reducing the time of processing is to keep the security layer at the API gateway level and internal APIs can communicate freely with whitelisting of the nodes that can connect to a given service. But the above-suggested approach is only viable provided your security architecture gives heads up on the same.
Conclusion
This article provides different ways in which Rest APIs can be architected to meet the SLA yet satisfy the overall processing requirement. It also compares and contrasts what you lose in case adopt Rest API architecture type 2 instead of Rest API architecture type 1. As this part of the ecosystem is ever-evolving, there are future trends we need to learn and adopt as we move forward.
Opinions expressed by DZone contributors are their own.
Comments