I’m having a little bit of difficulty understanding some architectural principles when developing a service. If you make a call to a WCF service and it returns a collection of items(Orders) (which are custom made classes made up From LINQ-to-SQL entity data) to a client and each item has a collection of items(OrderItems) (one-to-many) that are also made up from the same LINQ-to-SQL context. If I make another call to the service and request a particular OrderItem and modify its details on the client side, how then does the first collection of Items realise that one of its Orders OrderItem has changed from the client side. I am taking the approach of when changing the OrderItem I send the OrderItem object to the WCF service for storage via LINQ-to-SQL commands but to update the collection that the client first called I use IList interface to search and replace each instance of the OrderItem. Also subscribing each item to the PropertyChanged event give some control. This does work with certain obvious limitations but how would one 'more correctly' approach this by perhaps managing all of the data changing from the service itself.. ORM? static classes? If this is too difficult question to answer, perhaps some link or even chat group that I can discuss this as I understand that this site is geared for quick Q/A type topics rather than guided tutorial discussions.
Thanks all the same.
Chris Leach
If you have multiple clients changing the same data at the same time, at the end of the day you system must implement some sort of Concurrency Control. Broadly thats going to fall into one of two categories: pessimistic or optimistic.
In your case it sounds like you are venturing down the optimistic route, whereby anyone can access the resource via the service - it does not get locked or accessed exclusively. What that means is ultimately you need to detect and resolve conflicts that will arise when one client changes the data before another.
The second architectural requirement you seem to be describing is some way to synchronize changes between clients. This is a very difficult problem. One way is to build some sort of publish/subscribe system whereby, after a client retrieves some resources from the service, it also subscribes to get updates to changes to resource. You can do this either in a push or pull based fashion (pull is probably simpler, i.e. just poll for changes).
Fundamentally you are trying to solve a reasonably complex problem, but its also one which pops up quite frequently in software.
Related
I am designing an e-commerce application with microservice approach, using ORM(JPA) for data persistence for one of the microservice named OrderService. OrderService owns functionality related to persisting and reporting orders, which essentially include customer and product information. Customer and product functionality is managed by different microservices.
My question is at ORM layer OrderService need POJO which belongs to ProductService and CustomerService. What is the best way to deal with this dependency between services? Should application needs to design in different way?
There are few things that one should take into consideration when try to find a solution
1. You cannot access the database of other services, you have to make a call.
2. You should try not to keep data from other services into yours. Data duplication lead to an inconsistent state and should be avoided if you can
3. You should have a means to query data from other services when asked for.
Now with those points, I will mostly restrict data from other services to some reference ids (which should be immutable). At ORM layer I will just fetch the reference IDs and bloat them up by making an API call to concerned services(business layer).
You may realize that you are making way too many calls for say getting customer name to customer service using customer id, if that is the case, you may consider saving some of these information in your system. But be cautioned. Data that you saved should not be volatile and make sure you have done due diligence in making that call.
Recently, I have gone through many design principles of microservices and realizes that CQRS-ES and data replication with eventual consistency is best solution of this issue. We try to make communication Asynchronous as much as possible, uses point to point synchronous communication between microservices only when necessary.
This is a fairly common situation when designing microservices. Most microservices will require access to data available through another microservices or an external provider.
The best way to deal with this is to design each microservice as a "separate" application and think of all other microservices as external to it.
So, the developer of Microservice#1 (M1) would have to check into the Microservice#2 (M2) spec and write simple POJO classes for the data he fetches from there. Just like he would do if he were using some external API like Facebook.
Do note that that M1 will always talk to M2 (via REST for example) and never to the DB directly for the data it needs.
Ideally, each microservice would have its own database (or part clone of a central database)
Looking for some guidance.
I'm building an application, SL4 with WCF as the backend service. My WCF Service layer sits over a Domain Model and I'm converting my Domain Entities to screen specific DTOs using an assembler.
I have a screen (security related) which shows a User and the Groups that they are a member of, now the user can add and remove groups for the user after which they can hit the apply button. Only when this apply button is hit will the changes be submitted.
Currently I have a UserDetailDto which is sent to the client to populate the screen and my intention was on hitting apply to send a UserDetailUpdateDto back to the server to perform the actual update to the domain model.
Does this sound ok to start?
If so when the user is making changes client-side should my UserDetailUpdateDto be sending back the changes, ie. whats been added and whats been removed.
Not sure, guidance would be great.
Guidance is always to tricky when so much is unknown about the requirements and the deployment environment. However, your approachs sounds reasonable to me. The key things I like about this:
1) You are keeping your DTOs separate from your Domain Entities. In small simple apps it can be fine to send entities over the wire, but they can start to get in each other's way as complexity and function increase.
2) You are differentiating between Query object (UserDetailDto) and Command object (UserDetailUpdateDto). Again the two can often be satisfied using a single object but you will start to them bloat as complexity/function increases because the object is serving two masters (the Query object is to be consumed at the client and the Command object is to be consumed at the server). I use a convention where all command DTOs start with a verb (e.g. UpdateUserDetail), it just makes it easier to sort 'data' from 'methods' at the client end.
If the SL application is likely to become large with more complex screen logic it may be worth looking at the Model-View-ViewModel (MVVM) pattern. It allows you to separate screen design from screen function. It provides a bit more flexibility in distributing work around a development team and better supports unit testing.
As far as what gets sent back in the UpdateUserDetail object, I think this should be guided by what is going to be easiest to work with at the domain model (or the WCF service sitting over your domain model). Generally, smaller is better when it comes to DTOs.
I am creating a brand new application, including the database, and I'm going to use Entity Framework Code First. This will also use WCF for services which also opens it up for multiple UI's for different devices, as well as making the services API usable from other unknown apps.
I have seen this batted around in several posts here on SO but I don't see direct questions or answers pertaining to Code First, although there are a few mentioning POCOs. I am going to ask the question again so here it goes - do I really need DTOs with Entity Framework Code First or can I use the model as a set of common entities for all boundaries? I am really trying to follow the YAGNI train of thought so while I have a clean sheet of paper I figured that I would get this out of the way first.
Thanks,
Paul Speranza
There is no definite answer to this problem and it is also the reason why you didn't find any.
Are you going to build services providing CRUD operations? It generally means that your services will be able to return, insert, update and delete entities as they are = you will always expose whole entity or single exactly defined serializable part of the entity to all clients. But once you do this it probably worth to check WCF Data Services.
Are you going to expose business facade working with entities? The facade will provide real business methods instead of just CRUD operations. These buisness methods will get some data object and decompose it to multiple entities in wrapped business logic. Here it makes sense to use specific DTO for every operation. DTO will transfer only data needed for the operation and return only date allowed to the client.
Very simple example. Suppose that your entities keep information like LastModifiedBy. This is probably information you want to pass back to the client. In the first scenario you have single serializable set so you will pass it back to the client and client pass it modified back to the service. Now you must verify that client didn't change the field because he probably didn't have permissions to do that. You must do it with every single field which client didn't have permission to change. In the second scenario your DTO with updated data will simply not include this property (= specialized DTO for your operation) so client will not be able to send you a new value at all.
It can be somehow related to the way how you want to work with data and where your real logic will be applied. Will it be on the service or on the client? How will you ensure that client will not post invalid data? Do you want to restrict passing invalid data by logic or by specific transferred objects?
I strongly recommend a dedicated view model.
Doing this means:
You can design the UI (and iterate on it) without having to wait to design the data model first.
There is less friction when you want to change the UI.
You can avoid security problems with auto-mapping/model binding "accidentally" updating fields which shouldn't be editable by the user -- just don't put them in the view model.
However, with a WCF Data Service, it's hard to ignore the advantage of being able to write the service in essentially one line when you expose entities directly. So that might make the most sense for the WCF/server side.
But when it comes to UI, you're "gonna need it."
do I really need DTOs with Entity Framework Code First or can I use the model as a set of common entities for all boundaries?
Yes, the same set of POCOs / entities can be used for all boundaries.
But a set of mappers / converters / configurators will be needed to adapt entities to some generic structures of each layer.
For example, when entities are configured with DataContract and DataMember attributes, WCF is able to transfer domain objects' state without creating any special classes.
Similarly, when entities are mapped using Entity Framework fluent mapping api, EF is able to persist domain objects' state in database without creating any special classes.
The same way, entities can be configured to be used in any layer by means of the layer infrastructure without creating any special classes.
First of all, I'll clarify some words: when I use the word "user" you have to understand "application user" and the "patient" is an "item" from the model layer.
Let's now explain the context:
A client application has a button "get patient" and "update", a text box "patient name" and a grid to display the patient returned after the click on the "Get patient" button.
At server side I've got a WCF method GetPatient(string name) that searches the reclaimed patient and does some business logic to a PatientEntity used with nHibernate. That method returns a PatientDto (a mapping from PatientEntity). And I've got an Update(PatientDto patient) method to update the modified patient.
The user can modify the returned PatientDto and click on the "Update" button.
So far I have two ideas to manage a "session" through this senario:
First idea: I expose an "ID" property in my DTO so when the user clicks on update, I search, at server side, the "patient" with the specified ID using nHibernate's "GetByID()", I update the result with the data from PatientDto and call the nHibernate's "Update()" method.
Second idea: I create manually at server side a CustomSession (I use this name for clarity) class that encapsulates an ISession and exposes a session's unique id that will travel between the client and the server. So, when the client sends to the server the PatientDto and the unique session id, I can get the CutsomSession and update the patient with the Update() methods of the ISession
I don't like these ideas. Because the first is a lot of overhead and it doesn't use the features of nHibernate. And the second idea demands to the developer to manage himself the id of the CustomSession between the calls: It is error prone.
Furthermore, I'm sure nHibernate provides such a mechanism although I googled and found nothing about this.
Then my questions are:
What mechanism (pattern) should I use? Of course, the mechanism should support an entity's object graph and not a single entity!"
Does nHibenrate provides such a mechanism?*
Thank you in advance for your help,
I don't think this is a Hibernate issue and in my opinion is a common misunderstanding. Hibernate is a OR-Mapper and therefor handles your database objects and provides basic transactional support. Thats almost it.
The solution for Sessionmanagement in Client-Server environments is for example the use e.g. Spring.net which does provide solutions (Search for OpenSessionInView) for your problem and integrates quite well with NHibernate.
The stateless approach you mentioned offers many advantages compared to a session-based solution. For example think about concurrency. If your comitt is stateless you can simply react on a failed Save() operation on the client side for example by reloading the view.
Besides your 2 good arguments for the use of Hibernae is, if done right, security aggainst SQL-Injection.
One reason that I usually don't bother with ORM tools/frameworks in client-server programming is that you land at, usually, your first solution with them. It helps in making the server side more stateless (and thus more scalable) at the expense of some reasonably cheap database calls (a fetch-by-PK is usually very cheap, and if you immediate write it anyway, guess what the database is likely to do first on a write? Grab the old record - so SELECT/UPDATE may be only marginally slower than just UPDATE because it seeds the cache).
Yes, you're doing stuff manually that you want to push out to the ORM - such is life. And don't fret over performance until you've measured it - for this particular case, I wonder if you really can measure it.
Here's a sumary of what has been said:
A nHibernate session lasts the time of the service call. That's, the time of the call of "GetPatient(string name)" no more.
The server works with entities and returns DTO's to the client.
The client displays and update DTO's. And calls the service "Update(PatientDto patient)"
When the client triggers the service "Update(PatientDto patient)", the mapper gets the patient entities thanks to the ID contained in the DTO with a "GetById(int id)" and updates the properties which has to be.
And finally, the server calls the nHibernate's "Update()" to persists all the changes.
Is it ok from your real-world-experience to define service contract with one method which will accept some object as a form of request and return some other object as a result of that request. What I mean is instead of having method for creating, deleting, editing and searching customers I would have these activities encapsulated within DataContracts and what service would do after receiving such DataContract would be take some action accordingly. But service interface would be simple as that:
interface ISomeService
{
IMessageResult Process(IMessageRequest msg);
}
So IMessageRequest would have filed named OperationType = OperationTypes.CreateCustomer and rest of fields would provide enough information for the service that it could create Customer object or record in database or whatever. And IMessageResult could have field with some code for indication that customer was created or not.
What I'm trying to achieve by such design is an ability to easy delegate IMessageRequest to other internal services that client side wouldn't even know about. Another benefit I see is that if we will have to add some operation on customers we only provide additional DataContract for this operation and don't have to change anything on service interface side (I want to avoid this at all costs, I mean not new operations but changing service interface :)
So, what do you think? Is it good way of handling complicated business processes? What are pitfals, what could be better.
If I duplicated some other thread and there are some answers to my question please provide me with links because I didn't find them.
Short answer: yes, this could be a very good idea (and one I have implemented in one form or another a couple of times).
A good starting point for this type of approach are the posts by Davy Brion on what he calls the request/response layer. He consolidated his initial ideas & thoughts into a very usable OSS project called Agatha, which I am proposing at a customer site as I write this.
This is exactly what we're doing here where I work. It works great and is easy for all the developers to understand, and really easy to wire up new methods/class/etc.