2

I have read Why not publish NServiceBus messages from a web application and another similar question about this but I am not clear if this applies to service layer as well. For example, if the service layer is composed of web services or REST services built using WCF or Web API or any other way, should those services publish events or send commands? If those services are hosted in load balanced web servers, the problems outlined in the articles apply to this layer as well. How would the recommendation change or not change?

If I look from the definition of Event vs Command, the messages I am talking about are Events e.g. "a user was created" and so an event should be published. As a matter of fact, the service that created the user doesn't even know what else to do i.e. may be another application is supposed to create a customized portal for it and yet another application is supposed to send a welcome kit to the user. This would be an event and not a command. I guess I am hung up on the definition of a web application and application service when application service itself is composed of one or many web applications.

The definition of Web Application

A web application is an application that is accessed by users over a network such as the Internet or an intranet.

However, to me, the users can be computers and thus web services are web applications and that is the reason for this question.

EDIT:

Let's consider a concrete example. An ASP.NET website (MVC or Web form - doesn't matter) displays the form to the operator, gets a post with data about user creation (Name, UserName, Password) and invokes a WCF service to create the user. In between website and WCF service we can put ServiceBus and send command to create the user (Request/Response) so that we get all the benefits described in the first article. WCF service is the actual business processing layer i.e. it would create the user. That is where I have the question. After the user is created, it should announce that a user has been created and other systems can react to it and do whatever they are supposed to do. So it fits perfectly the pattern of publish the message. However, the WCF service itself is a web application and thus has most of the traits of the web applications and thus the confusion.

Community
  • 1
  • 1
amit_g
  • 30,880
  • 8
  • 61
  • 118

2 Answers2

2

As mentioned in the answer to the SO question you linked to, publishing event has more to do with where the actual processing takes places. Just as a side-note: it is not a matter of Send instead of Publish since that would imply that the two are interchangeable whereas they have rather different intentions. When you want to publish, you want to publish.

The same questions should arise if you find yourself publishing from your web-exposed integration layer: should you be performing the business processing in that code or rather sending it off to another endpoint for processing? Typically you should just send it off to another endpoint. You may even consider how you would perform the relevant action should anyone wish to invoke it. For instance, if you are publishing a UserCreatedEvent message it implies that you created a user. How would a user be created? Would I be forced to use the WCF / Web-Api layer or can I send a CreateUserCommand message on the bus that is processed by some application endpoint? If it is the former then you may need to rethink your design. However, if the latter you should be sending the command from your WCF / Web-Api anyway and the processing endpoint will perform the Publish bit :)

update: My take on it is that it is more about cohesion / concerns. You would typically interact with your domain, from within your business, via a service bus for commands and events, and a simple query layer for reads. If you need to expose anything to a third-party (or simply via the web) then you use WCF / WS / Web-APi. The point is that you should try to avoid business processing in an integration endpoint (or in a front-end like a website). Business processing is better suited to application servers. There are usually exceptions to the rule but if you are in a position to influence the structure then you are in a better space.

Eben Roux
  • 12,983
  • 2
  • 27
  • 48
  • Thanks Eben. However, I am not sure if I still understand. I updated the question to have a concrete example to go by. "> rethink your design" - do you mean to say that the service layer also should not do the actual business logic processing and instead by just a pass-thru to another windows service and communicate to it via another layer of Request/Response? Also, about Send and Publish, I am using the terminology used by NServiceBus where we Publish the Events and Send the Commands. – amit_g Feb 21 '13 at 18:32
  • I guess it will have to be a conscious choice having the WCF service perform the actual processing. Ideally the WCF service should not be performing the actual business processing, IMO, but it is not inconceivable that one may implement it as such in which case you will need to publish from there unless you have a service bus processing endpoint in front of the WCF service acting as the go-between in which case you would publish from the service bus endpoint. Your terminology is in line with the thinking :) – Eben Roux Feb 21 '13 at 19:19
  • Thanks again. How many layers are we talking about in an ideal application? Web layer is presentation. Service layer is just a pass-thru to business layer? What is business layer then? Windows services? Here I am only talking about physical layers not to mention logical layers within each of these physical layers! – amit_g Feb 21 '13 at 19:31
1

The fact is, whatever code is truly responsible for performing the action should be the same which publishes the event. If you've got a MVC app and in the controller itself you're using Entity Framework to insert the User record, then that is exactly where the Publish should be, right after the SaveChanges call. If however, the controller calls a referenced binary or service which does the actions involved in the "add user" call, then the Publish should be there. My thought is the event should be right alongside the code that does the action whose event you are trying to publish.

Rich
  • 2,076
  • 1
  • 15
  • 16