Putting Together a Full-Stack Codebase
I was recently looking for a way to serve a React application in a Spring Boot microservice and have the two together in a single, unified, and manageable codebase. If you're working for a large company, then it's usually best to keep the two separate. However, this is just for my personal projects and one repository to keep track of helps with velocity.
An Overview
For those unfamiliar with the Spring Framework, it is a collection of different projects that make application development easier for Java and Kotlin developers. Spring Boot is a microservice starter and is one of those projects. Simply put, the build.gradle.kts
in a Spring application is the equivalent of the package.json
in a React project, as it has your dependencies and tasks (which are the same as scripts).
Not too long ago, Groovy was the domain-specific language (DSL) for the Gradle build file. I have seen various articles about achieving what I want to accomplish with Groovy, but I didn't see an examples using Kotlin, which has now become the default DSL.
A domain-specific language is a computer language specialized to a particular application domain. The build file in a Spring project is the application domain.
Spring Into Action
The Spring Initialzr can help you create an project and the only dependency you need is the Spring Web starter.
The generated Spring Boot project structure will look like this:
├── gradle
│ └── wrapper
└── src
├── main
│ ├── kotlin
│ │ └── me
│ │ └── darkes
│ │ └── springbootreactgradlekotlin
│ ├── resources
└── test
└── kotlin
└── me
└── darkes
└── springbootreactgradlekotlin
Creating the React Application
Run the following command inside the /src/main/
directory of your Spring Boot project.
create-react-app webapp --use-npm
This will go ahead and make a new directory called /webapp
with your newly made React application.
Setting Up the Gradle Build File
The whole process of having a combined codebase is possible because of the Gradle plugin, Gradle Node Plugin.
In a Spring application the resources/
directory is where we'd put our generated React build/
files, because that is where a Spring application looks for static files to serve.
Add all of this to your build.gradle.kts
file in your Spring Boot application root directory.
plugins {
id("com.github.node-gradle.node") version "2.2.2"
}
tasks.register<NpmTask>("appNpmInstall") {
description = "Installs all dependencies from package.json"
workingDir = file("${project.projectDir}/src/main/webapp")
args = listOf("install")
}
tasks.register<NpmTask>("appNpmBuild") {
dependsOn("appNpmInstall")
description = "Builds project"
workingDir = file("${project.projectDir}/src/main/webapp")
args = listOf("run", "build")
}
tasks.register<Copy>("copyWebApp") {
dependsOn("appNpmBuild")
description = "Copies built project to where it will be served"
from("src/main/webapp/build")
into("build/resources/main/static/.")
}
node {
download = true
version = "12.13.1"
npmVersion = "6.12.1"
// Set the work directory for unpacking node
workDir = file("${project.buildDir}/nodejs")
// Set the work directory for NPM
npmWorkDir = file("${project.buildDir}/npm")
}
tasks.withType<KotlinCompile> {
// So that all the tasks run with ./gradlew build
dependsOn("copyWebApp")
kotlinOptions {
freeCompilerArgs = listOf("-Xjsr305=strict")
jvmTarget = "1.8"
}
}
Building the Project
All you have to do is run ./gradlew build
from your project root directory. You'll notice after Gradle is finished, the React build directory is in the new location build/resources/main/static/
.
If you want to see the application in action you can run java -jar build/libs/PROJECT_NAME.jar
from the project root directory. Then visit localhost:8080
.
How It All Works
Typically with a normal React application you'll use npm install
and npm run build
. The Gradle plugin provides NpmTask
to run those same commands. The tasks that I included are all that's needed to install, build and copy the files to where the Spring Boot application will notice them. Additionally, if you're someone who prefers Yarn or just wants to run a Node.js script, you can use this plugin to do that too!
The code can be found here:
iamdarkes / spring-boot-react-gradle-kotlin-dsl
Using Gradle's Kotlin DSL to Bundle React With a Spring Boot Web Application
I hope this was helpful. If you're used to using another language or technology for your server-side code, this starter is a great way to give Kotlin and Spring Boot a try.
Top comments (0)