Explore WCF service using Cassandra
This is a brief tutorial on how to use Apache Cassandra’s user-defined types (UDT) with C# Windows Communication Foundation (WCF) rest service.
Summary of the Steps
- 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
1. Create User Defined Type
Create a user-defined type for address, fullname and users. There is more info in this datastax tutorial for UDT.
2. Create a mapper object for UDT in ‘C#’
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<FullName> DirectReport { get; set; }
public FullName Name { get; set; }
}
3. Register C# UDT object
Configure the POCO object to the Apache Cassandra driver using mapper component.
Map user-defined type (FullName and Address):
session.UserDefinedTypes.Define(
UdtMap.For<FullName>(),
UdtMap.For<Address>()
.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<User>().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()));
4. Connect to Cassandra cluster and create session
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<User>(session);
var user = users.
Where(u => u.Id == Guid.Parse(guid))
.FirstOrDefault()
.Execute();
5. Setting up a WCF
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();
}
}
6. Hosting WCF service
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.