Another fundamental technical detail you have to decide upon is which data types and programming paradigms to use to exchange data via services. As discussed in Chapter 4, this issue is influenced by concerns about loose coupling. The more complex data types and programming models you introduce, the more tightly coupled the systems will be.
Harmonizing data types over distributed systems is a common and natural goal, because it simplifies data sharing. Be careful, though—once you have introduced a new fundamental type, you will probably never be able to get rid of it.
In one project, we defined the generic list for future technical data having a key, a value, a type information for the value, and some additional attributes that allow giving additional hints on dealing with this value (e.g., one attribute allowed to define that service providers should pass this data through when they call other services while processing a service call).
You should clearly differentiate between fundamental data types (FDTs) and common data types:
Fundamental data types are simple and stable, so no versioning is provided for them. For these types, code generators and adapters have native behavior and implementations.
Common data types might change over time, so versioning is required.
In practice, being conservative when specifying fundamental types usually pays off. But don't be too extreme and provide only a string type. I recommend starting with these fundamental ...