If you watch Taylor Wicksell of Netflix's SpringOne Platform keynote you can’t help but be blown away by the sheer productivity of their engineering team. Last year, over 300 Spring-based apps went into production – an incredible achievement.
What Can Your Enterprise Learn From Netflix?
At Netflix, Taylor and his Java Platform team own the Java developer experience (DevEx). Taylor’s team has one mission: to help Netflix's engineers stay productive, delivering great code at great velocity. It’s a mission that is clearly proving successful.
Top of Taylor’s list of productivity secrets is Application Generators. Netflix found that developers adopt platforms far quicker when everything they need to get started is right there, at their fingertips. Application generators help developers to get started quickly by providing useful guide rails that reduce toil and ease their burden. Application generators also encourage common approaches to common problems, which is particularly useful if you have lots of teams creating microservices at the same time.
Also high on Taylor's list is easing access to important libraries. Every enterprise has libraries: tools they rely on to simplify tasks or take care of the plumbing. These libraries are quite important and often including proprietary business logic that’s both private and unique. Application generators can help developers to get easy access to these libraries without having to delve into docs, wade through wikis, or search in Maven repositories.
Are Application Generators Popular?
Yes. You probably use an application generator already. The best example I can think of is start.spring.io, also known as the “Spring Initializr” (although others exist, such as this one for .Net applications).
Spring Initializr makes generating Spring Boot apps a cinch.
The proof? Spring Initializr generated over 15 million Spring Boot projects in the last 12 months – up 63% on the year before. It’s phenomenally successful. It’s also living proof that a great developer experience can lead to greater reuse and wider adoption as this data from JetBrains illustrates.
The secret to its success is no secret at all: it’s superbly easy to use. You can use it in your browser, or directly from inside your IDE. You can even use it from the command line via cURL or HTTPie or from the Spring Boot CLI.
Build Your Own Application Generator
How? With Spring of course! There’s even a library for it. The library is also called Spring Initializr. It’s the core library that powers start.spring.io, and it's super easy to customize. In the rest of this article, we’ll walk through the steps required to create your own customized Initializr.
To imitate what you would do inside your enterprise, in this tutorial we’ll narrow some of the application generation options and include some libraries that the regular Spring Initializr doesn’t offer, namely the Axon CQRS and Event Sourcing Framework. We’ll call our project the “Axon Initializr”.
Follow these steps, and before you know it you’ll have easier access to custom libraries, greater adoption of preferred patterns, and a vastly improved developer experience!
NOTE: The full code from this tutorial can be found here on GitHub.
On to the tutorial!
Step 1: Create a Spring “Web” Project
At the risk of getting recursive, we can use the start.spring.io website to start building our Axon Initializr!
Using the website, create a project with the settings in the screenshot below (or use this link which uses the handy new “Share” feature). Make sure you include the “web
” dependency. We’re building a RESTful web service, so we need those libraries present.
Hit the green “Generate” button to download the project as a Zip file. Unpack the zip and open the generated project folder in your IDE or text editor. Now we can begin to build our custom axon-initializr
project.
Step 2: Add Spring Initializr As A Dependency
We need to add a few entries to our Maven pom.xml
in order to include in our project the Spring Initializr libraries. In the POM, add a dependencyManagement
entry for the Spring Initializr as shown below:
|
Next, add a couple of extra Spring Initializr dependencies into our POM’s existing <dependencies>
section:
|
The initializr-web
dependency is bringing in predetermined application generation endpoints which IDEs can talk to, and the initializr-generator-spring
brings in preset opinions about how to build Spring Boot projects (which we want). Now we’re ready to customize the axon-initializr
.
Step 3: Configure The Basic Generator Options
The Spring Initializr library can generate application projects based on a host of different choices (language, build tool, etc.). However, in your enterprise, it may be prudent to limit these choices. This way, you can encourage certain approaches. (These are the aforementioned guide rails.) For example, your enterprise may have a preferred database or a preferred messaging platform, so it would complicate things if you offered any others.
We configure our Axon Initializr using an application.yaml
file. In our axon-initializr
project, rename the src/main/resources/application.properties
file to application.yaml
. Then, start customizing by adding the following YAML configuration:
|
These “initializr:
” parameters configure our application generator by specifying the available choices for:
-
Java Versions (just 8 and 11 for now)
-
Languages (Java and Kotlin, but not Groovy)
-
Build and packaging (Maven and JAR, respectively).
You’ll notice default: true
, on some items. This setting automatically promotes our preferred options when no choice has been made.
Let’s run a simple test, to make sure we’re on track. First, build and run the new Initializr project with the command:
|
Then, in a separate terminal, use cURL to access the Initializr help:
|
The output in your terminal window should look similar to the screenshot below:
This confirms the axon-initializr
started up as expected and incorporated the desired Spring Initializr libraries. But it’s not yet ready to start generating Spring or Axon applications. Use Ctrl-C
in the first terminal window to stop the axon-initializr
, and we’ll continue with our customization.
Step 4: Add Spring Libraries
Adding regular Spring libraries is easy. We simply create an entry for each library in our YAML configuration’s “dependencies:
” list. The downside: YAML is quite verbose. I’ll just show one entry here for the Spring Web project to get you started. (The rest are in GitHub.)
Dependency entries start with a name
followed by a list of content
items. In the example below, you’ll see the “Web
” dependencies group, and then an entry for “Spring Web
”:
|
NOTE: You can copy any other Spring related entries you like from this example YAML file from start.spring.io.
Step 5: Add Your Custom Libraries
This is the last configuration step! For our Axon Initializr, we need to add our custom Axon libraries. For brevity, I’ll just add a single Axon library here as an example. But when customizing your initializr you can add as many entries as you need.
|
You might notice that this configuration looks different from the configuration in step 4. That’s because we’re explicitly calling out the Maven coordinates of each library (the groupId
, artifactId
, and version
). We do this because the Axon Framework libraries are outside Spring, so we need to be specific.
NOTE: The examples here are just snippets. You can see the complete axon-initializr
YAML configuration here in GitHub.
Try The Axon Initializr From Your IDE
Now we’ve added our desired configurations and customizations to the axon-initializr
project it’s time to use it to generate an Axon application in our IDE.
NOTE: I’ll use IntelliJ IDEA Ultimate Edition as my IDE, but the same smooth developer workflow can also be accomplished easily with Eclipse, Spring Tools, NetBeans, or Visual Studio Code in much the same way.
First, start the axon-initializr
service in your terminal:
|
Then, start IntelliJ IDEA and choose “File → New → Project...” and on the next screen, choose ‘Spring Initializr’ as your new project type in the panel on the left. Then, in the center panel switch the service endpoint URL to http://localhost:8080 like this:
When you click “Next,” you can begin to customize your new Axon based application. Our efforts to standardize are already paying off; the default project name, group id, artifact id, package, packaging, language, java version, and description all come from our default settings in the application.yaml
within the axon-initializr
.
Finally, after clicking “Next” again, we can configure our (still yet to be generated) Axon application project.
We start by adding our desired dependencies from our axon-initializr’s
curated list. In the screenshot below, you can see that alongside the various standard Spring tools like Spring Data JPA and Spring for RabbitMQ (if you added them), we can also select our custom libraries like Axon Framework. It all works seamlessly, mixing our preferred Spring libraries with our custom Axon libraries.
And we’re done. After setting a few more items in IntelliJ IDEA (such as the folder to generate the application into) clicking the “Next” button for the final time will create our new Axon application project and take us straight into the IDE. From there we can get to work on our CQRS application, adding Commands, Queries, Events, and Aggregates.
Wrapping Up
As you’ve seen, creating a custom application generator using the Spring Initializr library as a base is really easy, and it greatly improves our developer experience. By adding your preferred libraries and other customizations, you make it easy for developers to “do the right thing” and give them something that everybody wants – more time to work on the things that really matter!
I’ve only scratched the surface of what’s possible with Spring Initializr customization. To find out more about the many other customization options, take a look at the official documentation. And finally, don’t forget that the code that accompanies this tutorial can be found here on GitHub.