An exercise in designing SOA systems
This question came up in the NServiceBus mailing list, and I think it is very interesting question to try to solve. The standard disclaimers are that I haven't build a real system using this approach, although I am leaning toward it more and more.
I would like to thank Brad for agreeing to post this example here.
I would like some advice as to how to properly identify the services I need to create. I know that Udi has said that creating services for each department is a good starting point, but I keep feeling like something is missing.
So, here's some details. I work for a company that is the parent of two physician job placement companies. The parent company would like to create a single system that will support both child companies. The business processes of both companies have been analyzed and documented, and there is about a 95% overlap in the processes. Should my team create a monolithic job placement application and wrap it in a service or should I break that application into higher-level business services?
Here's an example of where I get stuck when trying to map the job placement application's functionality to a high-level business service like Sales Service. The Sales department is broken into two groups: marketers and recruiters. Marketers call hospitals to find out what positions are available and try to fill these positions. Recruiters call physicians to find out if the physician is looking for a new job and tries to find available positions. Before a physician can be placed, his or her credentials must be verified. The Credentialing department is responsible for doing this.
Ok. So I now have two service candidates (Sales and Credentialing). I have no issues with the credentialing service but the sales service feels like it should be a job placement service. What if the business decides to take on a new line of business? This new line-of-business may have the sales department selling something entirely unrelated to job placement services. Is a job placement service a better idea? But wouldn't that mean that all job placement functionality would need to be placed in that service? This feels like I'm loosing the agility that SOA gives the business because I'm no longer modeling the way the departments interact with each other.
I once built a system with very similar concepts, although with drastically different focus. What Brad has already outlined is a good start, but I would break the system even further. We have two main sections of the business that were identified, marketing and recruitment. Let us attack the problem from each side in turn, but keep in mind that we are talking about a single system here.
High level services:
- Available candidates - given a set of requirements, will attempt to find all verified candidates that match the requirements. Additional responsibilities include logging search history (important for noticing what requirements are common and desirable), and recording which requirements has no matching physicians in the system (should be passed for human inspection, to decide if head hunting should begin, or this should be ignored).
- Register open position - enter a new position into the system, with all its requirements. As part of the registration, it will query the available physicians and offer them as matches. If there are no matches, it will register the new position in the recruitment service.
- Register new candidate - enter a new candidate to the system in unverified state. Request credentials verifications from the system.
- Verify credentials - given a candidate, perform a verification of the candidate credentials, references, etc. If the verification succeeds, we move the candidate to the available candidate pool. If the verification fails, we request additional intervention.
- Problematic credentials resolver - there are several reasons for getting problematic credentials, fake credentials, honest mistakes and hostile employers are just a few that comes to mind. In most cases, you need complex logic or human intervention here, and it deserves its own section in the map.
- Candidate hunger* - which candidates are we looking for, this is used by the recruitment guys to know which candidates they should aim for.
- Candidate tracker - if we already assigned a candidate for a job, we already have a happy person, let us keep it this way by ensuring that they remember us, so when they leave, they will contact us again for their next job.
- Potential candidates - given a set of requirements, will attempt to find all candidates that match them. Potential candidates are usually candidates that were gotten from external data sources (the physician listing for the country, for instance), so you want to go through them to see if they can become real candidates.
Those are just the services that I can think of off the top of my head. Notice that each of them has very few responsibilities, and they match pretty closely a specific business scenario. The services communicate between one another, but they do so using one way, async messaging. This is especially important in this type of scenario, where some services can take long time to process a piece of work (verifying credentials requires a human to call and ask for references, for example).
My next post will deal with the actual code for one of those services, for now I think this is enough.
* It was originally a typo, but I like the implications.
Comments
His question seems like a question of granularity. SOA can be defined as the underlying services that are then tied together by some business processing layer to form 'business' services for doing work. I personally like the way that you broke the services down into 'smaller' loosely coupled items. The challenge would then be to write a larger business process that maps onto what the business units are doing that utilizes these lower lever bits of work in order to make it 'make sense' to the business.
Nice post. Thank you for allowing my $0.02.
Joe Campbell
There are some problems with the services proposed in this post. For example, the "Available Candidates" service appears highly data centric, likely exposing search/data retrieval operations. CRUD interfaces are bad. Moreover, this service would likely have synchronous request-reply interactions in order to retrieve data or perform searches, and that too is bad.
The services proposed here are also too fine grained. A number of these services will share business logic and data representation. For example, the "Available Candidates" service and "Register Candidate" service both deal with candidates as part of the Recruitment process.
As such the suggested services should be combined into fewer services so that we do not get duplication of business logic and data representation between services.
With regards to defining your services, you need to look at the business context. You want your services to have loose coupling and high cohesion.
To me it seems you should have a Sales service which supports the business processes around finding available positions for physicians.
You should also have a Recruitment service which supports the business processes around finding physicians to fill the roles identified by the Sales service.
I know in your example that the Sales department performs the Recruitment function, however in my view of standard business processes, Recruitment is a distinct function quite independent of the Sales function; involving quite distinctly different business processes and concepts. This makes them good candidates for separate services.
Since you have a separate credentialling department, I would agree with your assessment that you should have a Credentialling service as well.
If anyone is looking for further guidance on SOA design principals, feel free to check out my blog (http://bill-poole.blogspot.com/) .
Comment preview