Web Service Contract Design - Single-Responsibility - wcf

I'm curious as to see how most developers go about designing the contracts to their web services. I am quite new to service architecture and especially new to WCF.
In short, I'd like to find out what type of objects you are returning in your operations, and does each operation in your service return the same object?
For example consider the following:
Currently, all services I create inherit from a ServiceBase object that looks similar to:
public abstract class AppServiceBase<TDto> : DisposableObjectBase where TDto : IDto
{
protected IAppRequest Request { get; set; }
protected IAppResponse<TDto> Response { get; set; }
}
Response represents the return object which composes something like:
public interface IAppResponse<TDto> where TDto : IDto
{
List<TDto> Data { get; }
ValidationResults ValidationResults { get; }
RequestStatus Status { get; }
}
Therefore, any derived service would return a response composed of the same object.
Now initially, I felt with would be a good design as this forces each service to be responsible for a single object. For the most part this has worked out, but as my services grow, I've found myself questioning this design.
Take this for example:
You have music service you're writing and one of your services would be "Albums".
So you write basic CRUD operations and they pretty much all return a collection of AlbumDto.
What if you want to write an operation that returns the types of albums. (LP, Single, EP, etc)
So you have an object AlbumTypesDto. Would you create a new service just for this object or have your Albums service return many different objects?
I can imagine a complex service with several varying return types to be cumbersome and poor design, yet writing a whole new service for what maybe, only one or two service operation methods to be overkill.
What do you think?

It is a good idea to design your services around your domain problem. By exposing a CRUD pattern on the service, essentially you are using services for data access. The risk of this is your business logic will end up on whatever is consuming your service.
You service should expose methods relavent to the problem you are trying to solve (which loosely models onto the operation on the UI typically)
From here you will see your data contracts start to fit more naturally to the problem you are trying to solve, instead of creating "one size fits all" contracts.
For a good starter, Google "Domain Driven Design" But there is plenty of reference material on this.

Related

Web service coordination

We are creating a WCF infrastructure to allow other systems in the organization to consume our business logic. Some of this logic has to do with user authentication, so securing the services is of high concern. The transport layer is secured by certificates. I am more concerned with securing the business layer.
One of our clients calls these services in a certain sequence, in order to support a business process. What I would like to do is put in place some mechanism to verify that the sequence is indeed kept. The sequence can be disrupted by developer errors on the consuming side or by attackers trying to compromise the system. I do not want to put the logic of the process inside the services themselves, since this will couple them to this specific client`s process. I would like to put the logic for coordinating the different services in a separate layer, which will be client specific (or maybe something more generic to support any process?)
Can someone point me to specific patterns or resources which discuss this issue?
I have been searching Google for half a day, and I can`t seem to find any resource discussing this specific issue.
Most web services should be designed to be called independently, since there's no guarantee what order the caller will compose them.
That having been said, one way to encourage them to be called in order is to use a design akin to a Fluent Interface, in which Service A returns an object that is an input parameter to Service B.
[DataContract]
public class ServiceAResult
{
// ...
}
[DataContract]
public class ServiceBResult
{
// ...
}
[ServiceContract]
public interface IServiceA {
[OperationContract]
public ServiceAResult OperationA() {
// ...
}
}
[ServiceContract]
public interface IServiceB {
[OperationContract]
public ServiceBResult OperationB(ServiceAResult input) {
// ...
}
}
Here, the easiest way to create a ServiceAResult to pass to ServiceB.OperationB is to call ServiceA.OperationA.
I recommend you separate your concerns.
Have a web service whose operations are called in order to perform your business processes.
Have a second service which orchestrates your business processes and which calls the operations of the first service in the required order.
Do not make it the responsibility of the first service to ensure that the second service calls things in the correct order. The responsibility of the order of calls should belong to a different service.

Service contracts vs. domain objects

Say I have two interfaces to my application:
A web front-end
A back-end which provides data
Both of them talk to a web-service, and that web-service in turn, handles business logic and talks to a separate data layer, which persists the objects.
So, if each client of the web-service uses the DataContracts of that web-service, what do I need domain objects for?
Where does domain-driven design fit in here, and what advantages does it bring to my architecture?
Or is it that case that what I have already is fine, and I don't need domain objects at all?
Am I misunderstanding the meaning and purpose of domain-driven-design?
The data contracts are nothing more than messages that your client and server exchange between each other.
Your WCF service is that layer which accepts the messages and processes them so that they can be handled by your business logic.
Your domain objects would be your business logic, which accepts the processed messages, performs the necessary actions, and then applies any events that need to be applied.
If you follow a more Command-Query Separation principle (CQS), then your commands (inserts/updates/deletes) would be fired off to the WCF service and not return anything. Your client would request reads from your WCF service separate from your commands (meaning a InsertOrder command doesn't return an Order - you have to issue a separate request for that).
In all of that, your data contracts are the messages to and from your WCF service. Your domain is behind that service handling all of the business logic that needs to happen in order to make your reads as accurate as possible.
I'm answering this from more of a CQRS (command-query responsibility segregation) perspective, but I hope this explains where I'm coming from.
To answer your other question:
- do you need domain objects --> I'd say yes, you should
What do I need domain objects for?
You may not need domain objects in your application. Typically, DDD would fit into a service layer in the following way: The service layer exposes its operation contracts and data contracts. Data contract classes often correspond to objects in your domain, but they are not domain objects because they don't have any behavior, they are only a representation of the data with which a particular service is concerned. Here is a simple example interaction between data contract objects and domain objects in a service:
public MyEntityDto GetMyEntity(string id) {
var entity = this.myEntityRepository.Get(id);
if (entity == null)
return null;
return new MyEntityDto(entity);
};
In this case, MyEntityDto is a DTO object for MyEntity, it serves to expose the specific properties of MyEntity which the service wishes to provide to its clients.
The value of DDD comes into play when your domain is more complex and has associated behavior:
class MyEntity {
public void ChangeState(MyEntityState state) {
if (!IsValidState(state))
throw new Exception("Not a valid state.");
// further domain logic here...
}
}
[DataContract]
class ChangeStateCommand {
[DataMember]
public string MyEntityId { get; set; }
[DataMember]
public string State { get; set; }
}
public void Process(ChangeStateCommand command) {
var entity = this.myEntityRepository.Get(command.MyEntityId);
if (entity == null)
throw new SomeException().
entity.ChangeState(command.State);
this.myEntityRepository.Commit();
}
In this case, the data carried my ChangeStateCommand is used to operate upon your domain entity.

Domain Model – Repositories – Communication across Sub-Systems

I am currently in the process of designing a system which will use multiple data sources to consume the required data. I am attempting to model the concepts shown below (would post an image but don't have enough points!) where a customer can have an association with a number of products. The Customer would be stored in the "Customer subsystem" and the Product and CustomerProduct would be stored in thee "Product subsystem"
public class Customer
{
public string FirstName { get; set; }
public Guid ID { get; set; }
}
public class CustomerProduct
{
public Guid ID { get; set; }
public Customer Customer { get; set; }
public Product Product { get; set; }
}
public class Product
{
public string Name { get; set; }
public double Price { get; set; }
public Guid ID { get; set; }
}
The “Customer” entity will be physically persisted in a system which must be accessed via a web-service. The “ConsumerProduct” and “Product” entities will be persisted in a SQL database, using NHibernate as the ORM.
As part of the design I was planning to use Repositories to abstract the data persistence technologies away from the domain model. Therefore I would have 3 repository interfaces, ICustomerRepository, ICustomerProductRepository and IProductRepository. I would then create a concrete NHibernate implementation for the CustomerProduct and Product repositories and a concrete web service access implementation for the Customer repository.
What I am struggling with is how the entities, which are persisted in different sub-systems will interact. Ideally I would like a rich domain model, where the CustomerProduct entity would have a physical “Customer” property which returns a Customer object. However I have no idea how this would work as the Customer entity would need to be accessed from a different data store.
The only way I can see to solve this issue is to not maintain a full reference to Customer in the CustomerProduct entity and instead just hold a reference, and then every time I need to get a reference to the Customer I would just go via the Customer Repository.
I would be grateful for any suggestions anyone could put forward on how to solve this issue.
hi I haven't been in your situation before, but I have designing domains that communicate with other subsystems.
I do not have the whole picture, but it seems like the customer entity is more isolated from the others, CustomerProduct and Product. So am I guessing correct that you will present the model in a common GUI but its only the datasource that are separated?
First you can solve this by different ways and you should also ask yourself about non-functional requirements such as maintenance, uptime and support. Will both systems always be up and running simultaneously or will it happened that you take on system down. The clue I'm fishing for is should you communicate sync or async (message queuing?) with subsystems. This can be achieved by using NServiceBus.
But to focus on your Domain, you should go for making the Domain look like it only has one model. This can be accomplished in different ways:
1) Have your ICustomerRepository (an interface contract that acts like is working against a collection of objects) be implemented by a infrastructure related repository that consume your web service in your subsystem. A hint is that you should use GUID as keys so keyconfilcts occur. This approach will not let you have any relationships/associations to customer from your other entities. They will but only through the repository (This a solution that Jimmy Nilsson uses in his book (http://jimmynilsson.com/blog/) to not tighten the model with to many bidirectional relationships).
2) Depends how your use cases will target/use the model, but you can create a application wide service layer that resides at one physical place but uses CustomerService and CustomerProcuctService and ProductService. To prevent that domain logic will leak into application layer some of the coordination between these entites can be encapsulated in a domain event handlers that coordinate some events between different services.
3) you can also create a CustomerAdapter class that have the other subsystems CustomerGUID as a key (it cannot generate keys since Customer webservice have control of that). But you can map it in Nhibernate and have relationsship between CustomerProduct and CustomerAdapter. But when you Map CustomerAdapter you will only load the GUID. Then make sure you will have a ICustomerAdapterService injected into a property using Spring.Net Windsor or some other DI tool. Then you to not map properties (like customername, adress etc) for customerAdapter in Nhibernate. But when you get/read Adress from CustomerAdapter it will get it from ICustomerAdapterService and set all other values as well.
This is not a recommended solution since it will break some DDD rules, like not having services in domain model. But if you see it from this perspective: it actually can be considered a Domain Service since it solves problem within your distributed domain. However it includes infrastructure related things like a WCF service implementation and therefore should the service implementation be in another infrastructure layer/assembly
Most simple is the solution 2 If you can handle the fact that Customer Entity will be accessed only by a Service in application layer.
However this application serviclayer can be a good anticorruption layer between the two subsystems. There is probably a reason why you have two subsystems today.
But an example of interaction flow (with no detailed knowledge of how your domain is):
GUI calls Application Service CustomerProductService method BuyNewProduct(CustomerDTO customer, ProductDTO newProduct)
CustomerProductService have ICustomerProductRepository and IProductRepository injected into constructor. It will also have a infrastructure Service ICustomerFacadeService (change name now :-)) that is injected into a Property CustomerFacadeService. The creation of this service is done by a factory that have two creation methods, Create() and CreateExtendendedWithCustomerService(). The later one will also inject CustomerServiceFacade
The method BuyNewProduct(...) will now Assemble the CustomerDTO and use the CustomerGUID to load Customer from CustomerFacadeService that will call the web service in the other subsystem.
The loaded customer will ensure that it actually exists but now we load the Product with IProductRepository
With both CustomerGUID value and Product Entity we create a new CustomerProduct entity (which is actually just a mapping class between Products and Customer GUID's) and save it through ICustomerProductRepository
Now you can call another infrastructure service to send an email to your customer that will be notified that it has access to the new product. Or you can create Domain events in CustomerProduct entity that delegates this notification to en eventhandler (in application service layer) that has the IEmailService injected in ctor. Then you have incapsulted the domain knowledge of sending notifications when you connect a new customer to a product.
Hope this help you in modelling your domain with less pain. Because its painful to do DDD. Requires a lot discussions with colleagues, domain experts and yourself in front of the mirror :) Is this the right path?
Look at the DDDsample.net for Domain Events or search for Udi Dahan and domain events.
I write an answer here, more space:
Regarding CustomerAdadpter also refered as CustomerFacadeService in the interaction flow example here is my opinion: How to implement depends of your application. Will most usercase be calling mainsystem calling your "cloud-subsystem" which will have a good uptime: -Then you maybe do not need a queue and will have a WCF service in the cloud. Your CustomerFacadeService will be a service Wrapper that just exposes the method your application layer needs and also assemble all necessary DTO objects.
If your cloud system will also call back to your mainsystem then you need to expose some of your methods as a service. THEN you have the option to expose a NServiceBus endpoint as a WCF service. This gives you the possibility to take down the mainsystem without loosing information.
But there is always a lot of buts...
You need of course to have the WCF service on another machine if your infra-tech guys want to install hotfixes/reboot main system's web server.
If you have client's waiting for an response while main system is down, how long will they wait? Not too long I guess.
So one scenario I can see benefits of this is if you have batches/reports that need to be carried out, and if one part of the system is down, the reporting will continue once it's up again.
Here is some example of NServiceBus exposed as a WCF service. But I have no experience in doing exactly that, just the knowledge of "it can be done".
http://docs.particular.net/nservicebus/architecture/nservicebus-and-wcf

Objects returned from WCF service have no properties, only 'ExtentionData'

Im am not new to WCF web services but there has been a couple of years since the last time I used one. I am certain that last time I used a WCF service you could determine the type of object returned from a service call when developing the code. EG;
MyService.Models.ServiceSideObjects.User user = myServiceClient.GetUser();
You were then free to use the 'user' object client-side. However now it seems as if the WCF service will not return anything more than objects containing basic value types (string, int ect). So far I have remedied this by defining transfer objects which contain only these basic value types and having the service map the complex 'User' objects properties to simple strings and int's in the transfer object.
This becomes a real pain when, for example you have custom type objects containing more complex objects such as my Ticket object.
public class Ticket
{
public Agent TicketAgent {get;set;}
public Client Owner {get;set;}
public PendingReason TicketPendingReason {get;set;}
}
As simply mapping this object graph to a single transfer class with a huge list of inter-related system-typed properties gives a very 'dirty' client-side business model. Am I wrong in thinking that I SHOULD be able to just receive my Ticket object from a service method call and deal with it client side in the same state it was server-side ?
I realise this is probably a violation of some SoA principal or similar but my desktop app currently consuming this service is the ONLY thing that will consume ever consume it. So i do not care if many other clients will be able to manage the data types coming back from the service and therefore require some hugely normalised return object. I just want my service to get an object of type Ticket from its repository, return this object to the client with all its properties intact. Currently all I get is an object with a single property 'ExtentionData' which is unusable client-side.
Hope this makes sense, thank you for your time.
I might've missed a memo, but I think you need to decorate your model classes with DataContractAttribute and your properties with DataMemberAttribute, like so:
[DataContract( Namespace = "http://example.com" )]
public class Ticket
{
[DataMember]
public Agent TicketAgent { get; set; }
[DataMember]
public Client Owner { get; set; }
[DataMember]
public PendingReason TicketPendingReason { get; set; }
}
This is why you probably want to set up a DTO layer, to avoid polluting your model classes.
As for ExtensionData, it's used for forward-compatibility: http://msdn.microsoft.com/en-us/library/ms731083.aspx
I have marked Niklas's response as an answer as it has solved my issue.
While it seems you do not NEED to use [DataContract] and [DataMember], in some cases, I believe it could cause the issues I was experiencing. When simply transferring custom typed objects which, in themselves, only have simply typed properties, no attributes needed. However, when I attempted to transfer a custom typed object which itself had collections / fields of more custom typed objects there attributes were needed.
Thank you for your time.

Request/Response pattern in SOA implementation

In some enterprise-like project (.NET, WCF) i saw that all service contracts accept a single Request parameter and always return Response:
[DataContract]
public class CustomerRequest : RequestBase {
[DataMember]
public long Id { get; set; }
}
[DataContract]
public class CustomerResponse : ResponseBase {
[DataMember]
public CustomerInfo Customer { get; set; }
}
where RequestBase/ResponseBase contain common stuff like ErrorCode, Context, etc. Bodies of both service methods and proxies are wrapped in try/catch, so the only way to check for errors is looking at ResponseBase.ErrorCode (which is enumeration).
I want to know how this technique is called and why it's better compared to passing what's needed as method parameters and using standard WCF context passing/faults mechanisms?
The pattern you are talking about is based on Contract First development. It is, however not necessary that you use the Error block pattern in WCF, you can still throw faultexceptions back to the client, instead of using the Error Xml block. The Error block has been used for a very long time and therefore, a lot of people are accustom to its use. Also, other platform developers (java for example) are not as familiar with faultExceptions, even though it is an industry standard.
http://docs.oasis-open.org/wsrf/wsrf-ws_base_faults-1.2-spec-os.pdf
The Request / Response pattern is very valuable in SOA (Service Oriented Architecture), and I would recommend using it rather than creating methods that take in parameters and pass back a value or object. You will see the benefits when you start creating your messages. As stated previously, they evolved from Contract First Development, where one would create the messages first using XSDs and generate your classes based on the XSDs. This process was used in classic web services to ensure all of your datatypes would serialize properly in SOAP. With the advent of WCF, the datacontractserializer is more intelligent and knows how to serialize types that would previously not serialize properly(e.g., ArrayLists, List, and so on).
The benefits of Request-Response Pattern are:
You can inherit all of your request and responses from base objects where you can maintain consistency for common properties (error block for example).
Web Services should by nature require as little documentation as possible. This pattern allows just that. Take for instance a method like public BusScheduleResponse GetBusScheduleByDateRange(BusDateRangeRequest request); The client will know by default what to pass in and what they are getting back, as well, when they build the request, they can see what is required and what is optional. Say this request has properties like Carriers [Flag Enum] (Required), StartDate(Required), EndDate(Required), PriceRange (optional), MinSeatsAvailable(Option), etc... you get the point.
When the user received the response, it can contain a lot more data than just the usual return object. Error block, Tracking information, whatever, use your imagination.
In the BusScheduleResponse Example, This could return Multiple Arrays of bus schedule information for multiple Carriers.
Hope this helps.
One word of caution. Don't get confused and think I am talking about generating your own [MessageContract]s. Your Requests and Responses are DataContracts. I just want to make sure I am not confusing you. No one should create their own MessageContracts in WCF, unless they have a really good reason to do so.