Microservices in .NET Core with examples in Nancy
Christian Horsdal Gammelgaard
The theatre director Sir Peter Hall once said that the name of the institution he founded, the RSC, contained his three favourite words: Royal, Shakespeare and Company. I feel a little like that about the title of this recent book by Christian Horsdal Gammelgaard. The combination of .Net Core, the microframework Nancy and microservices is incredibly exciting for those of us brought up on the Microsoft stack. They offer the possibility of achieving highly scalable designs deployed wherever we like but without the verbosity and cruft of Microsoft's hefty frameworks and libraries. Maintaining 7digital's web API for serving digital music at scale has given me some insight into using Nancy with independent services. It is fair to say that Horsdal, a contributor to Nancy, has both outlined the benefits I see every day and opened my eyes to a few I had never considered.
He starts with a definition of microservices that I particularly like. My (perhaps idiosyncratic) view is that microservices win because it is so hard to scale applications that have a bottleneck caused by a database join. Since tables grow at different rates in a system, it may well arise that a reasonably simple SQL query will start to creak when the table on the other side of a join becomes massive. Whereas a reactive system can wait asynchronously for a HTTP call to another service and still serve its users in a timely fashion, it is much harder to pound a database with queries that need to execute complicated query plans without everything getting nasty. So whereas some people concentrate on the freedom to implement different microservices in different languages or platforms, Horsdal (following Martin Fowler) recognises this centrality of data ownership to the notion of a microservice, something with which I readily concur.
Nicely, the book uses a realistic scenario for illustrative purposes. It is hardly the first shopping cart to be mock-implemented in a programming book, but the decomposition of the cart into microservices has several useful pedagogical purposes. Firstly it is a nice domain driven exercise in itself that shows realistic sizes for microservices. Secondly it offers the opportunity to describe common characteristics all programmers deal with in writing services: those that respond to events, those that are command driven or those that deal with cross-cutting concerns like logging. A lot of the solutions he outlines are very similar to the work we have done with ours. Perhaps we all have.
There are some sections of the book that are indebted to others, whether the author realises it or not. Someone looking for advice on the test pyramid, for example, would be much better off reading Mike Cohn's Succeeding With Agile. Similarly, some of the section about robustness uses a lot of the ideas of Release It!. But there are some areas of expertise that are better here than anywhere else I have seen. The advice on writing tests using
Nancy.Testing is superb, and deserves to be followed in projects everywhere.
But we don't just read books to be impressed by the things we already agree with. There were several things here that I didn't know about at all. Your mileage may vary, but I discovered the fault-handling library Polly that I have already incorporated into our codebase. More significantly the section on Open Web Interface for .Net (OWIN) is new to me and fills a big hole in my knowledge. The idea of putting cross cutting concerns into the middleware was a lightbulb moment that I really want to develop.
In summary, I heartily recommend this elegant outline of modern .Net application architectures that really help write maintainable, scalable applications in the real world.