views:

194

answers:

4

OK, so we are using entity framework and wish to expose data from these entities to consumers. This data is pretty common and although initially only consumed by WPF applications it could be consumed by other technologies such as Silverlight, ASP.NET, Office, etc in the future.

Typically you would build WCF services that expose a number of explicit methods to return data according to what the consumers would require. For example, GetCustomersById(int Id), GetAllCustomers(), etc. This would incur the overhead of having to rewrite the WCF service and deal with versioning issues if you needed to add other methods in future. You would possibly also use DTOs to return the data.

So we are considering simply exposing the entities through WCF Data Services. This seems to make sense. It saves development effort by removing the necessity of having to build explicit services that implement the various interfaces. It could also protect you from having to rewrite those interfaces if modifications to your entities occur.

It all seems to easy and I am sure we are missing something. What are the disadvantages of this approach? Also, if we return the entities rather than DTOs, what else are we losing?

Then there is the obvious follow on question relating to the update and delete operations you may also have. Is it worth considering WCF Data Services for those operations as well?

Thanks for any insight!

+3  A: 

Personally I prefer your initial approach, but this is due to my desire to have strong control over the queries, and the processes that are used by my applications. i find that as I work with very large scale projects, it is helpful for me to have full control over the queries that are executed, etc.

Mitchel Sellers
Thanks for the response Mitchel. Apart from the personal control aspect, can you think of anything from an architectural or technical perspective that would raise concerns about using WCF Data Services instead? I can think of a few things when it comes to updates and deletes, such as where and how to implement your business logic related to them, but I am not seeing real issues when simply querying data. In fact, I am seeing a whole lot of advantages. I was thinking about splitting out the two and sort of having an almost CQRS like view of things.
Jon Archway
Well, my biggest fears/risks that I see with it is around the "amount of data returned". I typically work with large datasets and I need assurances that a query will not accidentally return 1 million records or something nutty like that
Mitchel Sellers
From what I have seen you could use the DataServiceConfiguration.SetEntitySetPageSize property to define the maximum page size to return. I guess the nervousness you have (and I have too) is effectively exposing the data access layer higher up in the chain. Typically my explicit service methods protect the data access layer. However, if exposing through WCF Data Services then this isn't quite as obvious, I guess you control through configuration.
Jon Archway
A: 

Personally, I think your initial approach is stupid. That simple.

  • Data Services allow the user to filter and query related data as he needs.
  • Data Services have full tooling integration already - programming language (LINQ pass through), Reporting Services, Excel can work against them.

At the end of the day you expose a way more usable API with less maintenance work and tooling support.

TomTom
Thanks for the frank response :-) I think I was looking for someone to give a response as to the scenarios when it would NOT be a good approach to use WCF Data Services, rather than promote WCF Data Services. I can see the benefits of WCF Data Services myself, but want to make sure there are no angles that I have missed. I have already considered you are possibly introducing a certain degree of coupling and maybe losing some abstraction. Also, when taking it beyond simply querying data, are there things to be concerned with when conducting CUD operations. Thanks again.
Jon Archway
There is I think not a single scenario where usage of simple SOAP protocols is superior. That simple.
TomTom
I can't believe that. So you are suggesting a REST implementation such as OData is ALWAYS superior to a SOAP implementation? Oh, and I expanding this question to be more than just querying data now.
Jon Archway
For data query, yes. it is not about SOAP / REST - it is about OData being a SEMANTICAL web service. This is always superioer for data retrieval than a hard coded web service (get customer by ID - how do I search by name?). Also OData has good semantics for updating multiple dfferent (!) entities (of different types) in ONE call. This CAN be done with SOAP, but most people never bother to actually make a decent service interface.
TomTom
Regarding data retrieval, the advantage of OData is also harder by the fact that it is not only a semantical interface, but one with an accepted standard and tooling support.
TomTom
OK, I am fairly happy with the data retrieval side now, although would we still look to use DTOs rather than surfacing entities to applications in order to provide a level of change protection there? What about other data access such as create, delete and update. Do you have the same opinion with these operations?
Jon Archway
What for? Well, th ENTITIES you expose in Odata can be DTO transformations. Or simply have no methods exposed... so they act as DTO. Works like a charm.
TomTom
Create, Delete, Update - nex time i see a "UpdateCustomer (id, blablabla) interface I hit the programmer in his face. Stupid, slow. update 100 custoemrs - make 100 calls. Looks at how OData handles updates. THAT is an efficient interface.
TomTom
I am pretty much agreeing with you, but it feels like I am suddenly moving away from the consensus of how to design applications using specific repository, DTOs, service operations in WCF, mapping between business objects and DTOs,back on the client, etc. I want thinks to be easier and more concise than all that and EF/WCF Data Services seems to be the solution. BUT, I want to make sure I am not missing something. Plus which scenarios it would be less suitable, or we would simply all go out and write every app this way and surely there are more than a couple of instances where its not suitable
Jon Archway
The consensus was never there. Odata is a design of a remote interface that i see in 20 year old design documents. Non-chatty, semantical. The consensus, mostly, was made by people too stupid to read books written 15 years ago and ignoring all the advice given even then.
TomTom
it is not suitable is a less retrieval more operations interface where you want hatd coded processes (!) exposed.
TomTom
OK, but it still seems more people are in favour of writing services in an operation like fashion regardless of what the requirement is. I am leaning on the side of a mixture but trying to fathom out the scenarios types where each is more appropriate.
Jon Archway
+2  A: 

I think you have a valid case for Data Services. They are designed to expose data in a standards friendly format to end users.


With that being said, arguments against....

The downside is you are basically giving them free reign to query the data however they want. As a result they can do stupid things and cause bottle necks for other users. Think of how easy it is to write a bad LINQ query that combines in-memory and DB operations.

Additional, arguments against using Data Services and using traditional services are when you have a lot of business logic, or you want to pass data types that are outside of your entity model(you can do this in 4.0 but its a pain).

Lastly I am always uncomfortable when it comes to Insert/Delete with data services, because you require your end user to have a lot of knowledge on how your data is stored. You have to trust them, and I have learned that trust generally comes back to hurt you.

So all in all, Data Services are great when you dont have to force a lot of "rules" onto your end users(business logic or governence).

Nix
When you say "giving them free reign", apart from when you are exposing specific data to something such as Excel the consumers would generally be developers writing client applications (or possibly business services). So, as much as I am a control freak I would like to trust them with that :-) I guess the business rules is certainly something that has been at the back of my mind. You could maybe create a business process service in those specific cases where such functionality is truly necessary?
Jon Archway
When I say free reign, its free reign to query your data however they choose to do. So if they decide to do really poorly formed queries your other users could suffer.
Nix
I agree, but then if the "end users" are developers programming against the interface then surely they could do this regardless of whether they are coding against data services or ef?
Jon Archway
Programming against what interface? A service interface you provide? If you are providing the service you control how the users interact with the database. Yes they could DOS you and hit your service 1000 times, but giving a user a client query framework to your database has its own set of potential issues, that are completely uncontrollable.
Nix
OK, but if the same developers are working on both the clients and the services then the danger is no different. I can see if the client is developed by a separate team then this would be different. Thanks.
Jon Archway
A: 

The data services are definitely a time saver, but the service itself shouldn't be exposed to clients directly, but through other services.

My approach would be to have layers of services: for example, your service is practically behaving as a data layer, and just as you don't expose database to clients, you don't expose data service directly, but through the services that add additional logic & value to the data (processing data, controllers, business logic, permissions, etc...). This would be a typical SOA oriented approach...

This way, if you see a problem when you change database model, you change only the services that expose it, and not everything. Typically, if you use some Enterprise service bus you'd have DTO's and you map your object to what clients can work with, thus avoiding the troubles with object changes. Of course, you could do it manually, but it's worth investigating first whether it's worth the effort...

veljkoz
If you are not going to expose your WCF Data Services then what would be the point in using them at all?
Jon Archway
What I meant is to control their exposure so not everyone can use it, but only services that add some logic to the data (what's saved first, what has to be deleted if some entity is deleted, what rules have to be fulfilled if updating etc...)
veljkoz
OK, but if you are effectively having a service façade in front of the data service why not just create a wcf service on top of entity framework and not have the data service at all?
Jon Archway
Imagine you have a solution with 15 services, and you're serving data externally to clients. Obviously, you wouldn't expose your data service to the clients directly, but through some intermediary service. For your internal services, there's no need to put a facade between since it's a "home" service, except for some cases where it's appropriate (to simplify some complex action or similar). So, the data service is used as-is for local services you trust/own, but you shouldn't put it out as a complete service to be used by everyone...
veljkoz
Ah, I see. Is it not possible to lock down a service dependant on the user consuming it? So, an internal user would have full access, an external user would only have partial access? In this case you would not need to introduce a façade?
Jon Archway
Yes, I guess you could do it that way as well. But, in my experience, external users don't respond to changes very well (for example if your data model changes a bit), so after a while you'll probably put a facade in front anyway, if not to limit access, then at least to maintain structure of the data exposed.
veljkoz