This episode covers web and API development with Groovy: using frameworks like Grails or Micronaut, writing simple REST APIs with JSON serialization, and deploying to containers, the cloud, or JVM services.

Groovy isn't just for scripting and builds — it's also used to build web applications and APIs. With modern frameworks, writing REST APIs in Groovy is even more concise than in Java.
Episode 17 covers using Groovy with Grails and Micronaut, writing simple REST APIs with JSON serialization, and deploying to containers, the cloud, or JVM services.
Grails is a full-stack MVC framework that uses Groovy as its primary language. Its key concepts:
Grails follows convention-over-configuration: files in the right location are automatically wired up, so you don't write much manual configuration.
Micronaut is a modern framework that also supports Groovy, with the advantage of build-time compilation (AOT). Micronaut generates reflection and proxies at compile time, so startup is very fast and memory-efficient — suitable for serverless.
Choose Grails for full-stack applications with server-side UIs, and Micronaut for microservices and lightweight APIs.
Micronaut uses annotations to define endpoints:
import io.micronaut.http.annotation.*
@Controller("/sapa")
class SapaController {
@Get("/{nama}")
String sapa(String nama) {
"Halo, ${nama}!"
}
}@Controller("/sapa") marks the class as an HTTP handler, and @Get("/{nama}") maps a GET request with a path parameter. String sapa(String nama) is the handler returning a direct response — Groovy converts it to plain text.
For structured data, Micronaut automatically serializes Groovy objects into JSON:
@Canonical
class Pengguna {
String nama
int umur
}
@Controller("/pengguna")
class PenggunaController {
@Get("/{id}")
Pengguna ambil(int id) {
new Pengguna(nama: "Arman", umur: 25)
}
}@Canonical creates toString and the named constructor automatically. Pengguna ambil(int id) returns an object that Micronaut serializes into JSON thanks to the integrated Jackson library.
For manual control, Groovy provides JsonOutput for serialization and JsonSlurper for parsing:
import groovy.json.JsonOutput
import groovy.json.JsonSlurper
def data = [nama: "Arman", skill: ["Groovy", "Java"]]
def json = JsonOutput.toJson(data)
println json
def hasil = new JsonSlurper().parseText(json)
println hasil.nama
println hasil.skill[0]JsonOutput.toJson(data) converts a map into a JSON string, and new JsonSlurper().parseText(json) parses it back. hasil.skill[0] accesses the first element of the parsed list — Groovy's map and list structures survive the JSON round trip.
JVM-based APIs are most commonly deployed as containers. Here's a Dockerfile for a Micronaut application built with Gradle:
FROM gradle:8-jdk17 AS build
WORKDIR /app
COPY . .
RUN gradle build --no-daemon
FROM eclipse-temurin:17-jre
COPY --from=build /app/build/libs/app-all.jar /app/app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/app/app.jar"]FROM gradle:8-jdk17 AS build uses the Gradle image for the build stage, and FROM eclipse-temurin:17-jre uses a slim JRE runtime for the production stage. COPY --from=build ... app.jar copies the built artifact between stages — a size-saving multi-stage pattern.
docker build -t sapa-api .
docker run -p 8080:8080 sapa-apidocker build -t sapa-api . builds the image from the Dockerfile, and docker run -p 8080:8080 sapa-api runs the container while forwarding port 8080. docker build -t sapa-api . is the command that produces the deploy-ready image.
Once the container image is ready, there are several deployment targets:
For simple JVM services, Cloud Run is a cost-effective choice because it scales to zero when there's no traffic. For full orchestration, Kubernetes offers more control.
Episode 17 connected Groovy to the web world: choosing between Grails and Micronaut, writing REST APIs with controllers and domain classes, manual and automatic JSON serialization, and deploying to containers and the cloud.
The key takeaways:
@Controller and @Get annotations define REST endpoints.JsonOutput and JsonSlurper provide manual serialization control.In episode 18 next, we'll discuss plugin and extension development — creating plugins for Gradle or Groovy applications, packaging and publishing, reuse in the build ecosystem, and contributing to community plugins and reusable scripts.