Reputation: 53
DISCLAIMER: I'm really just starting out in SOA so you will have to excuse my ignorance.
I have a pretty simple service that processes applications from a 3rd party API (salesforce). The UI accepts IDs -> sends ProcessCmd and starts saga -> saga imports data from API -> saga subscribes to ImportedEvt & tries to validate -> saga runs indefinitely checking for new info or manual override -> if saga ends publishes ProcessedEvt with status.
Now my UI is two pages based on Angular/SignalR.
Index.html is populated with the IDs and empty fields on submit (via JS) and listens for the two events. ImportedEvt populates some of the fields and ProcessedEvt populates the status field (accepted/denied etc.). It also activates the link to details.
Details.html just queries the DB.
Originally I saved the data in the ProcessingSaga but I read in David Boike's book that this is bad practice because a saga is the captain of the ship, only giving orders but no actual steering. So I added another ProcessedEvtHandler on my Service to save to DB but I don't know if this is correct.
A few things confuse me:
It seems to me that despite my UI having it's own endpoint and being able to send/receive messages like any other service. It doesn't really fit into the same category. Having Eventual Consistency is great for behind-the-scenes business rules but makes terrible UX and I don't understand how I cannot have the UI service sharing databases?
Am I missing something?
Upvotes: 2
Views: 152
Reputation: 28016
If two physical services/processes share a database, you essentially don't have two logical services, you have one. This is a basic tenet of SOA.
It sounds like your UI and your back-end service are physically separate. Even so, you may want to ask yourself whether they represent two logical services or one. If they represent the same logical service, you would not be violating anything by having them access the same database.
If they represent two logical services (which I suspect they do), consider not querying the database directly from the UI; instead query the back-end service via some form of request/response (WebAPI, WCF, etc.), and have it query the database. Saving to the database should be done by sending commands to the back-end service from the UI. Commands should generally be business verbs (e.g. "ChangeCustomerAddress" vs. "UpdateCustomer").
Why should I have a new event SavedToDbEvt purely for the sake of the UI?
I'm not completely sure I understand this part of the question. Essentially you should be publishing events when something has already happened. If you're working through a process that saves to the database, the event usually gets published after the database commit is successful. That does not mean that you should be publishing events like "SavedToDbEvt", but it might mean that your ProcessedEvt shouldn't be published until the data has been persisted.
Edit
This is a good question, and your follow-up questions in comments are also reasonable. Unfortunately we're starting to cross the line into areas that would make this a better question for a forum, where back-and-forth discussion is possible. I'll add a few general thoughts here, but a definitive answer may not be possible as every situation is unique, and there is (likely) more than one solution that would work.
Perhaps I'm creating more layers/services than I really need.
Hard to say without knowing more. Is the UI going to consume other back end services, or just the one involved in your question? Also, is the back-end logic going to be consumed by other services, or just by this UI? If they are logically one unit, you should definitely consider simplifying your design by not distributing them physically.
another layer of abstraction (ie WCF) helps bridge the gap [...]
Even if you are using Event Driven/Bus-Style Architecture, there will almost always still be some need for request/response-style querying of other services. Just as a simple example: what if your UI service was brand new, but your back-end service had been deployed for years? How would the UI get the existing state, since it has presumably missed the years of events that the back end service has already published?
While you can simulate request/response via an ESB, that's really not what it's intended for--I'd recommend against it in most cases.
Finally, it sounds like you actually do need an additional event to be published once the database save has been completed. It seems to me that when the Application has become a permanent part of the system, it represents an interesting state change. If that's the case, what is it about that state change that makes it interesting to the business? If you can figure that out, your event should start making more sense, and will probably naturally translate into a better name than "SavedToDb"!
Upvotes: 4