Integration is a complex subject, covering many areas:
- Unified API: app developers need APIs that hide the complexity of data in multiple locations, without requiring multiple calls that reduce performance
- Data Synchronization: Enterprise databases need to share information, with synchronization between systems that store common data
- RESTful services: business logic can be simplified by leveraging existing software, e.g., address validation
- Existing software: business logic should be able to leverage the investment in existing software libraries
The following sections explain how Espresso makes it easy to address these.
There are a few key elements of Espresso we need as a background for exploring integration.
Espresso as RESTful Server
Espresso is built on REST, which is a great start. So, out of the box, your other Servers can make RESTful calls to Espresso servers to Get data, and Put/Post/Delete it, all subject to logic and security.
Not only is Espresso a natural server, it enables you to invoke other RESTful services, whether for unified API, or for update processing to address Data Synchronization and utilization RESTful services.
Espresso is not simply a SQL pass-through. In addition to the logic and security enforcement, it also provides point-and-click means to define Resource Endpoints that provide document-oriented (tree) JSON responses.
Taking a pure SQL example for the moment, .
You can connect your database to Espresso, and define the following Resource simply by selecting tables.
The system automates the joins from the Foreign Key, which you can override.
This creates a fully executable Resource, which returns a result as shown here.
Observe the Customer data (lines 7-8) includes Orders data (lines 9-18). Both lists are paginated.
This screen show is taken from Espresso's built-in RESTLab test facility, but could also use Curl or any other tool.
Espresso Resources (Endpoints) provide a powerful document-model based API that is easy to call, with functionality for joining multiple tables, projecting the desired rows and columns, and aliasing names for a clean API. These services extend beyond relational data, so you can define Resources that combine data from multiple sources, like this:
So, if you are starting with no existing API, you simply connect Espresso and define the Resource above, and you are optional.
The example illustrates its easy to invoke an existing API. But what if one does not exist? No problem - just
- stand up an Espresso server for the target database, which provides a RESTful API.
- Create a Resource that returns the desired data, using the join, project and alias functionality described above
- Call it as shown in the example above
Experience has taught us that large, single corporate databases prove cumbersome to design and iterate. It is typically better to create databases that address a single function, and share data as required.
Such sharing might be performed without replicating data between databases, as in the example above. On the other hand, if the shared data is required to complete transactions, it may be better to synchronize copies it between systems. There are a number of implications:
- Business Objects: Synchronization typically involves business objects comprised of multiple rows, such as a customer and their addresses
- Transformations: Table and column are typically not the same between systems, so a translation layer is required for name mapping
- Update logic: updates must be trapped and analyzed, to see if they require synchronization. Such logic should be replicated in each client
Espresso makes this really simple. Let's consider two cases: client (where we send synchronization messages), and server (where such messages are sent).
In this scenario, updates to Espresso data are to be transformed and sent to a remote system. That is simple to accomplish:
- Transformation: Create a Resource that matches the remote system names for objects and attributes. Note this can be a Business Object - set of related rows. It's called
cust in the screen shot below.
SysUtility.getResource to create a JSON string, per the format of the Resource created in step 1
- Send it to the remote system, either by a direct POST, placing it on an Enterprise Service Bus, or using a guaranteed delivery service.
Conversely, your Espresso system can also play the role of server, that is, receiving changes from a remote system. In the simplest case, you can just
- Define a Resource matching the format of the incoming message (again, cust in the example above)
- When that Resource is Posted, Espresso will perform the Translation and insert the data - including any associated business rules.
While simple, there is a subtlety we must consider. While we may want to Post the data the first time, what about subsequent changes from the remote system?
We could ask the remote system to issue a Put instead. While that works, it's not really reasonable for them to "remember" which related system has received what data.
So, Espresso provides an
MergeInsert feature, where a Business Object payload can be inserted if it does exist, and updated if it does. Espresso provides the ability to define your match logic, and runs the business logic associated with the updated data.
REST Service Integration
Data Synchronization is useful, but the advent of RESTful Web Services has ushered in an exciting new era of service that are very useful in applications: address validation, credit checks, etc. These are extremely useful in business logic.
oldRow, so you can invoke such services under the proper conditions (e.g., only when designated values change).
Existing Software Integration
The final piece of the integration puzzle is the library of software assets your organization has been accruing for years. Espresso preserves this investment: