Monday, December 31, 2012

Some thoughts on service naming / service capability naming conventions (2/2)

This post was created due to a few questions on this topic in my initial post on service and service capability naming in 2009. Elena's questions revolved around concrete service naming (endpoint naming). I had promised Elena a month ago that I would come back to this topic once I could sort out my time so here goes....

Abstract approach first:

Service and service capability naming is driven by the context (purpose) of the service or capability. The service defines the context itself and the capabilities define what you can do within that context.

By this definition, no relation exists between the service or capability name and the transport, end point type, parameters passed etc.

This post conveys the message that regardless of the implementation, transport etc. the name of the service or capability is not affected.

The example in the previous post used, was the Order (entity) service. The 'Order' context defines the actual order service name: 'Order'-Service.

Within the OrderService, a number of example capabilities exist:
- create
- get (or getDetails depending on you naming conventions)
- getHeader
- update
- updateShippingAddress
- cancel (cancels a running order)
- search

This order service apparently has 6 capabilities, following the CRUD approach which is common for entity services. One more #7 capability exists and is used to find orders (Order::search). (Note that the :: notation was borrowed from C++.)

In an object oriented language like C++, method overloading can be used to have several versions of the same capability.

As an example, let's explore the search capability a bit more: the Order::search is defined as:
Description: Search for orders and return a list of orderIDs which adhere to the search criteria.
Input: various (combinations of) search criteria
Output: List of order IDs (list can have 0, one or more results)

Let's take a closer look at this contract:
- The context is always the same for all capabilities: Order.
- The purpose of the capability is searching for orders; this is always the same regardless of how I search (which parameters used).
- The result of the call is always the same: a list of orderIDs is returned

So if all of the above are the same, the only one factor that might change is the way I search for orders (or in technology speak: which parameters I use).

As an example, I can search for orders based on:
- address
- customer lastname/city/DoB
- customer ID.
This means I can search using one of three ways for finding search results.

In C++ this can be solved by method overloading which might allow me to define the following methods (please ignore the syntax I'm just trying to convey a message here):
- Order::search(geoAddress)
- Order::search(Lastname, City, DoB)
- Order::search(customerID)

As you can see in the example above, in C++, although different parameters are used in the method signature, the actual name of the operation does not change. The reason is because context, purpose and result are the same; we're just using different search criteria.

In Web services, the same applies: if context, purpose and result are the same, there is no need to change the service capability name. The concept of method overloading does not exist in web services. This means that, in order to achieve a capability name that does not change, another solution must be found.

A significant difference between C++ and Web services exists (between most OO languages and Web services in general):
- C++ uses parameters in the method signature
- a web service only has one input parameter: the input document 

An example that shows how a capability only has one input document:
<porttype name="OrderService">
  <operation name="search">
    <input message="ns0:searchCriteria" />
    <output message="ns0:orders">
  </output> </operation>
In practice we never talk about input/output parameters when we talk about web services. Instead, we talk about input and output documents. The input/output documents can be complex XML structures and this means that we can still have some flexibility in this area: we can define an input document that allows to take in complex XML search criteria.

Concrete approach:

Following the abstract approach, whenever an actual service is built, the service can be used in various scenarios and implementations.

One of Elena's questions was whether or not there would be one WSDL per service or per service capability? I'm personally fond of one WSDL per service and would only break up if there are size/readability issues or in case there is a security need to now show specific operations in certain scenarios. As a consequence, if you ask me the first generic implementation of a WSDL would be to have all capabilities listed as operations in the WSDL document. So one OrderService.wsdl and multiple operations in the same service. The reason why I'm so fond of this approach is because it reflects the context definition of the abstract approach so beautifully.

Now let's try and solve the method overloading challenge from the first part of this post. If we create an input document for the search capability that looks like this:
  <xs:complexType name="searchCriteriaType">
      <xs:element name="Address" minOccurs="0">
            <xs:element name="StreetName"/>
            <xs:element name="HouseNumber"/>
            <xs:element name="City"/>
            <xs:element name="Country"/>
      <xs:element name="NameAddressDOB" minOccurs="0">
             <xs:element name="CustomerLastName"/>
             <xs:element name="DateOfBirth"/>
             <xs:element name="City"/>
      <xs:element name="customerID" minOccurs="0"/>

we can use any of the three listed possible ways of searching. By adding more restrictions to the XML (not a fan!) you might for example indicate that only one of the three search criteria can be used in any given call).

Different service platform to implement a service

A service inventory can be comprised of hundreds or more services and since service-orientation allows for flexible choices regarding vendor platform etc. can allow for quite a heterogeneous environment. Sometimes by adding or removing new vendor technologies (remember this is like gardening; the service inventory is not a static thing; it grows in certain areas at certain times of the year, and shrinks in others) the implementation of certain functionality might be moved around. If the name of the service would depend on the vendor platform, this would mean that when changing the platform, the service had to be renames with all the cascading consequences (repository retire old service, create new service, fix dependencies etc). Generally speaking a bad idea. The better approach would be to leave the service and capability name the same and use a versioning naming scheme to solve this problem. The new implemented version would not have a major version increase if the service remains compatible (assumed here) and only a limited cascading effect would be noticed (regression testing mainly).

Conclusion: do not couple the name of a service or service capability to the platform or vendor stack on which the service is implemented.

Different language to implement a service

Similar to the previous one if, by coincidence, a particular programming language is used to implement a service, this should not influence the name of the service (capability). Sometimes specific tasks are solve easier in one language than in another for any number of reasons, and the context, purpose and result of the call does not change, so why rename it? Conversely, a service (capability) can be comprised of more than one component and not all of them need to be written in the same language (ie. combination of J# and C#). If the language used to implement a service really mattered, this would be a nice naming challenge...

Conclusion: do not couple the name of a service or service capability to the language or component technology used.

Different transport used on a service capability

Assume that we have a web service implemented using SOAP 1.2. Typically the message is sent on the HTTP transport, but for some capabilities (or for all) we can allow for a JMS based transport if needed. This means that the one service capability can have multiple transports. It does not make any sense at all to create  two capabilities just for this purpose. Modern middleware allows different end points on different transports almost seamlessly. It's the same code that is executed, it is just accessed in another way. This does not at all justify a different name. In the service repository, one might find two transport references with this service:  "HTTP, JMS" but that's all - the service capability is and remains the same.

Conclusion: do not couple the name of a service or service capability to the transport technology used.

Different interface implementation

Assume we have a web service implemented using SOAP. Additionally a REST interface is required. Does that mean I get a searchREST and a searchSOAP capability? The answer is a clear NO! Reason for this is again that it's not a different capability; it is just accessed in a different way. It is still the same context, purpose and result. When looking at how we access these interfaces, these are clearly distinctly different and can be easily identified from each other just by looking a the message contents; no need to create a different capability name for that.

Conclusion: do not couple the name of a service or service capability to the interface implementation used.

Different underlying database

Already addressed in one of the other topics I posted on service abstraction. Regardless of the underlying database implementation, the context, purpose and result of the service remains the same. If we applied principles like standardized service contract and service abstraction, the names of the message and the vocabulary used in the messages themselves we would have already abstracted from ANY implementation aspect, including abstraction from the database technology. If we would expose that this service was implemented on a specific database technology we would cause a number of issues
- we can let a consumer 'assume' it is always this technology - basically not giving us the freedom to evolve the service onto another RDBMS product
- we can create a security risk where malicious consumers can target the service is such a way to abuse any weaknesses in the underlying database to get access to data unintentionally, or worse, change the data in ways we don't like etc.

Conclusion: do not couple the name of a service or service capability to the underlying implementation or RDBMS used.

Different versions of a service capability

Now this one definitely does allow for different service (capability) naming. Just a thing or two that you can pick up from the Web Services Contracts Design and Versioning book by Thomas Erl et al: Make sure that
- a service is versioned
- a service capability is versioned
- compatible changes of a service do not break the contract
- incompatible changes must break the contract - to facilitate this an incompatible version change of a service is accompanied by a service name change and/or a namespace change (to force consumers to change their implementation as well)

So initial versions of the OrderService may be called OrderV1. Minor changes would not be reflected in the name; major changes would be reflected in the name. So only an incompatible change can result in OrderV2 service.

I realize that perhaps this is a bit of cutting corners but it would probably best be covered in another post (working on that post early 2013) as one paragraph would not do the topic any justice.

Conclusion: do not couple the name of a service or service capability to compatible changes to a service.

Conclusion: do couple the name of a service or service capability to incompatible changes to a service.

How can service naming improve discoverability?

Having the same name for a service capability allows us to better discover a capability. If I would try and find the search capability for Order I would find only one I hope:
- When looking a the details of that capability I would find that (coincidentally) the service was implemented as a web service, is executed in a specific context (order) had one purpose (search for specific orders), had one type of result (list of order IDs), had a specific version (ie. 2.1), supports REST and SOAP; supports specific transports (HTTP 1.1 and JMS 1.0), and what the input and output documents are (more is available perhaps).
- I would (depending on access authorization) not be able to see whether it was implemented on the MS/Oracle/IBM or Tibco platform, I would not be able to see what the versions of these platforms used are, and I would not know what the underlying database technology was.

If I would follow the other approach an have a different name for every scenario of a capability, this would also mean that I would have to document equally many service capability profiles etc. Finding a specific capability would also be more complex as I would have to know more about the implementation of a service up-front; Ie. if I would not know up-front which different versions of which attribute (platform, transport) etc. exist, I would not know how to find the capability. To me at least this does not make any sense.

I hope that this post contributes to a healthy understanding of the concerns of service naming and service capability naming. Be aware that this is my view of the topic, and I do realize that probably for each argument why you should or should not change a service (capability) name, a dozen arguments exist to do the opposite. Also I recognize that exceptions may exist which justify a different name where I am arguing for not changing it, I would however treat them as exceptions, not as standard behavior!

- Roger

Thursday, October 11, 2012

Facade or Wrapper or Mediation?

What is the different between service facade, wrapper service and mediation?

So here's the problem- there's no standard definition on each of these and since different groups of people mixed up the definitions of these and then some vendor sauce was poured over it, things start getting blurry.

Let's go back to the basics:
  • facade - a facade is a component that makes a component appear as something else; 
  • wrapper - a wrapper (or better: wrapper service) is a service that wraps a service or system and makes it appear as something else;
  • mediation - a mediation is a component that makes a component appear as something else.
Facade (or Facade Component)

A facade component is a component inside a service that can be used to mitigate for evolving several aspects of a service without the need to change other parts of a service. For example the facade component (or class) can be used to shield:
  • contract from evolving service logic -or-
  • service logic from evolving back end systems -or-
  • offer multiple contracts for the same logic -or-
  • offer a standardized contract for a non-standardized component -etc.
The facade component is the most commonly applied design pattern in the world of service-orientation because this is what allows a service-oriented solution to be flexible and cheaper to manage (on the long term). It is a solution that helps manage the cascading effects of changes to the implementation of a service or a back end. Knowing when to position (even an empty one) facade component up-front is key to the successful application of this design pattern.

Wrapper Service

A wrapper service is a service wrapping another service or system. The service architecture (the infrastructure inside a service) can actually contain (a) facade component(s) to make its magic work. Many services are -if you looked at them conceptually- wrapper services. Ie. an entity service exposing a standardized contract can contain a core service logic component to access a database to access but it would typically also contain a facade component to make that database access logic appear as something more usable from standardized-service-contract point of view. Also application-specific public service which are there to accommodate for service consumers that cannot adhere to our standardized service contract are considered wrapper services. Ideally this kind of a service would wrap the standardized service and make it appear in a way that the domain specific service consumer can understand.

Mediation (or Mediation Component) 

If we look closely at the short explanation of mediation above, we can see that it is the same as for Facade. This was done intentionally to convey an important statement: Mediation is a specific application of a facade; Vendors need to come up with a new "hot topic" now and again - this is the latest greatest commercial name for something that conceptually existed for a long time but is now introduced as the new miracle glue to make vendor products look more attractive. If push comes to shove, mediation should conceptually not be viewed as anything else than a facade component. If we look closely they even exist inside services on most vendor platforms. As a side note: some vendor platforms allow us to place mediation between services, they are then agents placed in the message flow but the purpose of these is the same as a facade component: to make a service appear in a different way. Usually a form of mapping is involved in one way or another.

- Roger

Saturday, September 22, 2012

Speaking at the service technology symposium

September 24th, Marc Schmeetz (Vodafone) and myself will be presenting at the service technology symposium in London, UK.

The topic of our presentation will be on how we improved business and technology alignment in a multi-project programme that lasted for several years.

This cross-expertise programme involved many business units, suppliers, developers, business analysts, architects and stakeholders and was particularly challenging.

For more details please see the agenda and presentation profile at the service technology symposium.

Click here for the symposium web site.

Click here for the presentation abstract.

- Roger

Friday, September 21, 2012

SOA, Separation of concerns and agnosticism (5/5)

Separation of concerns and abstraction

Any service that we build should have a certain level of abstraction. Abstraction comes in many kinds but they are all intended to provide separation of concerns.

As an example. if a service accesses a database and the database has an VARCHAR2() field for a numeric value called DBLADR2FLD, then it should not matter to the service consumer what the underlying datatype and column name of the database field is. In essence the service abstracts from the implementation to prevent this.

Additionally, a VARCHAR2() datatype is a specific vendor technology datatype. The service should also abstract from the specific database vendor technology.

Why we do this can be answered pretty simple and straight-forward: the underlying data model and the database vendor technology can change over time or be replaced by a completely different system or technology, and this should not matter to the consumer of the service. This is the most important reason why we have abstraction. By doing contract-first approach, we can already make sure that up-front no implementation-specific or technology-specific dependency can trickle into the contract and as a consequence into the service consumer logic (see [3])

Another form of abstraction is the quality of service abstraction: not all quality of service information does need to be known to the consumer of a service. Important QoS attributes are the availability and the reliability of a service, how much load it can handle and what the average and peak duration of execution is.

Not important however is the fact that the service had 4 failures in the past hour, as this does not say anything about how it will behave in the future and also it might even make the service look unattractive. In a sense we need to be shielding these kind of runtime concerns from potential service consumers. This can be done by creating SLAs that cover the quality of service in a constructive way with meaningful performance indicators.

Many more types of abstraction can be applied - if I can find some more time I will update this article.

- Roger

Thursday, September 20, 2012

SOA, Separation of concerns and agnosticism (4/5)

Separation of concerns and interoperability

Because the contract must be interoperable we need to define contracts in a technology that is interoperable and preferably vendor-neutral by nature.

We also need to make sure that both the message protocol as well as the transport protocol are standardized as much as possible. Ie. in case we use a message protocol that cannot be supported on a specific platform or a transport which is not supported by all required platforms, this poses us with a significant interoperability challenge. Sometimes both message and transport are coupled (ie. REST), sometimes decoupled (ie. SOAP where the message protocol remains SOAP but the transport protocol can change from ie. HTTP to JMS).

For this interoperability challenge to be resolved we can choose a technology that allows for cross-platform interoperability, like SOAP, REST or plain XML over HTTP. As you can see the standards used in this paragraph are all industry standards. Industry standards are standards that agreed on and have large industry support. As an example, at the time of writing, SOAP 1.1 has more industry support than SOAP 2.0, so although SOAP 2.0 has some improvements over SOAP 1.1, personally still I would prefer the older standard.

Choosing industry standards for the technical contract, the chances of interoperability increase, as multiple different types of platforms would most likely be compatible, despite the platforms being disparate systems.

As a side note, if technology like SOAP is used, the contract can easily be designed first because WSDL (yes another industry standard) can be used to describe the contract in a standardized way (from technology point of view). This would help creating a (separately governed) contract that can be used by both the service designer as well as the service consumer designer to allow for concurrent design and delivery of both service as well as its consumer. 

Tuesday, September 18, 2012

SOA, Separation of concerns and agnosticism (3/5)

Separation of concerns and decoupling

To facilitate standardized contracts, they must be decoupled as much as possible. Decoupling can be achieved by designing the contract first, regardless of technology, back end, consumer etcetera.

A number of different coupling types can be identified. Generally speaking we distinguish positive and negative coupling types. Positive coupling types are encouraged whereas negative coupling types should be avoided. Negative coupling is anything on which the contract can form dependencies. In other words, contract-to-* coupling is considered negative coupling and *-to-contract coupling is considered positive coupling as this reduces the amount of dependencies the contract can form.

A way of achieving contracts independent of consumers and implementation is by designing the contract first. If the contract-first approach is not followed the risk exists that a number of different kinds of negative coupling find their way into the contract.

Now that we have identified positive and negative coupling types, the following can be considered positive coupling:
  • Consumer-to-contract
  • Logic-to-contract
The directly negative coupling types are:
  • Contract -to-consumer (contract depends on one or more consumers of the service)
  • Contract-to-logic (contract depends on the implemented logic’s interface
  • Contract-to-functional (contract only supports specific functional context ie. parent process)
Indirectly another set of negative coupling types can exist, ie:
  • Logic-to-implementation(logic depends on how the logic is implemented)
  • Logic-to-technology (logic depends on the technology on which it is implemented)
Because the contract can depend on the logic, the contract can indirectly depend on implementation or technology. Examples of negative coupling are situations where contracts are generated from implemented components or classes, or components generated to expose a database implementation.

Regardless of the coupling type, any negative coupling type from contract-to-logic will inadvertedly also expose an indirect level of coupling to the consumer of the service. Ie. the consumer might need to populate parts of a message to our service which represents ie. a tablename or fieldname of the underlying back end or database implementation. This will result in unnecessary changes to cascade though our services into the consumers and should be avoided in general.

Again, a fairly simple way of avoiding these kinds of problems is by following the contract-first approach. Another advantage of contract-first approach is that once the contract is defined (and hopefully also standardized as described in section 2), is that delivery streams of both service provider as well as service consumer can make their design and implementations in parallel, as the interface of the service is predefined with a clear purpose, context and meaning. This would facilitate a quicker delivery model than ie. a straight-forward sequential approach where service implementation had to be finished before the contract can be shared. This would benefit any project manager, scrum manager etc. as there is no sequential dependency before the consumer of a service can start designing and developing. This provides flexibility to the project delivery lifecycle.

Monday, September 17, 2012

SOA, Separation of concerns and agnosticism (2/5)

Separation of concerns and contracts

A significant prerequisite for separation of concerns is the fact that contracts are standardized in multiple ways. Aspects that can be standardized on a contract are the data model (service data representation standardization), and the naming and semantics of the services, operations and data elements (functional expression standardization).

Standardizing the contract forces us to separate the concern of contract design from everything around the contract, this is also called decoupling (see [3]).

A way to standardize and independently govern the contract is simply by approaching a service using the top-down approach. 

This is easier said than done, but a few pointers are:
  • Expression of functionality from the viewpoint of business and business processes
  • Naming entities from the viewpoint of the business functional area they support
  • Applying normalization and logic centralization to services
  • Creating the contract-first, only then think about the implementation

Once the contracts are designed first, there is a natural decoupling of contract and logic, as the contract ideally should not expose any implementation details. The separation of concerns is reached specifically by the contract-first approach as this does not allow implementation-specific details to trickle down into the contract.

Saturday, September 15, 2012

SOA, Separation of concerns and agnosticism (1/5)

Middleware and Separation of Concerns

Middleware can exist in many ways but most common approach is either the application service or the ESB approach. Regardless of what platform or technology the middleware is hosted on, the main  purpose of the middleware layer is the same: separation of concerns.

As an example the following picture shows that the middleware decouples the consumer from the back end systems by providing services that act on behalf of the back end. This way the consumer does not need to be concerned with the back end, and the back end does not need to be concerned with who the consumer is or how it works.

Decoupling should be explained a bit further. Two systems are coupled if there is a dependency between the two. What we try to achieve with decoupling is that we try to minimize the amount of dependencies between them.

Separation of concerns can be observed in middleware in many ways but starting with offering services on the middleware platform allows us to wrap back end systems. This then allows us to offer a standardized way of accessing underlying back end systems. Standardizing the access to logic can improve interoperability. To provide increased opportunity of interoperability, we need to understand that we have to standardize contracts. If two systems are interoperable it means that they can easily exchange information, or in other words, cooperate. If we put in lots of effort we might be able to provide a system that has something called intrinsic interoperability.

Intrinsic interoperability is achieved if we have standardized a system in such a way (and if we have built logic in such a way that the interoperability can be supported) that if two systems exchange messages, the messages can be easily understood, without the need for (complex) transformations or translations.

For intrinsic interoperability to be achieved, a number of prerequisites must be met, and even then matters are not easy and require significant amount of attention in the governance area.

Friday, September 14, 2012

SOA, Separation of concerns and agnosticism (0/5)

Separation of concerns and agnosticism

Separation of concerns and agnosticism are two closely-related terms. Where separation of concerns is a term commonly used in object-oriented and component-based technologies, it is a way to clearly separate functional concerns by defining containers (services, classes, components) to identify a functional boundary of the contained operations.

Agnosticism (from the Greek word agnostos) is a term traditionally used in religion-related discussions but also in the world of service-orientation to explain that the service is not aware of, or is not concerned with, the parent functional context. Gnostos means “aware of the existence of”, the “a-“ is a negation making the whole term’s meaning “not aware of the existence”.

Both terms convey a similar concept where we keep concerns of a particular piece of code local to that piece of code only, and not have it scattered across the software infrastructure. The term agnostic however intends to apply to a wider scope than only code or logic, for instance on the contract or on the service as a whole, as well as the entire service inventory structure.

This five-part series touches on several aspects of how separation of concerns can be achieved in a service-oriented solution.

Tuesday, August 7, 2012

Just finished reviewing Thomas Erl's upcoming book SOA with REST

Hi all,

I just finished reviewing the upcoming book SOA with REST, written by Thomas Erl et al.

For more information about this no-nonsense book, see the SOA with REST infopages.

- Roger