Implementing SOA with RESTful service and application APIs? - rest

At the moment we have one huge API which is used by our backoffice, our frontend, and also our public API.
This causes me a lot of headaches because when building new endpoints I find a lot of application specific logic in the code which I don't necessarily want to include in my endpoint. For example, the code to create a user might contain code to send a welcome email, but because that's not needed for the backoffice endpoint I will then need to add a new endpoint without that logic.
I was thinking about a large refactor to break our code base in to a number of smaller highly specific service APIs, then building a set of small application APIs on top of those.
So for example, an application endpoint to create a new user might do something like this after the refactor:
customerService.createCustomer();
paymentService.chargeCard();
emailService.sendWelcomeEmail();
The application and service APIs will be entirely separate code bases (perhaps a separate code base per service), they may also be built using different languages. They will only interact through REST API calls. They will be on the same local network, so latency shouldn't be a huge issue.
Is this a bad idea? I've never seen/worked on a codebase which has separated the two before, so perhaps there is a better architecture to achieve the flexibility and maintainability I'm looking for?
Advise, links, or comments would all be appreciated.

Your idea of making multiple, well-defined services is sound and really it is the best way to approach this. Going with purely micro-services approach however trendy it might seem, proves to be an overkill most often than not. This is why I'd just redesign the existing API/services properly and follow solid and sound SOA design principles below. Good Resources could be found on both serviceorientation.com and soapatterns.org I've always used them as reference in my career.
Consider what types of services you need
(image from serviceorientation.com)
Entity services are generally your Client, Payment services - e.g. services centered around an entity in your domain. They should be business-agnostic, and be able to be reused in all scenarios. They could be called sometimes by clients directly if sufficient for their needs. They could be called by Task services.
Utility services contain logic you're likely to reuse in other services, but are generally not called by the clients directly. Rather, they'd be called by Task and Entity services. An example might be a Transliteration service.
Task services combine and reuse Entity and Utility services into meaningful tasks. Most often they are not that agnostic and they do implement some specific business logic. They have meaningful business operations and they are what clients mostly call.
Principles to follow when redesigning
I strongly recommend going over this cheat sheet and making sure everything there is covered when you do your redesign. It's great help.
In general, you should make sure that:
Each service has a common context and follows the separation of concerns principle. E.g. Clients service is only for clients related operations, etc.
Each of the Entity and Utility services is business-agnostic and basic enough. So it can be reused in multiple scenarios and context without being changed. Contract must be simple - CRUD and only common operations that make sense in most usage scenarios.
Services follow a common data model - make sure all the data structures you use are used uniformly in all services in order to prevent need for integration efforts in the future and promote combination of services for clients to exploit. If you need to receive a customer that another service returns, this should be happening without the need for transformation
OK, but where to put the non-agnostic logic?
Now, you have multiple options for abstracting business logic whenever you have a need for complex business functionality. It depends on your scenario what you're going to chose:
Leave logic to all clients. Let them combine your simplified services
If there is business logic that is commonly implemented in multiple of your applications and has the potential to be reused heavily you can implement a composite service that reuses multiple existing underlying services and exposing the logic.
Service Composability. Concerns on multiple API calls communication overhead.
Well, this is an age-old question - should you make multiple API calls when they will probably create some communication overhead? The answer is - it depends on how complex your scenario is, how much reuse you expect and how flexible you want to be. Also is speed critical? To what extent? In Service Oriented Architecture though, this is a very common approach - to reuse your existing services and combine them in new configurations as needed. Yes, it does add some overhead, but I've seen implementations in very complex environments, for example Telecoms, where thanks to the use of ESB solutions, message queues, etc the overhead is negligible compared to the benefits. Here is a common architecture approach (image from serviceorientation.com):
The mandatory legacy refactoring heads-up
More often than not, changing the established contract for multiple existing client systems is a messy business and could very well lead to lots of refactoring and need for looking for needle-in-a-stack functionality that's somewhere deep in the (possibly) legacy code. Business logic might be dispersed everywhere. So make sure you're ready and have the controls, time and will to lead this battle.
Hope this helps

Is this a bad idea?
No, but this is a big overall question to be able to provide very specific advice.
I'd like to separate this into 3 areas:
Approach
Design
Technology
Working backwards, the Technology is the final and most-specific part, and totally depends on what your current environment is (platforms, skills), and (hopefully) will be reasonable self-evident to you once the other things are in progress.
The Design that you outlined above seems like a good end-state - having multiple, specific, focused APIs, each with their own responsibility. Again, the details of the design will depend on the skills of you and your organization, and the existing platforms that you have. E.g. if you are already using TIBCO (for example) and have a lot invested (licenses, platforms, tools, people) then leveraging some of their published patterns/designs/templates makes sense; but (probably) not if you don't already have TIBCO exposure.
In the abstract, the REST API services seems like a good starting point - there are a lot of tools and platforms at all levels of the system for security, deployment, monitoring, scalability, etc. If you are NGINX users, they have a lot of (platform-independent) thoughts on how to do this also NGINX blog, including some smart thinking on scalability and performance. If you are more adventurous, and have an smart, eager team, a look at Event-driven architecture - see this
Approach (or Process) is the key thing here. Ultimately, this is a refactoring, though your description of "a large refactor" does scare me a little - put that way, it sounds like you are talking about a big-bang change and calling it refactoring. Perhaps it is just language, but what's in my mind would be "an evolution of the 'one huge API' into multiple, specific, focused APIs (by refactoring the architecture)". One place to start is Martin Fowler, while this book is about refactoring software, the principles and approach are the same, just at a higher-level. Indeed, he talks about just this here
IBM talk about refactoring to microservices and make it sound easy to do in one step, but it never is (outside the lab).
You have an existing API, serving multiple internal and external clients. I will suggest that you'll want to keep this interface solid for these clients - separate your refactoring of the implementation from the additional concerns of liaising with and coordinating external systems/groups. My high-level starting approach would be:
identify a small (3-7) number of related methods on the API
ideally if a significant, limited-scope change is needed anyway with these methods, that is good - business value with the code change
design/specify a new stand-alone API specifically for these methods
at first, clone the existing model/naming/style
code a new service just for these
with proper automated CI/CD testing and deployment practices
with associated monitoring
modify the existing API to have calls to these methods re-direct to call the new service
perhaps have a run-time switch to change between the old implementation and the new implementation
remove the old implementation from codebase
capture issues, assumptions and problems along the way
the first pass will involve a lot of learning about what works and doesn't.
then repeat the process over & over, incorporating improvements each time.
At some point in the future, when appropriate due to other business-driven needs, the API published to the back-end, front-end and/or public clients can change, but that is a whole different project.
As you can see, if the API is huge (1,000 methods => 140 releases) this is a many-months process, and having a reasonably frequent release schedule is important. And there may be no value improving code that works reliably and never changes, so a (potentially) large portion of the existing API may remain, just wrapped by a new API.
Other considerations:
public API? Maybe a new version (significant changes) will be needed sooner than the internal APIs
focus on the methods/services used by it
what parts/services change the most (have the most enhancement requests approved)
these are the bits most likely to change, and could benefit most from a better process/architecture
what are future plans for change and where would the API be impacted
e.g. change to user management, change to payment processors, change to fulfilment systems
e.g. new business plans (new products/services)
consider affected methods in the API
Also see:
Using Microservices for Legacy System Modernization
Migrating From a Monolith to APIs and Microservices
Break the Monolith! Loosely Coupled Architecture Brings DevOps Success
From the CEO’s Desk: Application Modernization – Assess, Strategize, Modernize! 9
[Microservices Architecture As A Large-Scale Refactoring Tool 10
Probably the biggest 4 pieces of advice that I can give is:
think refactoring: small changes that don't affect function
think agile: small increments that are valuable, testable, achievable
think continuous: have a vision for where you will (eventually) get to, then work the process continuously
script & automate the processes from code, documentation, testing, deployment, monitoring...
improving it every time!
you have an application/API that works - keep it working!
That is always the first priority (you just need to work to carve-out time/budget for maintenance)

Not a bad idea at all.
Also what are your looking is microservices arch. and with that the question comes is how you break your system into well defined services.
We use Domain Driven Design Arch. to break our system into microservices and lagom framework , which allows every service to be in diff. code base and event driven arch. between microservices.
Now lets look at your problem at low level: you said a service contains code like creating a user and sending a email and one with just creating a user and there might be other code as well.
First we need to understand how many type of code you are writing:
Domain Object Logic (eg: User Object) -- what parameters are valid and all -- this should be independent of service endpoint and should be encapsulated in one Class like user class and we say it an Aggregate in Domain Driven Design terms
Business Reactions -- like on user creation send a email -- using event driven arch. these type of logics are separated into process managers or sagas which could most cases work conditionally like a for user created externally send a mail and for user created internally send a email , by having extra data in the event
Also the current way you are doing it , how are you handling transaction across services???

Related

Architecture of microservices from a business approach or technical?

Our team is trying to decouple a monolithic spring mvc administrative application (create, update, delete) and we want to adopt an architecture based on microservices.
After a bit of research, it seems the best is create microservices according to the problem that a specific part of the software solves, for example, Managing Clients.
The problem comes when we read some definitions, like the following from Wikipedia:
In software engineering, a monolithic application describes a
single-tiered software application in which the user interface and
data access code are combined into a single program from a single
platform.
Based on that definition, my application is not monolithic, because it is perfectly separated in layers, but it is not found in a micro-services architecture either, which is confusing to me since in the web everything is about Monolithic vs. Microservices.
So, should the microservices architecture be designed based on the business problem it solves?
Should the microservices architecture be designed based on to the way in which the application is organized in layers?
Thanks.
I like to view each microservice as self contained smaller monoliths. When you're forcing yourself to split up your legacy application to, um, smaller monoliths, you'll find:
60% of your code is scaffolding and will need to be repeated across multiple services.
It's easier to split things (and maintain them that way) if you've established a what-goes-where rule upfront.
The most common approach is to split the application by functionality area. So to answer your question, I'd agree more with the image at the top-right, assuming you intended to show multiple containers there.
And about #1 above, there's often a whole bunch of scaffolding modules that you can avoid writing by hand after all.
From my experience, the most obvious advantage of a microservice is the ability to scale horizontally. User analysis takes to long? Just add 10 more workers. Done. Remove then. No need to add more RAM/CPU/whatever to your already costly server that runs your monolith.
Do not plan ahead an try to separate ClientManager microservice - this should be just a class.
You are thinking about migrating to microservices for a reason. Something is using up too much resources. Find the most problematic process that slows everything down, and create microservice for it. It can be for example report generation, user creation, data agregation. Start with planning the API. It will state clearly, what are responsibilities it will have and how much resources it will use. When you know what it should do, name it properly.
Agile software methodologies are your greatest friend in this process. Take the processes one by one. Experiment, iterate and evaluate. With time, it will be obvious how the microservices should do.
There is also a hot topic on how to organize code with microservices - I lean towards a monorepo - a single repository with all the code.
Pros: One pull request for many services, easy utils sharing, common dependencies, common deployment procedure and easier automation.
Cons: You can easily break the API contract and do too much work within one microservice (meaning, it can take other services responsiblity.)

Why shared libraries between microservices are bad? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
The community reviewed whether to reopen this question 6 months ago and left it closed:
Original close reason(s) were not resolved
Improve this question
Sam Newman states in his book Building Microservices
The evils of too much coupling between services are far worse than the problems caused by code duplication
I just don't understand how the shared code between the services is evil. Does the author mean the service boundaries themselves are poorly designed if a need for a shared library emerges, or does he really mean I should duplicate the code in the case of common business logic dependency? I don't see what that solves.
Let's say I have a shared library of entities common to two services. The common domain objects for two services may smell, but another service is the GUI to tweak the state of those entities, another is an interface for other services to poll the state for their purpose. Same domain, different function.
Now, if the shared knowledge changes, I would have to rebuild and deploy both services regardless of the common code being an external dependency or duplicated across the services. Generally, same concerns all the cases for two services depending of the same article of the business logic. In this case, I see only harm of duplication of the code, reducing the cohesion of the system.
Of course, diverging from the shared knowledge may cause headaches in the case of shared library, but even this could be solved with inheritance, composition and clever use of abstractions.
So, what does Sam mean by saying code duplication is better than too much coupling via shared libraries?
The evils of too much coupling between services are far worse than the problems caused by code duplication
The author is very unspecific when he uses the generic word "coupling". I would agree with certain types of coupling being a strict no-no (like sharing databases or using internal interfaces). However the use of common libraries is not one of those. For example if you develop two micro services using golang you already have a shared dependency (towards golang's basic libraries). The same applies to libraries that you develop yourself for sharing purpose. Just pay attention to the following points:
Treat libraries that are shared like you would dependencies to 3rd party entities.
Make sure each component / library / service has a distinct business purpose.
Version them correctly and leave the decision which version of the library to use to the corresponding micro service teams.
Set up responsibilities for development and testing of shared libraries separately from the micro services teams.
Don't forget - The microservices architectural style is not so much focusing on code organization or internal design patterns, but on the larger organizational and process relevant aspects to allow scaling application architectures, organizations and deployments. See this answer for an overview.
Short
The core concept of the microservice architecture is that microservices have their independent development-release cycles. "Shared libraries" undermining this.
Longer
From my own experience, it's very important to keep microservices isolated and independent as much as possible. Isolation is basically about being able to release & deploy the service independently of any other services most of the time.
In other words its something like:
you build a new version of a service
you release it (after tests)
you deploy it into production
you have not caused the deployment cascade of your whole environment.
"Shared libraries" in my definition those libraries, do hinder you to do so.
It's "funny" how "Shared Libraries" poison your architecture:
Oh we have a User object! Let's reuse it everywhere!
This leads to a "shared library" for the whole enterprise and starts to undermine Bounded Contexts (DDD), forces you to dependent on one technology
we already have this shared library with TDOs you need, written in
java...
Repeating myself. The new version of this kind of shared libs will affect all services and complicate your deployments up to very fragile setups. The consequence is at some point, that nobody trusts himself to develop the next releases of the common shared library or everyone fears the big-bang releases.
All of this just for the sake of "Don't repeat yourself"? - This is not worth it (My experience proves it). T
The shared compromised "User" object is very seldom better than several focused User objects in the particular Microservices in the praxis.
However, there is never a silver bullet and Sam gives us only a guideline and advice (a heuristic if you like) based on his projects.
My take
I can give you my experience. Don't start a microservice project with reasoning about shared libraries. Just don't do them in the beginning and accept some code repetition between services. Invest time in DDD and the quality of your Domain Objects and Service Boundaries. Learn on the way what are stable parts and what evolves fast.
Once you or your team gained enough insides you can refactor some parts to libraries. Such refactoring is usually very cheap in comparison to the reverse approach.
And these libraries should probably cover some boilerplate code and be focussed on one task - have several of them, not one common-lib-for- everything In the comment above Oswin Noetzelmann gave some advice on how to proceed. Taking his approach to the maximum would lead to good and focused libraries and not toxic "shared libraries"
Good example of tight coupling where duplication would be acceptable can be shared library defining interface/DTOs between services. In particular using the same classes/structs to serialize/deserialize data.
Let's say you have two services - A and B - they both may accept slightly different but overall almost same looking JSON input.
It would be tempting to make one DTO describing common keys, also including the very few ones used by service A and service B as a shared library.
For some time system works fine. Both services add shared library as dependency, build and run properly.
With time, though, service A requires some additional data that would change the structure of JSON where is was the same before. As a result you can't use the same classes/structs to deserialize the JSON for both services at the same time - the change is needed for service A, but then service B won't be able to deserialize the data.
You must change shared library, add new feature to service A and rebuild it, then rebuild service B to adjust it to new version of shared library even though no logic has been changed there.
Now, would you have the DTOs defined separately, internally, for both services from the very beginning, later on, their contracts could evolve separately and safely in any direction you could imagine. Sure, at first it might have looked smelly to keep almost the same DTOs in both services but on the long run it gives you a freedom of change.
At the end of the day, (micro)services don't differ that much from monolith. Separation of concerns and isolation are critical. Some dependencies can't be avoided (language, framework, etc.) but before you introduce any additional dependency by yourself think twice about future implications.
I'd rather follow given advice - duplicate DTOs and avoid shared code unless you can't avoid it. It has bitten me in the past. Above scenario is trivial one, but it may be much more nuanced and affect much more services. Unfortunately it hits you only after some time, so the impact may be big.
There are no absolute answer with this. You'll always find an example for a reasonable exception to the rule. We should take this as 'guidelines'.
With that being said, yes coupling between services is something to avoid and a shared library is a warning alarm for coupling.
As other answers have explained, microservices lifecycles should be independant.
And as for your example, I think it strongly depends on what kind of logic / responsibilities does the library have.
If it is business logic, something is odd. Maybe you need to split the library in different libraries with different responsibilities, if that responsability is unique and can't be splited, you should wonder if those two services should be only one. And if that library has business logic that feels weird on those two services, most likely that library should be a service in his own right.
Each microservice is autonomous so executables will have its own copy of shared libraries so there is no coupling with shared library?
Spring Boot, packages language run time also in package of microservice
Nothing is shared even runtime so I don't see problem in using library or common package in microservice
If shared library creates coupling in Microservice then using same languages in different Microservice also a problem?
I was also confused while reading "Building Microservices" by Sam Newman

Is REST only adequate for applications with human-computer interaction?

I am fairly new to building applications using the RESTful architecture. As a matter of fact, all I have done so far is categorized as Level 2 REST by Leonard Richardson and that I know Fielding would happily categorize as Non-RESTful.
I have spent hours trying to understand HATEOAS and how to reach level 4. And I see it more clearly now. I conceptualize the application as a series of state transitions, and the resources will dynamically provide links with information on how to move from one state to another.
But everything related to HATEOAS seem to be inherent of a human-computer interaction. I mean, even when the resources provide the links that enable the application user to move to the next state, it is ultimately the user the one that drives the application from one state to the other by causing the use of of the provided links.
But how are things supposed to work when we are dealing with computer-to-computer interaction? After all when it comes to service-orientation the idea of service composition is key, and we cannot naively assume that the client is always going to be a human being? Many services are designed to be consumed by non-human users, and some interactions/orchestrations might be fairly complex, the type of things that are typically modeled with things like BPM, or BPEL.
Is REST and particularly HATEOAS only usable in applications that imply human intervention and if not how is this supposed to work otherwise?
I am getting this vibe that REST is only good for certain type of solutions and inadequate for others, but literature out there has failed to explain those inadequacies and sell REST as the cure of all evil, but I just don't quite get how to use for proper service composition when humans are not the drivers.
I'd really appreciate any references or insights on this, because believe me I have two days straight reading all I have been able to find on this topic and I have not yet being able to reach any reasonable and well documented conclusions.
Well, your client app can parse the response to get possible actions. In this case actual urls are obtained not from knowledge of the API, but upon calling the initial method (usually GET). All human-less.
It sounds almost as if you're comparing SOA to REST/Hypermedia and fail to see that SOA is a strategy, for designing a complex system made out of other systems, while REST/Hypermedia is a software architecture style applying a bunch of constraints on client-server communication. The client, however, can be both a server or a human, it doesn't matter.
To use or not to use REST/Hypermedia is not something to bother with when outlining/designing service composition. It's a question that comes into play when trying to achieve syntactic interoperability. Many times it comes down to comparing REST to Soap and other technical details.

Enterprise Web Application Architecture Question

I am wondering if it would be possible to develop an enterprise-level web application without the use of a standard MVC structure and application server by carrying the business/flow logic and session data to the client-size Javascript and make it talk to REST data services directly...maybe we could make use of an authorization/authentication layer and a second validation layer sitting on top of the data services. All these services operate on standard HTTP methods, support configurable logging&monitoring, and content or query parameters are all contained in the HTTP request/response body. Static HTML and Javascript are served to the browser and the rest is carried out by Javascript functions talking to the HTTP-based authorization/authentication, validation and then data services. Do you think this kind of an architecture could satisfy enterprise-level web application requirements?
It's possible but unlikely; what are the drivers that suggest this architecture to you? Is it just to be different or are there some specific aspects that this best addresses?
by carrying the business/flow logic
and session data to the client-side
Javascript and make it talk to REST
data services directly
In theory you'd still be able to have an appropriately layered solution (Business Logic (BL) script vs UI focused script) but practically speaking it'd be messy, and you'd lose the ability to physically separate it into different tiers. This could "bite" you at any number of places in the life of the system.
"Enterprise" grade systems are seldom small, I hate to think how much logic you'd be having to send over the wire to support a given action/process.
Putting all the BL into a scripting language ties you to that platform, and platforms change over time. The bad thing about scripts is that whilst they are stable to a degree I'd suggest they are more exposed to change than server-based platforms like Java or .Net. In an enterprise scenario, the servers will have very tight change control and upgrade paths mapped out for them - whereas browsers are much more open to regular change.
There's the issue of compatibility - unless you're tied to a specific browser (to the version level) guaranteeing consistent behavior is going to be harder, and will likely require more development effort. Let's say you deliver the solution successfully; what do you do when the business wants to take advantage of mobile computing - say iPads? Your only option is going to be a browser - you won't be able to take advantage of any of the native advantages of the platform. "The web and browsers" might seem like they'll be around forever - but then I'm guessing that what MainFrame folks said at the time. A server-centered solution is going to give you more life for less expense.
Staffing will be an issue - you'll need very strong JavaScript and server-side developers.
Security: having your core BL out on the client where it's much more exposed sounds very dangerous.
EDIT:
Web Apps can be sow for many reasons - not many of which are reason enough to put all your BL in JavaScript on the client. Building apps for performance is a whole field of endeavor on its own - I suggest you get more familiar with Architecting and implementing for performance before you write off n-tier web apps altogether :)
Regarding keeping your layers separated: there are different ways of doing this but it boils down to abstraction - and more correctly to keeping good design principles in mind; if you haven't heard of SOLID that would be a good place to start. In terms of implementation start reading up on Dependency Inversion (FYI - self-promotion, the articles mine and is .Net focused, but you should have no problem tracking down Java-based ones too).

Is WebService the next Big thing?

I was today trying to figure out on working with WebService and found many articles really gospel over the Web Service and its effectiveness in the Market share.
My Questions are:
For a Complex project of critical data, is it better to opt for WebService?
What Makes WebService different from other way of fetching the data?
The answer is... it depends. Web services are not really the next Big thing, they have been a Huge Thing for years now. In business applications, web services allow a big level of interoperability and capabilities never seen before.
They help integration with legacy systems, cooperation between distinct departments, defining loosely coupled interfaces and such. You should read some about Service-oriented architecture.
If all you need is a PHP application that handles data from a single database, you might not need web services at all. If you are designing a solution that revolves around multiple data sources, with complex security involved, multiple languages and/or multiple applications, then web services become essential.
SOAP is a protocol; if working with PHP, you'll need to check out the PHP: SOAP guide to understand how it works. For every language (almost), there are existing APIs to develop web services. Anyhow you might want to check RESTful web services instead of SOAP-based ones, they are generally simpler to implement/understand. But that's another debate ;-).
Cheers.
That mostly depends on the definition of "big thing".
My experience with the WS stack and SOAP and all the acronym soup is that it takes an awful lot of workforce to deploy it. The status of the frameworks is complex, and definitely not something a hobbyist can put to work in a couple of afternoons. We have seen how many things on the net became the next big thing just because they were easy. Easy to understand, easy to interact with, easy in technology. Wikipedia, twitter, digg, youtube are internet big things, and they are, from the interaction point of view, light years away from SOAP/WS based interaction. They are KISS: simple and stupid. A whole horizontal market was opened just because of their simplicity. Even multiprocessing platforms like BOINC don't use anything near the WS stack, but they are the core of many high-throughput efforts.
Now, if you have to deal with complex multi-host transactions, authentication, credential delegation, caching... WS is there. It's the target that makes the need: banks, flight reservation, stuff like this. but they won't impact the common programmer. They require too much energy and too many different competences at once to become something usable for a horizontal market of developers.
Also, I am a REST person. I never advocated SOAP with much emphasis, but there was nothing else and it was a better evolution over XMLRPC (which, if you have to perform dumb RPC, IMHO it's still a good choice). Now I changed my mind. You mostly have resources on the web, and you interact with them with HTTP methods. SOAP is nothing but RPC on hypersteroids. No, REST is not the solution that replaces WS. At all. it's simply easier to use and to debug, albeit more difficult to design (you have to think in terms of resources instead of method calls). It's KISS. That's why it has more chances for success on the horizontal market.
It depends.
Web services can be useful if you need to expose the data across security boundaries, where a direct connection to an RDBMS would be a bad idea.
Popular method for implementing web services nowdays is to use RESTful API (eg. via Ajax/JSON). It's already "next big thing" – almost every major player has been offering it for years. Google, Flickr, Twitter, you name it.
The big advantage is that they help to implement an API layer.
If you implement your solution using a "bus" where the web services sit, it opens up your product to a far greater range of users and moves away from being a proprietary product.
It also enables people to interface using a wide range of solutions e.g web service clients can be implemented using command line, Jsp, Java, Asp, .NET, PHP etc.
They also enable code re-use e.g. if you implement GetClientDetails (ID) as a web service for one user, when the next group comes along wanting the same thing, all you have to do is give them the WSDL and they are away.