Complete tutorial of creating RESTful API with Spring Boot.

Configuration
Java Compilation:
Java Runtime:
Maven:
Java Compilation:
Java Runtime:
Gradle:
JDK 17.0.2
JRE OpenJDK 17.0.2
Maven 3.9.6
JDK 17.0.2
JRE OpenJDK 17.0.2
Gradle 8.6
Create the following folder structure:
folder structure of Create first RESTful API with Spring Boot
pom.xml: (if using Gradle, replace pom.xml with build.gradle)
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.2.5</version> </parent> <groupId>net.maxjava</groupId> <artifactId>FirstSpringBootWebService</artifactId> <version>1.0</version> <packaging>jar</packaging> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <scope>compile</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.30</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
plugins { id 'java' id 'org.springframework.boot' version '3.2.5' id 'io.spring.dependency-management' version '1.1.4' } group 'net.maxjava' version '1.0' repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' compileOnly 'org.projectlombok:lombok:1.18.30' annotationProcessor 'org.projectlombok:lombok:1.18.30' }
Some notes about pom.xml:
  • spring-boot-starter-parent as parent POM for Spring Boot application
  • Spring Boot 3.2.5 requires Java 17
  • lombok is used to remove boilerplate code like get and set
  • Use spring-boot-maven-plugin to re-package all dependencies into a single, executable jar
  • By running mvn clean package, a jar artifact which is ready to run by using java -jar will be created
Some notes about gradle.build:
  • Use org.springframework.boot plugin for Spring Boot application, to make the jar executable and re-package all dependencies into a single jar
  • Spring Boot 3.2.5 requires Java 17
  • Use io.spring.dependency-management plugin for dependency management
  • lombok is used to remove boilerplate code like get and set
  • By running gradle clean build, a jar artifact which is ready to run by using java -jar will be created
MySpringBootWebApplication.java:
package maxjava; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class MySpringBootWebApplication { public static void main(String[] args) { SpringApplication.run(MySpringBootWebApplication.class, args); } }
Some notes about MySpringBootWebApplication.java:
  • Mark a class with @SpringBootApplication and pass the class in SpringApplication.run will be good enough to run a Spring Boot application with web server (default setting)
  • We could just put SpringApplication.run inside the static main function and annotate the same class for simplicity
MyController.java:
package maxjava.controller; import maxjava.model.Square; import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/myapp") public class MyController { @GetMapping("/square") public Square getSquare(@RequestParam("side") int side, @RequestParam("color") String color) { Square square = new Square(); square.setArea(side * side); square.setColor(color); return square; } @PostMapping("/square") public String postSquare(@RequestBody Square square) { return "Got square, which the side is " + Math.sqrt(square.getArea()); } }
Some notes about MyController.java:
  • Specifying @RestController will make this a controller to handle web request. Using @RestController instead of @Controller to perform serialization automatically, without the need of using @ResponseBody
  • @RequestMapping("/myapp") + @GetMapping("/square") will make the getSquare function map to the path in the URL to GET /myapp/square
  • @RequestParam will map to the query param side and color
  • @RequestMapping("/myapp") + @PostMapping("/square") will make the postSquare function map to the path in the URL to POST /myapp/square
  • @RequestBody is to perform de-serialization into the Java object
Square.java:
package maxjava.model; import lombok.Data; @Data public class Square { private String color; private int area; }
Some notes about Square.java:
  • This is the object used in the request or response body on the Controller APIs
  • Use Lombok @Data for get and set
To run the application, java -jar target/FirstSpringBootRESTAPI-1.0.jar
Sample output:
  • GET:
    curl --request GET '<CONTEXT_PATH>/myapp/square?side=12&color=blue'
    Response:
    { "color": "blue", "area": 144 }
  • POST:
    curl --request POST '<CONTEXT_PATH>/myapp/square' --header 'Content-Type:application/json' --data ' { "color": "blue", "area": 144 }'
    Response:
    Got square, which the side is 12.0