As alternative modern development platforms, such as SalesForce Lightning, Mendix and even analytics platforms like R proliferate, the role and value of API's can be a critical component to unleash their full potential. While these platforms promise rapid application development by trading off the amount of freedom developers have to "go off the rails" of the framework and enable developers to become productive more quickly by limiting the amount of onboarding and knowledge required to rapidly deliver applications on the platform, the use of “Experience” API's are a foundational component to rapidly deliver applications by exposing data in a ready-to-consume manner.
A tradeoff with these highly prescriptive frameworks, however, is the corresponding difficulty for developers to go "under the hood" to handle inevitable edge cases that occur during software development, "shoe-horn" data into the platform and conduct non-trivial performance tuning, clustering and caching. In order to fully achieve the potential of these new modern paradigms, it it is very important that enterprise data is surfaced in such a way that is easily consumable by these platforms and the developers using them.
Using Experience API's to Expose Data to Front End Applications
In my previous blog post I discussed how System API's can be used to surface otherwise hard-to-access data from systems-of-record in a way that's easily consumable by generalist developers and that protects these systems-of-record from unintended changes (i.e. an Anti-Corruption Layer). For applications delivered using traditional development stacks (Java, .NET, Node, etc) these API's might be sufficient. Some platforms,however, may not provide the right abstractions to query, transform and otherwise massage the data coming from these services. Developers building apps using these platforms may not be comfortable composing data from various API's together. Composing data from API’s can be non-trivial, as developers need to know how to:
- Effectively query the API - depending on its quality, varies significantly between API’s.
- Negotiate different API protocols - While most modern API’s are REST and JSON based, XML based SOAP API’s are still prevalent in many enterprises.
- Transform data - Programmatically manipulating different data structures together can range from trivial to extremely complicated.
Even for sophisticated developers using a traditional stack there's an argument to be made against tightly coupling UI/UX logic to backend systems (see https://blog.omni3tech.com/2018/07/29/system-apis-an-enterprise-acl/ for the inherent dangers and how to mitigate those dangers with an anti-corruption layer (ACL)) .
API-Led Connectivity proposes Experience API's as a solution to this problem. Experience API's compose data from services "underneath" them and presents it in a way that is easily consumable for a particular engagement channel. This pattern is useful for frameworks that have limited data transformation, composition and integration functionality by presenting data in such that its easily imported or defined in these tools. It’s also useful for more sophisticated frameworks by limiting the amount of "plumbing" logic coupled in the code (ie, integration logic conflated within UI/UX code.)
The following diagram illustrates how this pattern might be applied to Salesforce's Lightning Connect platform:
In this example we have a custom Lightning Component with its corresponding Lightning Controller. The Lightning Controller uses the Apex HttpRequest class to invoke the Experience API via an HTTP GET. The Experience API is composing data from two System API's and is formatting the response in JSON so it can be used immediately by the Lightning Component without any kind of transformation performed in the Lightning Controller. This frees the Lightning developer from the following concerns:
- Having to know/understand which System API's to call
- Having to compose the data from the System API's together
- Having to transform the composed data so that the Lightning Component can display it properly
Provided the API is suitably documented (ie, via an API Portal) then it should be trivial for the application developer to consume and expose the API's response for their application.
Domain Events to Signal State Changes
Experience API's behave just like any other REST-ful API, potentially exposing the full range of HTTP methods. This provides an opportunity to expose more then just read-only or query capabilities, including operations that mutate state. State changes, particularly in regards to systems-of-record, are complex affairs involving compensating transactions, retry logic, complicated exception handling, etc. This will almost certainly be the case if the Experience API needs to update multiple systems-of-record.
For these scenarios we can borrow the Domain Event approach from the Domain Driven Design Patterns. In the event of state change, for instance HTTP PUT or DELETE invocation, the Experience API will broadcast a Domain Event over an asynchronous messaging channel (JMS, SNS, AMQP, etc.). Interested System API's subscribed to this channel will then be able to update their own state once they receive the message.
To extrapolate from our previous example lets assume the Lightning Component needs to send an update to the Experience API, say to update a Customer's address. The diagram below depicts this behavior:
The HTTP POST from the Lightning Component will trigger the Experience API to publish a message to a publish-subscribe channel on the messaging broker. The interested System API's will subscribe to this channel and update their own state appropriately. This frees the Lightning developer from the following concerns:
- Having to understand which systems-of-record or System API's need to be updated for a given state change
- Implementing transaction or compensating transaction logic
- Implementing retry logic if the System API is unresponsive
- Implementing error handling logic
This choreographed approach works very well for data that can tolerate eventually consistent updates.
Experience API's unleash developers to rapidly deliver applications by exposing data in a ready-to-consume manner. Through the use of Domain Events and Asynchronous Messaging, complicated state changes can also be abstracted from both the application developer as well as the implementation of the Experience API. This ultimately unlocks the full potential of modern, rapid development platforms.