I am in the processing of migrating from web services to WCF, and rather than trying to make old code work in WCF, I am just going to rebuild the services. As a part of this process, I have not figured out the best design to provide easy to consume services and also support future changes.
My service follows the pattern below; I actually have many more methods than this so duplication of code is an issue.
<ServiceContract()>
Public Interface IPublicApis
<OperationContract(AsyncPattern:=False)>
Function RetrieveQueryDataA(ByVal req As RequestA) As ResponseA
<OperationContract(AsyncPattern:=False)>
Function RetrieveQueryDataB(ByVal req As RequestB) As ResponseB
<OperationContract(AsyncPattern:=False)>
Function RetrieveQueryDataC(ByVal req As RequestC) As ResponseC
End Interface
Following this advice, I first created the schemas for the Request and Response objects. I then used SvcUtil to create the resulting classes so that I am assured the objects are consumable by other languages, and the clients will find the schemas easy to work with (no references to other schemas). However, because the Requests and Responses have similar data, I would like to use interfaces and inheritance so that I am not implementing multiple versions of the same code.
I have thought about writting my own version of the classes using interfaces and inheritance in a seperate class library, and implementing all of the logging, security, data retrieval logic there. Inside each operation I will just convert the RequestA to my InternalRequestA and call InternalRequestA's process function which will return an InternalResponseA. I will then convert that back to a ResponseA and send to the client.
Is this idea crazy?!? I am having problems finding another solution that takes advantage of inheritance internally, but still gives clean schemas to the client that support future updates.
The contracts created by using WCF data contracts generally produce relatively straight-forward schemas that are highly interoperable. I believe this was one of the guiding principles for the design of WCF. However, this interoperability relates to the messages themselves and not the objects that some other system might produce from them. How the messages are converted to/from objects at the other end entirely depends on the other system.
We have had no real issues using inheritance with data contract objects.
So, given that you clearly have control over the schemas (i.e. they are not being specified externally) and can make good use of WCF's inbuilt data contract capabilities, I struggle to see the benefit you will get the additional complexity and effort implied in your proposed approach.
In my view the logic associated with processing the messages should be kept entirely separate from the messages themselves.
Related
Let's say i do have a service, which is just a REST-API. This rest api provides some data.
As far as i understand, which makes sense, I can encapsulate data, which is sent from and to this service into DTO's. This totaly makes sense, since you'll have some business objects but often you'll need to serialize them in a way. So as far as i understand this would be a generally accepted and know way to abstract it regarding this part.
Then this DTO's are sent trough the REST-API. Regarding the server side it seams pretty straight forward, having some controllers which provide the data or receive them, I'm not seeing any issues there (at least for now).
So regarding my question. On the client side there are objects, which will access this API, this object, in my implementation contains a http client (not sure maybe i decouple them from this objects) and also it contains methods to access the api. So in one way or another, abstracting the use of http client and accessing the API away.
HOW DO YOU NAME THIS OBJECTS ACCESSING THE API?
I'm now naming them XXXManager/XXXHandler/..., but this names feel far to generic and i feel like there has to be some convention or pattern for this? Naming them XXXService also does not feel not completely right, because service for me is like the server side part, this object are accessing the service.
So how would you name this kind of objects and are there some deeper patterns to handle this kind of service/api accessors?
The model/pattern that would work here, is a classical layered architecture, which works like that:
The HttpClient should be wrapped around a class (let's name it ApiClient) that exposes methods for accessing the REST API. In each of those methods, the httpClient is used to execute the HTTP call.
There is a layer of Service/Manager classes that use the ApiClient and also apply their own business logic.
There is a layer of UI components which also inject the Services/Managers to grab the data and render it on the UI.
In this way you decouple the layers, which improves both the scalability and the testability of your code.
The naming somehow depends on the type of the client-side implementation/framework that you have.
If you have a web-frontend client, then the name TransactionService would tell me that this class talks to some external transaction service (Service is not a naming tied to server-side components).
This naming model applies to Angular, for example.
Patterns of Enterprise Application Architecture suggests Gateway, but I'd just go with Client.
I am currently in the process of developing a Web Service which should expose a relatively large number of ways to interact with it.
For example, Clients may be able to interact with the Web Service in order to manage users or projects in a Database.
To that effect, I created the following classes:
Two Data Contracts: IUsersServiceContract and IProjectsServiceContract
Two Service Contracts Interfaces: IUsersServiceContract and IProjectsServiceContract
My question is the following:
Does it make sense to create two different Web Services, each with their own endpoint(s), instead of creating one big class that implements both Service Contracts Interfaces ?
Keep in mind that in reality I would have many more Service Contracts Interfaces that deal with different sorts of data.
From what I understand, using a partial class (split in multiple files) will allow me to create one big Web Service with only one Endpoint.
This has the disadvantage of dealing with one big class split in multiple files, i.e: its harder to maintain and more prone to errors if developers "don't see the big picture".
The other solution would be to have one Web Service per Service Contract Interface implemented.
In essence, if I have X Service Contracts Interfaces, I end up with X Web Services with X Endpoints.
Which solution would you choose and why ?
Thanks for your input !
Personally I would not use partial classes for splitting a class; the sheer size motivating tgis split suggests that the class is too large and needs a refactoring. In my opinion partial classes main purpose is to add changes to auto generated code.
Since service and endpoint configuration can be shared using named behaviours in web.config splitting the service should not be that cumbersome. But the split should be motivated by grouping of functionality.
Without knowing the exact nature of you services it sounds like there could be a natural separation in two services; one for user related operations and one for project oriented operations.
If the implemantation classes grows above what you think are reasonable sizes I would consider letting separate classes - or preferably interfaces - handle each methods inner logic and let the service implementation it self be a shallow facade that delegates its own method parameters to the correct logoc instance
An important thing to consider here, when you're talking about n number of service contracts, is the cost associated with implementing each service contract. There's a good blog post on that here, "Service Contracts Factoring and Design", although if it wasn't Juval Lowy who posted this article then someone is clearly ripping him off (I am referring to Juval's book - "Programming WCF Services" page 93).
There are some pain points around transmitting entities between a client and a WCF service.
Defeating lazy loading by serializing all properties
Serialized data can be unecessarily bloated
Some coupling between UI and business layer
One way to address these issues is to transmit DTOs instead of entities but I am aware that this technique has its own set of caveats (the biggest one I am aware of is the typing required to maintain these function-specific DTOs).
I think it would be great if the service implementation could generate these DTOs dynamically and this appears to be possible. Unfortunately, it looks like the contract would be loosely defined on the client side (i.e. "object") and that smells like a possible risk.
Is it advisable to use dynamic DTOs in this fashion or is there another way to use DTOs without creating/maintaining classes for each one?
I think the holy grail would be where the implementation dynamically generates DTOs but the client sees well-defined contracts. I'm guessing this isn't possible with WCF.
I guess the issue is what are you going to generate them from? You have to have some description somewhere of what the data you want to transmit looks like. If all you have is the domain objects then you end up in a similar position of transmitting the data that you would of via the domain object.
One of the key things the DTO enables is decoupling so you can evolve your domain objects without breaking the consumers of your service accidently. If you dynamically generate the DTOs then you will cascade the changes - unless you view the dynamic creation as a one-off exercise to get you started with a DTO
DTO is data contract as any other and must be defined. When you choose to go with DTOs you are adding a layer of complexity which you have to maintain. There are tools which can help you with mapping between domain objects and DTOs (like AutoMapper) but your responsibility is to define what DTO should transfer - that is something which can hardly be done automatically. Even with automated tool you will still have to maintain some definition of DTOs which will be used to generate code.
I see a huge number of request and response types in a project to cater for all the endpoints exposed as WCF services. This seems like an awful lot of repetitive, simple code to maintain.
Can these types be auto-generated or avoided altogether using something like attributes?
They can be autogenerated a few ways. The two I'm most familiar with:
Web Service Software Factory - Modeling Edition. You maintain a UML-like model and let the factory generate much of your code. Code is generated as partial classes so you can manually add/override methods and more complex schema.
I also sometimes define all of the data in XML Schema, then use WSCF.blue to generate the contracts from the schema. Again, it creates partial classes so that you can tweak the generated contracts.
Please note that my experience in Silverlight/.Net and WCF is about two weeks of googling and deciphering tutorials. I need to attempt and provide feedback to a client on if Silverlight will be a possible solution to their application needing a RIA front end.
The client has a rather large .Net based application with a UI layer built which greatly relies on the creation and manipulation of specific (personal) classes and objects from the backend (which would be the server side).
A summery of what I understand to be the general procedure: one can pass simple objects containing simple data types, or more complex .Net type objects. Basically anything which can be understood by both client and server side, after serializing.
But what is the limitation to the complexity of an object I can pass? Or phrased otherwise, would silverlight and WCF be able to support the passing of a personalized object which may contain references to other classes/objects and variables etc?
Additional Info (in case it can help):
I am not allowed direct access to their backend code but with the information I have been given I can safely say their classes heavily use inheritance and overloading of functions/methods in the classes.
As far as I know there is nothing specific to Silverlight. There are some things to keep in mind though.
WCF serialization doesn´t like circular references.
All types need to specified in the contract. So watch out with inheritance etc.
In general using DTO's (Data Transfer Objects) and not exposing your business objects is the way to go.
The metaphor is one of message passing as opposed to passing objects. DTO's as Maurice said.
You can get pretty complex, but each object needs to have its contract defined.