This is a brief tutorial on how to use Apache Cassandra’s user-defined types (UDT) with C# Windows Communication Foundation (WCF) rest service.
Create user-defined type(Udt)
Create a mapper object for Udt in C#
Register C# Udt object
Connect to Cassandra cluster and create session
Define WCF DataContract and OperationContract
Host in IIS
Create a user-defined type for address, fullname and users. There is more info in this datastax tutorial for UDT.
Create a mapper object(CqlPoco). In our case that will also be a data contract. For more data types mapping, refer to CQL data types to C# types.
Class for address:
public class Address
{
public string Street { get; set; }
public string City { get; set; }
public int ZipCode { get; set; }
public IEnumerable<string> Phones { get; set; }
}
Class for fullname:
public class FullName
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
Finally, a class which represent a row in cassandra users table:
public class User
{
public Guid Id { get; set; }
public IDictionary<string, Address> Addresses { get; set; }
public IEnumerable DirectReport { get; set; }
public FullName Name { get; set; }
}
Configure the POCO object to the Apache Cassandra driver using mapper component.
Map user-defined type (FullName and Address):
session.UserDefinedTypes.Define(
UdtMap.For(),
UdtMap.For()
.Map(a => a.Street, “street”)
.Map(a => a.City, “city”)
.Map(a => a.ZipCode, “zip_code”)
.Map(a => a.Phones, “phones”)
);
In most of the cases, mapper will do the mapping for simple type like Fullname but a better controlled mapping is also possible, like Address, where it is mapped field by field.
Map User class representing a row in a table:
Cassandra.Mapping.MappingConfiguration.Global.Define(new Map().TableName(“users”)
.Column(c => c.Id, cm => cm.WithName(“id”))
.Column(c => c.Addresses, cm => cm.WithName(“addresses”).WithFrozenKey())
.Column(c => c.DirectReport, cm => cm.WithName(“direct_reports”).WithFrozenValue()));
Cassandra and C# setup is complete, so now connect to cluster and use it.
cluster = Cluster.Builder().AddContactPoint(“127.0.0.1”).Build();
session = cluster.Connect(“mykeyspace”);
var users = new Table(session);
var user = users.
Where(u => u.Id == Guid.Parse(guid))
.FirstOrDefault()
.Execute();
Decorate the POCO we just created with the DataMember attribute, declare OperationContract and provide a definition. Register mapping (see step 3) with a memoization library. In this case, service constructor was leveraged to initialise the mapping.
public class UserService : IUserService
{
static UserServiceLibrary.Data.DataService dataService;
static UserService()
{
dataService = new UserServiceLibrary.Data.DataService();
}
}
WCF rest service can be self-hosted using WebServiceHost:
WebServiceHost webhost = new WebServiceHost(typeof(UserService));
try
{
webhost.Open();
Console.ReadLine();
webhost.Close();
}
catch (Exception e)
{
Console.WriteLine(e);
webhost.Abort();
}
}
WCF can also be hosted in IIS to take the advantage of on-demand loading and application pool using:
<%@ ServiceHost Service=”WcfWebService.UserService”
Factory=”System.ServiceModel.Activation.WebServiceHostFactory”%>
The complete source code for this tutorial can be found at Github.