Have I got an architecture for you!
It’s cool. We have a set of services that underlie the user interface and collaboration infrastructure. The U/I can be built entirely on services, and the services are independent of one another. On paper, we are isolated and clean.
One problem… some of those services don’t belong in this app!
You see, we are building an infrastructure that will allow integration as a “root behavior” of the app, not an add-on. The app will call services in other systems to get key data. That data won’t be local. So, part of the services infrastructure includes services in other apps.
Those services don’t exist.
Three choices here
- 1. We write a service that drills down to the database of the other app, on behalf of that app. When our project is done, that service becomes part of the other app. To do this well, we need to study the code of the other app, and make sure that our new services correctly implements the business rules that the other app delivers, as well as the data elements.
- We write a service inside our app that turns around and calls an existing integration point. For example, let’s say that the other app routinely exports a flat file. We write code to bring that flat file into DB tables and write a service that presents the data from our DB tables as though it was from that other app. At some point in time in the future, we write a new service, in the other app, that mimics the service we wrote for ourselves. We kill off the data feed at that time. The data is right, but the business rules are simply absent, and the data is mostly read-only.
- We write a stub. This is a service that behaves similar to the way the other app behaves, but the data under it is either entered by hand or manufactured. Entered by hand may be the developers doing a “one time feed” or it may be business users with an interface where they type in data, or support engineers modifying db tables (or even an XML file) that contains the data. Now, our stub had to include business rules that we invent, hoping that we get kinda close to those implemented in the other app, and we make someone jump through data entry hoops.
All three are poor options.
If you want to know why SOA has a hard time taking off, this is it.
Two ways to counteract this, both must be done simultaneously:
- When planning an app, build the services that you “think” others “may” need, even when no one is consuming them. You will be wrong, of course, but it provides a hook for another dev team to create a service that they really do need, and that service calls yours. The other team doesn’t have to learn your business rules, just your protocol. Later, when your project has time, you rewrite your service to meet many or all of their needs.
- When building a consumer app, add the expense to the project to build a formal service in the producer app (option 1). This is best done by finding someone already familiar with the data and capabilities of that app. If you cannot do that, then picking one of the other two options takes on risk. Be prepared to have a follow-on project to clean up the mess you make.
SOA is intentional. In order to build services that others “may” need, you have to know what those services are, before you need them, and you have to know what systems should provide them, so that when funding happens against those systems, you are ready to pounce with a requirement to build the service. That requires you to plan out the interactions between most every system… a complete future state architecture. It doesn’t get much more difficult, or important, than that.