Jason Bloomberg’s recent post - Are Services Nouns or Verbs? - discusses whether services should represent verbs or nouns.
It's possible to design Services either way, as Entity Services, which predictably represent business entities, or as Task Services, that represent specific actions that implement some step in a process, in other words, verbs. Which approach is better?
Jason is using an example of a service approving a pending insurance policy in order to explain a difference between "noun" and "verb" type of services.
...following the OO approach, we might have an insurance policy object with several operations, including one that approves the policy, as the following pseudo code illustrates:myPolicy = new Policy (); ... successOrFailure = myPolicy.approve ();
... it is certainly possible to create a Policy Service as an Entity Service that has an approve operation that works more or less like the example above, with one fundamental difference: because Services are fundamentally stateless, you don't instantiate them. Here, then, is pseudo code that represents how an Entity Service would tackle the same functionality:request to create new policy, specifying create policy operation --> Policy Service --> response with policy number 12345
request to approve policy 12345, specifying approve policy operation --> Policy Service --> response with success or failure
Although this is a typical approach to services design, well-aligned with OO practices, Jason points out that there is:
...another way of offering the same functionality as the Entity Service above where the Services represent verbs rather than nouns, what we call Task Services. Here is the pseudo code for this situation:request to create new policy --> createNewPolicy Service --> response with policy number 12345
request to approve policy 12345 -- > approvePolicy Service --> response with success or failure
In this example, neither Task Service has any operations, but rather the functionality of each Service is understood from the context of the Service. After all, what would an approvePolicy Service do but approve policies?
In Jason’s opinion:
Both Entity and Task Services help architects connect the dots between legacy capabilities on the one hand, and flexible process requirements on the other... Entity Services... directly abstract underlying legacy capabilities... the Task Services, [represent] abstractions of individual operations belonging to underlying Entity Services. The... Process Services... are typically compositions of Task Services. In other words, Process Services are interfaces to SOBAs, and when those SOBAs are compositions of properly designed Task Services, they will exhibit process isomorphism.
Jason completes his post by stating:
As is usually the case, architects have several options at their disposal, and knowing which option is appropriate often depends on the business problem, an example of the "right tool for the job" principle. If the business problem is process-centric, say, a need to streamline or optimize the policy issuance process, then implementing SOBAs as compositions of Task Services will facilitate process flexibility. In other cases, the business problem is more information-centric than process-centric, for example, putting consolidated customer information on a call center rep's screen. In such instances the architect's focus may be on an Entity Service, because the rep is dealing with a particular customer and must be able to interact with that customer in a flexible way.
Although Jason tries to note (several times) the differences between SOA and OO in his post, the post itself is a testament of how much our OO experiences impact our SOA understanding. Let’s start from definitions. According to Wikipedia:
- Noun: a part of speech inflected for case, signifying a concrete or abstract entity.
- Verb: a part of speech without case inflection, but inflected for tense, person and number, signifying an activity or process performed or undergone.
Following Jason’s explanation that "Services are fundamentally stateless", they can’t represent an entity. In his example, a Policy service is not an entity service, but rather a collection of methods supporting operations (verbs) on any policy. This is similar to a stateless session bean (J2EE), which can hardly be called a noun. So, at the end of the day, Service is never a noun, its either a verb or a collection of verbs and the difference between what Jason calls Entity and Task services is the amount of methods that they are exposing.
Community comments
Third Choice
by Jason Alcock,
Re: Third Choice
by Jean-Jacques Dubray,
Re: Third Choice
by Dilip Krishnan,
Re: Third Choice
by Jean-Jacques Dubray,
Re: Third Choice
by Dilip Krishnan,
Re: Third Choice
by Jean-Jacques Dubray,
Re: Third Choice
by William Martinez,
Re: Third Choice
by Dilip Krishnan,
Re: Third Choice
by Jean-Jacques Dubray,
Re: Third Choice
by Luis Espinal,
Re: Third Choice
by Dilip Krishnan,
Verbs, operations?
by William Martinez,
Re: Verbs, operations?
by Dilip Krishnan,
Third Choice
by Jason Alcock,
Your message is awaiting moderation. Thank you for participating in the discussion.
I'm not sure that these two choices are the only ones available.
A RESTful interface could produce and entity that has a field "Status:READY_FOR_APPROVAL". A consumer of the interface could post back the entity with "Status:APPROVED". The service will the determine the value change, and make any required validations, then take appropriate action.
This avoids both Task style or OO style API's, and is fundamentally stateless.
This may not seem a natural paradigm, but neither was OO when first unleashed on a function+structure world.
Re: Third Choice
by Jean-Jacques Dubray,
Your message is awaiting moderation. Thank you for participating in the discussion.
Jason:
it does not matter how you "encode" the approve action. All that you are explaining is strictly (and only) equivalent to :
myOrder.Approve() (you POSTed to /orders/myOrder)
REST is fully object oriented with a global naming service and a ubiquitous ORB. There is nothing service oriented in what you are explaining, it is all Distributed Objects.
Service Orientation is about constructing systems with technologies that support bidirectional message oriented interfaces, explicit separation between interface and implementation, asynchrony, forward compatible versioning, extensible data models, orchestration, assemblies... None of these technologies are available in REST.
As a reminder there is no "service" in REST (I am not sure what you are talking about), REST can only yield synchronous interactions, cannot support versioning, since there is nothing to version, REST is bolting access to implementation. REST is not message oriented, it is RPC all the way.
Re: Third Choice
by Dilip Krishnan,
Your message is awaiting moderation. Thank you for participating in the discussion.
There are only two ways of looking at it...
the OO style = Where the service 'appears' to be the instance of the entity and all the operations are on itself
the Task style = Where the service is a container for all the operations it supports
In a stateless SOAP service its just as Boris says
When these operations in the SOAP service fall back to using a limited vocabulary of operations that do not have domain significance for e.g. GetOrder(), UpdateOrder(), DeleteOrder(), the service transforms into a document service, which is in essence an entity service.
RESTful services are usually a mix of entity services (noun) and task services (verb) with emphasis on the noun aspect. Assuming entity in question is an Order i.e. Order is a resource (noun) that supports a POST operation (verb) that infers the Approved status from the document/payload. Notice the verbs applicable to the service are a finite set (GET/PUT/POST/DELETE).
Ganesh has a very nice post that discribes this as "Viewpoint Flip".
Re: Third Choice
by Dilip Krishnan,
Your message is awaiting moderation. Thank you for participating in the discussion.
Objects? did you mean resources?
Could you explain what aspects of REST is RPC?
Re: Third Choice
by Jean-Jacques Dubray,
Your message is awaiting moderation. Thank you for participating in the discussion.
Dilip:
no I really meant object. /orders/myOrder is the instance of a class object. Its methods are accessed via encoding them such as:
myOrder.submit() -> POST /orders/myOrder/submission
myOrder.cancel() -> POST /orders/myOrder/cancellation
myOrder.ship() -> POST /orders/myOrder/shipment
myOrder.getStatus() -> GET /orders/myOrder/status
There is no viewpoint flip, there is just encoding. Unless you want to name this silly encoding the "viewpoint flip". If you don't encode the class's methods, you are simply CRUDing the state of the object directly, which everyone will do, even though they know it's bad.
Before you know it a smart developer who wants to make a name for himself or herself (and frankly tired of doing all this by hand) will create a code generation framework that transforms classes into RESTful calls, including the serialization of standard types (dubbed resource representation) like in the good old days of SOAP RPC.
The only reason behind REST-* is to provide a specification of OTS (still missing in REST), then the picture will be complete for the old CORBA guys. They will finally have achieved an unbreakable ubiquitous Distributed Object model, sweeping under the rug a decade of innovation of Service Orientation.
Re: Third Choice
by Dilip Krishnan,
Your message is awaiting moderation. Thank you for participating in the discussion.
JJ:
At the end of the day everything is encoding :) What ROA or SOA does is allow us to communicate ideas/architectural decisions at a higher level of abstraction. "Viewpoint flip" as a concept has nothing to do with REST or SOA or what have you. It has to do with how one wishes to model the service; as a stateless container of operations that act on domain entities or as a logical entity that exposes operations that can act on itself, a object oriented approach to model services.
BTW. you still haven't explained why you think REST is RPC.
Re: Third Choice
by Jean-Jacques Dubray,
Your message is awaiting moderation. Thank you for participating in the discussion.
So if everything is "just" encoding, could the RESTafarians leave the REST of us alone? For instance, this is how Microsoft implemented REST (transcoding WS-* isomorphically to REST).
RPC is defined by the degree of loose coupling between the interface and the implementation. I have explained in this post a long time ago how strong of a coupling the server-to-server REST was introducing, while it offers a nearly perfect loose coupling in browser-to-server scenario.
At the end of the day, REST offers some canned loose coupling capabilities (routing and caching) but it exposes directly what I call the "internal" interface, the main characteristic of RPC based technology.
What the RESTafarians don't understand is that SOA has introduced an explicit separation between the interface and the implementation (the external and the internal interface). That is not RPC. Of course the vendors decided that it was not RPC enough to their taste and they quickly made sure you could generate WSDLs from Java or .Net classes. This is for instance what InnoQ as they presented recently in InfoQ.
Unfortunately, the very nature of REST that creates a virtuous circle by transferring the internal interface of the resource to the browser induces the very nature of RPC and the strong coupling in case of server-to-server scenarios.
Re: Third Choice
by William Martinez,
Your message is awaiting moderation. Thank you for participating in the discussion.
Hello Jean-Jacques.
Sorry I disagree with you, not in the facts, but in the concepts.
1. Yes, web services in general (not only those "RESTful") are made RPCish by tools. My Battle story is actually the WRAPPED thing the they made up to convert truly document style into RPC style, by actually modifying the document! Worst coupling cannot be achieved.
Still, that is NOT REST. REST has nothing to do with objects nor RPC. People that are trying to do services without SOAP, said they will do them REST, and they then started creating the same horrible things like RPC and object distribution into HTTP (NOT REST). SO, you are right on facts, but wrong in the REST concept.
2. Not quite agree of your definition of RPC. To me it generates coupling but is not defined by it. Now, server-to-server coupling is due to bad design. In REST you have a client-server based style, that means you have two components, one is someone offering some services, and the other one consumes them (NOT the same Service concept here, careful). Later, abstraction in communication says you have a client that can perform operations upon a resource. So, a server-to-server is not quite a good abstraction, thus it is probably bad design.
Cheers!
William Martinez
Verbs, operations?
by William Martinez,
Your message is awaiting moderation. Thank you for participating in the discussion.
Now, about the post.
God!, There are only two ways of doing services? Just thinking of them as Objects, meaning collections of methods? When in time the concept of an object was changed to just a library?
Or... Think of them as verbs? No way! I have never though of a service as a verb, an entity-less operation!
Services are like live processes. And they should never receive action commands! They get documents, period. They should check those documents, and respond accordingly. If you do anything else, like commanding actions or calling operations on a service, you are just creation a distributed library, not even a distributed object system.
William Martinez Pomares
Re: Third Choice
by Dilip Krishnan,
Your message is awaiting moderation. Thank you for participating in the discussion.
JJ:
I read your article, and though it does a nice job outlining the problems with reliance on out-of-band change management in RESTful services in regard to message schema's, versioning etc. ...
... I think it doesnt resonate with me because of the following reasons
1. In any form of service oriented architecture, RESTful or otherwise, "boundaries are explicit", so in that sense, internal interfaces should be opaque to consumers. So though, changes in service implementation implicitly affect consumers across boundaries, that is not specific to ANY form of services, be it CORBA, WS-* or RESTful. I say this in the context of this statement in your article
2. Secondly, while your model is great at articulating how one can measure coupling as an observer to the entire systems, the architectural viewpoint that one uses for change impact analysis on a producer and consumer cannot be same. IMHO, it seems like the boundaries for analysis have been conveniently moved to make the argument that REST introduces strong coupling between client and service.
3. Thirdly using the logic that RPC is a measure of coupling (more coupling = RPC), and hence, if REST is strong coupling, then REST must be RPC, is NOT proof in set theory as I know it.
Re: Verbs, operations?
by Dilip Krishnan,
Your message is awaiting moderation. Thank you for participating in the discussion.
See my response
Re: Third Choice
by Jean-Jacques Dubray,
Your message is awaiting moderation. Thank you for participating in the discussion.
I'll stand by my definition whether you use REST in a CRUD way or via a series of method invocations on an object, encoded as POSTs+Nouns: as long as you wire directly the semantics of the a particular runtime be it OO or SQL, you are doing RPC, you are calling into that runtime.
Runtime invocations are synchronous, uni-directional, quick-running,... all the characteristics of RPC technologies.
I don't know many services which are "truly" autonomic. They all share some kind of container. REST is no different. Actually REST goes even further, REST offers one of the worst autonomy possible as it requires all resources to be under the same network authority, and prevents any kind of migration away from that network authority without breaking any systems that holds URIs that point to the original one. So in the RPC world, REST is one of the worst technology possible because I can't ever move my resources (you remember cool URIs don't change?)
To answer specifically your point #2, this is the definition of loose coupling, there is nothing that conveniently moved. There is no other way to achieve loose coupling, and certainly not by some automagical encoding. Encoding is by definition isomorphic. If you encode some RPC call, the encoding will be RPC. You have gained nothing and lost nothing. This is why function or object oriented RPC technologies failed in the past. This is why REST will fail just as well. People can try to market this encoding for money, but it is not because people pay high consulting fees that your encoding provides any value.
After all, people are signing up in droves for credit cards that charge 20% or more and is going to hurt them significantly months and years later. They are doing that for the instant gratification of getting some money without working for it, then they have to work 20% more for having had this privilege. So it should not be surprising that just as many people in IT would sign up in droves for a technology that give them the instant gratification of simplicity, even if shortly thereafter they start paying a heavy price for dealing with it.
Roy's REST works, works really well, trying to apply REST outside the boundaries for which it was defined does not work, my blog post explains why.
Re: Third Choice
by Luis Espinal,
Your message is awaiting moderation. Thank you for participating in the discussion.
It might not matter functionally, but it does matter conceptually. Developers go by conceptual models as they try to put stuff together so that the pedal meets the metal. A poorly design conceptual model (be it verbs or nouns) will have significant impact in its usability.
On another note, and this is not addressed to anyone in particular, I'm not sure why people tend/attempt to model coarse-grained services as entities. If they are stateless, then they can't be entities. It seems to me that objects (or entities) make sense at a level of abstraction that is different from the level of abstraction that services reside.
A service is a discrete, well-defined rendered capability that runs and can be reached at a given location as part of a collection of services. Services get accessed by objects/entities/processes, perhaps triggered by a call to another service. That is, there is no "service A that access service B". There is "object A that resides within the boundaries of location Z, gets out of those boundaries to access a service B that resides at a possibly different location."
With that in mind, and with the tenet that we want to be as stateless as possible, it seems, then, that services are better thought of as verbs, as (OMG!blazffemey!) procedures. In the actual implementation, there might be an object (or a collaboration of objects) that implement those services, but from an external (and stateless) point of view, that's a distracting detail. Furthermore, a client object might use one or more objects to get to access the service, but that's just that, a proxy to get to a procedure that lives somewhere else.
Unless a service (or collection of services) require an state to operate, trying to force services (specially stateless services) as objects or nouns sounds more like "syntactic salt" IMHO.