I am on a new project at work that looks to be very interesting. I am redesigning our Cassandra layer. Currently we have a beautifully done layer that was designed and implemented by our former architect. It ends up making Cassandra look just like a JPA entity and we have Cassandra Repositories that look just like Spring Data JPA Repositories. After this was in place we discovered the Spring Data Cassandra project. We went to the talk on Spring Data Cassandra and it turns out they had implemented pretty much the system that our architect implemented.
Now my goal for this project is to create a higher level Cassandra abstraction for our system. Often in Cassandra we create multiple tables to represent the same data. The reason is depending on how you structure the data in CQL determines what queries you can run. We have the need to query some tables in many different ways so we need multiple tables to be able to answer the questions that we could in the SQL world. In our architecture we don’t want the developer to worry about which table they need to query for a given question, we would like to present this more like a standard JPA entity where the developer doesn’t need to worry about it and we abstract away which particular table is being queried or which tables are being saved to.
One of the initial thoughts of this project was to use Spring Data Cassandra. The advantage of that is we would have a third party library we could use so we wouldn’t have to maintain the low level Cassandra code. At one point I was considering ripping out our custom Cassandra Data layer and just using the Spring Data one (prior to this project) as ours is so close to what they are doing anyway why should we maintain that code when there is a perfectly good library we could use and we are already using Spring Data JPA. Right now I am not sure if I want to do that anymore though. If I go with Spring Data Cassandra each of the underlying tables would need to be modeled as a separate entity like our current framework. In that case then I would need a second layer on top if I am trying to present 1 domain object backing multiple tables so this seems like it isn’t ideal for what we are thinking. Another thing I am not 100% on with Spring Data Cassandra is that it isn’t backed by Pivotal. It is a community plugin. That isn’t necessarily a problem but I do have concerns about how up to date it will be. One way to look at this is maybe I should be involved in the plugin since clearly I could be working on that as well, but I get a little concerned about if it will be around otherwise. I noticed that the Spring Data Cassandra project is built off of the Datastax 2.0 driver. So if we are running off of Cassandra 2.1 (which we probably will be by the time this project goes live) we aren’t necessarily taking advantage of the new features. Again I could submit a pull request to update it, but given that I am not sure this is the right approach anyway at this point I haven’t decided to go this route (though that may change). Another thing I noticed is Spring’s initializr doesn’t list Cassandra as an option out of the box. Though I suspect if you checked JPA and then added the Spring Data Cassandra to your maven pom or Gradle file it would probably work.
So how does this tie into Spring Boot? Well I am not a big design everything up front kind of person. I tend to like to play around in code to come up with my design ideas. So I decided I want to prototype against what we are doing so I can see how this design would play out in code. I downloaded a new Spring project from the initializr with AOP, JAX-RS, Actuator, and Shell support. I then pulled our code for our Cassandra layer into there and added the Cassandra driver to the maven pom. I updated the application.properties file with my Cassandra database properties and low and behold I was up and running with a framework to test all of my changes in. Even though I have played around with boot, seeing myself able to build a sandbox to play around with this design in so quickly was very impressive to me. So now I can evolve this design without messing up our current code base and when I get to something I am happy with I can just bring those changes into back into our branch and we will be ready to go with our new design. So even though I am stuck with a monolith and I couldn’t easily bring boot into our main product the design of our project is such that it was very easy to pull that whole layer into this project and just be up and running with almost no configuration (aside from setting up the Cassandra connection properties).
So as usual I think Spring Boot is the bomb and everyone should be using it. I look forward to seeing where this design takes me. Once I have my high level sorted out I may try playing with dropping Spring Data Cassandra in the low level to see if we want to use that as our base, but my current guess is we won’t end up going that route.