Within the world of SOA, services are the building blocks, and at the lowest level of the stack. SOA is an architectural style supporting loosely coupled services that enable the construction of many systems that are technology-agnostic. Services become the base of an SOA, and while some are abstract existing "legacy services," others are new and built for specific purposes. Moving up the stack we then find composite services, or services made up of other services and all services abstract up into the business process or orchestration layer, which provides the agile nature of an SOA. So, back to designing services.
While there are no hard and fast guidelines on what makes up a well-defined and developed service, we do know a few things:
Services are not complete applications or systems. They are a small part of an application. Nor are they subsystems; they are small parts of subsystems as well. Indeed, services are more analogous to traditional application functions in terms of design, and how they are leveraged to form solutions, fine or course grained. Knowing that, we have a better basis of understanding when approaching the service design problem.
Each service has a specific purpose, and they are not complex or naturally dependent upon other services. Thus, they are easily abstracted into composite applications, in essence, leveraging these services as if they are functions local to the composite.
Services should exist with a high degree of autonomy. They should execute without dependencies, if at all possible. This allows you to leverage the service by itself, and design the service with this in mind, no matter how course or fine grained the service is.
Service Design Principles
So, how do you design a service? First, it's important to follow a few basic principles. While following these principles does not insure success, it will clearly send you down the right path.
First and foremost, services should be designed for reuse. Services become a part of any number of other applications, and thus must be designed to provide behavior and information, but not be application specific. This is a difficult paradigm for many developers since custom one-off software is what they've been doing for most of their careers. Thus, the patterns must be applicable to more than a single problem domain or application, meaning you must have use for your reusable service. Else, the exercise is in vain.