September 8, 2016
When we develop modern web apps and sites, we often find that we need to interact with a variety of back-end services to perform a single task. These may be internal (possibly legacy) services or third-party services, likely accessible over a REST API or SOAP.
Consider a feature that allows a user to search for nearby locations of your business. The client app may need to interact with a service to query locations near a given coordinate, a service to query locations’ hours of operation, and a Google Maps API to provide additional distance or routing information. Assuming all of these services are available on the public internet, the client application could make requests to each of these services and construct its own data model as the responses come back.
Issues connecting directly to back-end services
It may already be clear that implementing all of this logic in the client is not ideal. There are several issues with this approach (and more not listed here).
Your back-end services have to be exposed on the public internet for the client app to have access to them. If these services are fronted with a well-documented API and are designed for public consumption, this may be an option. However, the security around each service will need to be ready to withstand such exposure. More likely, your internal back-end services were not designed to be public. Although many third-party web services provide some sort of authenticated access directly from the client, many rely on secret keys that should never be exposed to the client.
Each service request needs to execute across the client app’s network. We live in a mobile world, and as we know, mobile networks can be slow and unreliable. What happens when one of the requests fails?
The client app has become tightly coupled to the services it currently uses. Consider the effect of swapping the Google Maps API for the MapQuest API. The client is communicating directly with Google Maps and now needs to be updated. The app now has to go through a full release process, including full regression testing and waiting for Apple to approve it. It’s a significant amount of effort for something that amounts to no change in the end user experience.
As you’ve no doubt guessed, an aggregation (or integration) tier is our friend here. An aggregation tier is an architectural layer designed to act as a mediator between the client and the back-end services. It accepts client requests, interacts with the back-end services required to construct an appropriate response, and generates the composite (hence, “aggregate”) response to return to the client. Using this architecture, the client has indirect access to the underlying back-end services. The client doesn’t need to concern itself with the differing APIs or protocols required by the back-end services; that’s the aggregation tier’s job. This layer is also responsible for all of the business logic to construct the final response from the pieces provided by various back-end services. We can utilize this feature to ensure that only the appropriate data (possibly role-based) is returned to the client. Extraneous and sensitive data provided by the back-end services can be stripped out.
An aggregation tier in practice
Let’s revisit the previously identified issues and see how an aggregation tier would make our lives better.
1. Public service exposure
Now, you only need to expose a single endpoint to accomplish the task at hand. (This isn’t to say each and every feature requires a unique endpoint; your own experiences will help guide you.) Your internal services can remain safely behind your firewall. The aggregation tier will need to be available to the client, but it can establish secure connections to the back-end services, alleviating many security concerns. The aggregation tier will simply layer on top of these existing services, requiring minimal (if any) rework to the back-end.
2. Client network stability
You won’t be surprised to hear that your aggregation tier will have superior network access compared to a mobile device (even on WiFi). Executing many requests from the aggregation tier out to the necessary services will be much faster and reliable than issuing the requests directly from the client. Network teams can create server-to-server optimizations that are impossible to replicate from the client. Along these same lines, requests can fail and be retried quicker from the server side. In this way, the client only needs to make a single request over its own network instead of a request per service.
3. Tight coupling between the client and services
As the platform for your APIs, the aggregation tier defines the contract for responding to client requests. As long as that contract is maintained, the client and server are able to evolve separately. Using an aggregation tier in the example moving from Google Maps to MapQuest, the client continues to make the same request to the server for the list of nearby locations (no updates here). The aggregation tier is updated to request map data from MapQuest instead of Google Maps. On receiving this data from MapQuest, the aggregation tier uses it to generate the composite response. The client app is none the wiser to the switch, as it was never tightly coupled to the mapping API.
For non-trivial applications, implementing an aggregation tier can help you meet the security, robustness and maintainability requirements of enterprise-grade software. Contact us to learn more about how PointSource can help you design and implement mobile-ready architectures.