Building a Modern Line-Of-Business Application: Part 5 - Business API
Line-of-Business applications contain lots of parts which make the whole things run smoothly. And that's what we've been talking about so far; pieces. We need to start linking things together. That leads us to the Business API.
And that comes with its own planning problems. If we don't take that into account early on, we will run into some of the issues our existing systems have.
What is It?
The Business APIs have two parts: Internal API and Connection API. We'll start with the Connection APIs because they are the easiest to explain. They are what most people think of when they think of an API. These are the routines and processing that are used by ODBC, REST services, JAVA, .NET, PHP, and Python objects.
Connection APIs translate the data from whatever format the database holds it in into the language needed by the receiving process. If a developer is connecting using a REST service, then it might be designed to create JSON or XML from the internal data structure. If the Connection API is used from JAVA, .NET, PHP, or some desktop style language, then the routines are usually used to translate this information into memory objects.
Sometimes Connection APIs are created using native code and other times they are dynamic objects with schema- based definitions depending on the environment. For example, if you are working in .NET, then .NET assemblies can be created to represent the same structure as what REST service would produce.
One of the pitfalls of many existing systems is that the structure, and content, which returns through REST is different than what is returned through JAVA or .NET. This causes a problem with versioning. This restricts what some external applications can do because we may not have provided the same features from connection type to connection type. Any differences should be intentional, not accidental.
Connection APIs should contain your actual business rules. This is where the Internal APIs come in. They should be translating the internal structure to the structure needed for the Connection API.
These routines are what the developers are used to writing. Our Internal APIs are our actual business rules. You use them within your LOB application already. In a MultiValue system, these are generally subroutines. They can interact with each other, be called from each other, process data, change data, update data, create additional processes; anything but transmit data outside of the system.
What about EDI and transmitting e-mails from your business systems? We still consider those as Connection APIs because their primary purpose is to transmit and receive data; we can see them as separate events, sending notifications to people or outside processes from your business systems. They may or may not be powered by your database engine.
If you remember from my first article in this series, we were talking about the background processor and the asynchronous processor. Separating the two types made the work of development easier. Likewise, if you keep the notification processes and the data transmission processes separate from the Internal APIs it becomes easier to modify and replace either side when they have to evolve beyond the current requirements.
I'm going to steal an idea from JAVA and .NET here. Both languages have a concept called namespaces. In these environments, the namespace is used to group functions and methods together; or at least that is what it looks like on the surface.
Namespace Core.Accounting Sub CreateCustomer() Function GetCustomerAvailableCredit() Sub UpdateCustomer End NameSpace
The reality is that a namespace is really a compiler prefix. The above would compile into:
Call Core.Accounting.CreateCustomer Call Core.Accounting.GetCustomerAvailableCredit
This namespace idea has been used in several different programming languages for a reason. When building a system that allows for customization, it is very important to make core and vendor processes which can be overwritten as needed but still keep the existing functionality. Namespaces allow you this sort of re-use of an action name (for example, CreateCustomer) in both a standard way and, when needed, in a variant way. This allows you to set rules for how you create a customer while still giving you a controlled way to make exceptions. This is the concept of code isolation.
Core.Accounting.CreateCustomer() Nathan.Accounting.CreateCustomer() DotNet.Accounting.CreateCustomer() REST.Accounting.CreateCustomer()The example above shows how the namespace name would change based on either the customization or connection specific API.
Why do This?
Creating routines this way seems like extra work, but in the long run, it will help you manage your code as you move forward. You have to plan for the fact that the LOB applications are very long lived and very complex. Interfacing with the next generation of features will be a constant challenge in any healthy business. We need to spend the extra effort up front if we want to enjoy the downstream benefits.
Connection API Planning
The power of any LOB system relies on the ability to access, update, and process the data that is collected by the user. Connection APIs are important in this because they are the collective term for all of the ways we get the data into and out of our LOB system. In our increasingly interconnected world, much of its data is generated from outside the LOB itself.
If you provide a .NET assembly to access your data, then you should be prepared to provide a PHP and Python module to access the business data because the request will come. Your trading partners, the people you exchange data with, will especially appreciate it if you form these APIs into SDKs (Software Development Kits) by adding documentation and standardizing as may parts as possible.
Now, there are some very special processes, like EDI, which might not be attached to a specific internal process. The data used to generate the information for these processes should still be available through all Connection APIs.
Segregating Connection APIs from the rest of the system allows developers to focus on interchange without having to understand your business logic. Internal APIs hold the business logic apart from the connectivity. The Internal APIs process what the LOB needs and what the Connection APIs need. This provides more flexibility when dealing with connections to other applications.