WCF - contracts versioning (by example) - wcf

This should be easy for someone familiar with the best practices of versioning service/data contracts. I want to make sure that I will use this versioning in the correct way.
So, let's say we have a service contract:
[ServiceContract(Namespace="http://api.x.com/Svc1")]
public interface IService1
{
[OperationContract(Name = "AddCustomer")]
bool AddCustomer(DTOCustomer1 customer);
}
and data contract:
[DataContract(Name="Customer", Namespace="http://api.x.com/Svc1/2011/01/DTO")]
public class DTOCustomer1
{
[DataMember(Name="Name")]
public string Name { ... }
}
if I really need to change the latter into something else: (the following is just example)
[DataContract(Name="Customer", Namespace="http://api.x.com/Svc1/2012/01/DTO")]
public class DTOCustomer2
{
[DataMember(Name="Name")]
public string Name { ... }
[DataMember(Name="Address")]
public DTOAddress Address { ... }
}
...then how shall I use DTOCustomer2 instead of DTOCustomer1 from the service so that old and new clients will be compliant? What is recommended in this case? Will my service contract change? AFAIK I won't need to change the service contract. How will the service contract look like? Do I need a new endpoint? Do I need a new operation contract making use of the new data contract?
EDIT1:
Simply changing
bool AddCustomer(DTOCustomer1 customer);
into
bool AddCustomer(DTOCustomer2 customer);
will do?
EDIT2:
Answer to EDIT1 is No, since DTOCustomer2 has different namespace, but it might work if it has the same namespace. Still I don't know what is the best thing here and expect somebody to come up with a good answer.
Thank you in advance!

I ended up answering to this question with the help of another question here: WCF - handle versioning

Please find some useful links that describe the best practise for Data contract versioning.
Best Practices: Data Contract Versioning
Data Contract Versioning
The 2nd link describes on how you handle when you want to add or removed attributes of your data contract and few other scenarios.
Hope that helps.

Related

How to use a #FeignClient to map a HAL JSON _embedded collection

We're trying to use a spring-cloud #FeignClient to call the HAL-JSON REST API of a microservice from another microservice. The service is implemented with Spring Data Rest, Spring Boot 1.4, with Hateoas enabled by default.
Using a dedicated DTO on the client side, all the simple properties are properly mapped, but the HAL-specific _embedded collection is ignored.
As taken primarly from this post, we implemented a custom Feign Decoder with a corresponding ObjectMapper, using the often mentioned Jackson2HalModule, but this still does not solve our issue.
You can reproduce the issue with this sample project, where the problem is described in more detail.
We appreciate any help or hints on this problem! Thanks in advance
I think the key to understanding how to deserialize this is that your Customer is the Resources class that is embedding the relations. So you need to deserialize it as Resources in order for the HalResourcesDeserializer to pick it up.
I got it to work this way.
#Getter
#Setter
public class Customer extends Resources<Resource<Relation>> {
public static enum Type {
PERSON, INSTITUTION
}
private String displayName;
private Integer rating;
private Type type;
public Collection<Resource<Relation>> getRelations() {
return this.getContent();
}
}
This still looks a little odd and I am not sure if this is the best solution.
I know I am responding to an old question, but in my experience, I had to add #EnableHyperMediaSupport to my main/any configuration class to resolve this issue. You can try that and verify if it works for you.

QueuedDeliveryRequirements | Actual Meaning

Could someone please let me know what does QueuedDeliveryRequirements signify in DeliveryRequirements attribute?
MSDN says "Specifies whether the binding for a service must support queued contracts." This confuses me further as to what is "queued contracts". Please explain.
Thanks!
Very simply, when you define a service interface, eg:
[ServiceContract]
public interface ISomethingService
{
[OperationContract]
void Something();
}
there are no restrictions inherent in what kind of transport binding the interface will be exposed on, and this is a good thing, as it decouples the interface developer from having to think about how the service will actually be deployed and managed in the real world.
However, there are certain situations where as the interface developer, you need to bake in a requirement for a specific sort of binding, and a good example of this would be a queued binding. In WCF, Queued bindings are those transport bindings which take advantage of the msmq platform which comes with windows.
You may have good reason for specifying this at service design time - for example you need to enforce strict in-order, exactly-once, message delivery as part of your SLA.
If so WCF allows you to use the DeliveryRequirementsAttribute to specify this:
[DeliveryRequirementsAttribute(
QueuedDeliveryRequirements = QueuedDeliveryRequirementsMode.Required )]
public class SomethingService : ISomethingService
{
public void Something();
}
Hope this helps you.

WCF - handle versioning

If I need to go from this service contract:
[ServiceContract(Namespace="http://api.x.com/Svc1")]
public interface IService1
{
[OperationContract(Name = "AddCustomer")]
bool AddCustomer(DTOCustomer1 customer);
}
to this:
[ServiceContract(Namespace="http://api.x.com/Svc1")]
public interface IService1
{
[OperationContract(Name = "AddCustomer")]
bool AddCustomer(DTOCustomer2 customer);
}
and according to this good article: Versioning WCF I understand that when data contract is changed there is a need of defining a new vs of data contract in new namespace followed by defining a new vs of service contract in new namespace, after which a new endpoint should be added.
How exactly am I suppose to have this done. Is there an example anywhere? Could you write something based on my service contract shown above?
Thank you in advance!
According to the linked article you should do something like:
[ServiceContract(Namespace="http://api.x.com/Svc1")]
public interface IServiceNew : IService1
{
[OperationContract(Name = "AddCustomerNew")]
bool AddCustomer(DTOCustomer2 customer);
}
Then implement it in your service:
public class MyCurrentServiceImplementation : IServiceNew
{...}
You will need to redeploy your service but existing clients should be able to continue to call the AddCustomer operation, and new clients can call the AddCustomerNew operation.
It's very important to note that the assumption you state in your post:
"when data contract is changed there is a need of defining a new vs of
data contract in new namespace"
is not always true. See "Data Contract Versioning" on MSDN for a number of cases where a data contract change is non-breaking and may therefore require no action other than perhaps modifying the internal implementation of your service method to handle the presence/absence of certain data due to differences between data contract versions.
In this specific example I would question how two versions of a method called AddCustomer can vary so much in their intent that it justifies creating a new service interface. Without seeing your old and new data contracts I can't know for sure, but I'm guessing that the real issue here is that the method has evolved to accept additional customer information.
If that's true, then it's very much like the situation of optional arguments in a method call. WCF is designed to handle this scenario very nicely as a non-breaking change to the data contract. As long as you can follow the guidelines in "Best Practices: Data Contract Versioning" on MSDN, then calls supplying either the old or new version of the contract will be accepted just fine by your existing service interface. Your service method will get the data that is possible given the combination of the client and server data contracts.
I would keep my service interface coherent, simple, and clean (i.e. avoid doing things like IServiceNew) and instead just add to the data contract and modify the implementation of AddCustomer to adapt to the whatever data it receives.

What can I put in the namespace for WCF?

I just started learning on WCF and is trying to create a WCF service for my client application.
From the msdn tutorial, I have went through all the individuals steps and sort of grasp how WCF works and now I am trying to start coding the service on my part. For the first step it says, defining a service contract. and the sample code msdn gives are as follows
namespace Microsoft.ServiceModel.Samples
{
class Program
{
static void Main(string[] args)
{
}
}
}
and the service contract.
[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
what i would like to ask is, what can i actually substitute the namespace with since I am developing for my own application?
The namespace can be a string - typically it's a URI, like in your question, but it could also be a simple dotted namespace
[ServiceContract(Namespace = "Microsoft.ServiceModel.Samples")]
Contract namespaces are just strings to resolve possible conflicts (can be useful when versioning, for example). If you omit it your WSDL will contain http://tempuri.org. Not what you want in production. However, it's not that easy to just set proper name in ServiceContractAttribute, there are also binding and schema namespaces. For better understanding WSDL namespaces in context of WCF I highly recommend this blog post.

Adding REST methods to WCF Data Services?

I need to extend my WCF Data Service to include additional methods, not only the database tables..
But it doesn't seem to be working correctly.
Firstly i want to ask if this is legal? or frowned upon?
The reason i need to do it is i need add additional REST methods that will make a call to ASP.NET Membership services (the tables are in the db) to validate a login i.e.
public bool IsValidLogin(string username, string password)
{
return System.Web.Security.Membership.ValidateUser(username, password);
}
Here is what i have (i have simplied the IsValidLogin for testing).
[WebGet(UriTemplate = "TestMe")]
public bool IsValidLogin()
{
return true;
}
// This method is called only once to initialize service-wide policies.
public static void InitializeService(DataServiceConfiguration config)
{
// TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc.
// Examples:
config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);
config.SetServiceOperationAccessRule("IsValidLogin", ServiceOperationRights.All);
Now when i go to
http://localhost/MyDataAccess/MyService.svc/IsValidLogin
It seems to work i get an true back in the form of XML. But i have set a URI so i thought i could do this
http://localhost/MyDataAccess/MyService.svc/TestMe
But it fails? I am really confused, any ideas?
Also for it to work I needed to add this line, but a little but confused here
config.SetServiceOperationAccessRule("IsValidLogin", ServiceOperationRights.All);
Any help really appreciated
Not commenting on the REST dicsussion above, just posting a link on documentation on how to do so called "service operations": http://msdn.microsoft.com/en-us/library/cc668788.aspx
The ServiceOperation notion is a tacked on capability to provide exactly the escape you needed when you wanted to do something other than read data from a table.
Unfortunately, the default path in WCF REST has lead you to misunderstand how RESTful systems are supposed to work. REST is not just about exposing some data at URLs.
You really have two choices, either stick with RPC style of distributed computing that WS-*/SOAP based WCF provides or spend some time learning what REST is really all about. There are some links here to get you started.
I can't tell you what is the right approach for your scenario. What I can tell you is that you are not going to learn how to do REST from using the current WCF REST implementation. I'm not saying it is impossible to do, you just will be doing a lot of swimming upstream.