This morning at SpringOne, Josh Long and Dave Syer provided an introduction to writing microservices with Spring Boot with a live coding session demonstrating the construction of a Spring microservice. The entire process took about 60 minutes (with frequent stops for explanation) and resulted in a service that returned reservation information. The code can be found here.
In the fast and inspiring demo, a few things happened that touched upon larger concepts that Spring developers encounter on a regular basis. A conference like Spring One provides us an unusual opportunity to discuss those concepts with other Spring developers. So this blog post provides an event-specific conversation starter for discussing those concepts.
Example 1 — app creation: to jump-start the app, Josh used the Spring Initializr. To do this he visited to start.spring.io, chose the options he wanted, named the app, and clicked ‘Generate Project.’ (Fun fact: Intellij also has a Spring Initializr plugin that can do this for you via a wizard). On a few occasions throughout the talk, though, we needed to go back and add options that we had forgotten to check upon creating the app. In order to do this, Josh dove into the pom file and included those additional options. So there isn’t any magic associated with the option checkboxes: they generate pieces of the pom file that can also be introduced manually.
The availability of automated vs. manual options for changing a Spring app brings up an age-old programming question that remains a central point of controversy in many frameworks: how much magic is too much magic? A pom file generator at least provides visible magic. But we regularly use annotations in Spring like @RestController, @RequestMapping, and @Autowired, and we could technically get away with using them without exactly knowing how they work. Is this a problem? How much should we, as Spring developers, do to understand the code that underlies these annotations?
To answer these questions with any degree of nuance, I would argue that we have to differentiate between magic that makes it more obvious how code works and magic that makes it less obvious how code works. The @Service annotation often gets used as an example of an annotation designed specifically to make the purpose and role of an app component more obvious. Conversely, the Rails framework for Ruby frequently comes under fire for obscuring details about the way that an app works. This post is not meant to denigrate Rails or applaud Spring, but rather to provide examples of how developers react to different attempts to do the same thing: make applications easier to write. In the process, it seems that we run into another problem: how to make applications easier to read.
As app writers, we tend to talk a lot about app writing and less about app reading, but in many cases we end up doing a lot more reading than writing while implementing features. So we want to make sure that the code reads as self-evidently as possible. We do this with our very own code, but it’s also worthwhile to think about what our framework does to assist or hinder us in this regard. So what kinds of framework helpfulness make apps easier to read? How does Spring succeed at that, and how could it be better? What can it take from other frameworks like Rails, and what might other frameworks like Rails do well to take from Spring? Those questions make sense to ask when we have so many other developers around who use the same framework that we do.
Example 2 — @EnableZuulProxy: this one-line annotation establishes a proxy in our client app that connects to the server app and forwards requests and responses along. This annotation provides an apposite example Spring Boot enabling developers to create a functioning app with as little code as possible. It took Josh only a few seconds to throw this on, as opposed to using a more involved and time-consuming method to establish such a proxy.
That is an important stated goal of the Spring framework as a whole: allow developers to write apps with as little code as possible. For this reason, a Spring developer can benefit most from the framework (and learn a lot in the process) by acting upon this assumption:
“If this app structure problem is not unique to my app, then Spring has a solution.”
Will this assumption hold true all of the time? No, probably not. But then again, most assumptions don’t. That having been said, for every occasion when someone has searched for the Spring way to do something and come up empty, there have been multiple occasions where a developer writes something in a Spring app that feels boilerplate-y or even hacky, only to find out later that Spring has an easier way to do that. I have seen this happen with request interceptors, dependency injection, asynchronous tasks, and live documentation. Why does this happen? I wonder if it’s because we’re not always looking for info before we code, of if we are looking and we’re finding the info hard to find. In either case, other developers at a conference like this can give great insights about where to find information and even how to figure things out within the framework.
Because when we are developing Spring apps and we come upon a new problem that we (or developers we know of) have solved before on some other app, it pays for us to search for support from Spring.
…and even if we don’t find it, we can submit feature requests, extend the framework for our own purposes, or publish our extensions for others.
We have dozens of opportunities this week to watch, listen, and learn about how to develop apps with Spring and Groovy. While we are here among such a large group of our peers, it may also pay to explore questions about how to develop Spring and Groovy themselves, as well as how to develop ourselves as developers.