+++ categories = ["software"] tags = ["java"] date = 2024-11-10T15:55:42Z description = "" draft = false slug = "java-spring-tomcat" title = "☕ Developing Spring REST API - Pt. I" author = "nicholas" +++ Much time has passed since I last worked with Spring framework in Java. I need to build out a development environment to enable me to build Java applications. In this log, the environment will be configured to include the following tools and features: * Eclipse IDE * Java (JRE, JDK) * Maven (dependency manager, etc.) * Spring Boot (Java framework) This log is a series of baby steps that will result in basic implementation of a REST API. ## Code Editor First, I need a code editor/IDE. I selected Eclipse for no particular reason. My understanding is that IntelliJ IDEA is a more modern, refined alternative that I may try down the line. For now, all I need is a default installation to get started. ## Hello World I allow the IDE to walk me through a hello world tutorial to become familiar with the software and remind myself of the basic structure of a Java program. ## Spring REST API endpoint My next milestone is to set up a trivial API endpoint to familiarize myself with Spring MVC. I will use this framework to build an endpoint that will return "hello world". Eventually, this project will become an API for a plant simulation app. * I use spring initializr to automate the creation of the necessary boilerplate to run a minimally viable endpoint. * I create a controller class for the API: PlantController.java. * This class uses Spring's @RestController and @GetMapping annotations to define the controller and one endpoint. * For now, I have defined a GET endpoint at /helloworld, which returns the string "hello world". ```java package plantsim.PlantSimulatorAPI; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class PlantController { @GetMapping("/helloworld") public String helloworld() { return "hello world"; } } ``` It works. Now I can configure my data models and database. ## Database Database configuration will require a few steps. * Create in-memory database with h2 * Using the credentials defined below and in application.properties I am able to connect to the database testdb at /h2-console. ```java spring.datasource.url=jdbc:h2:mem:testdb spring.datasource.driver-class-name=org.h2.Driver spring.datasource.username=sa spring.datasource.password=password spring.h2.console.enabled=true ``` * In the h2 console, I can execute SQL queries and explore the database structure, etc. 1. Initialize database – populate with data * Since I have defined an entity class for the plant object, Hibernate will automatically create the plant database table for me. I will need to populate the table data, however. * I populate the tale with data using data.sql. By default, Spring Boot will look in src/main/resources for the script and execute it after the table has been initialized (according to application.properties -> spring.jpa.defer-datasource-initialization=true * I configure the script below to insert a couple of rows: ```sql -- Insert rows INSERT INTO plant (name) VALUES ('Ficus Audrey'); INSERT INTO plant (name) VALUES ('Lucky Bamboo'); INSERT INTO plant (name) VALUES ('Chinese Money Plant'); ``` 3. Configure API endpoint to return plant objects * To return a plant object instead of a string, I will need to configure following: * Plant entity that matches database schema – This will use object-relational mapping (ORM) to map my Java entities to my database table plant ```java package plantsim.PlantSimulatorAPI; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; @Entity public class Plant { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; public Plant() { } public Plant(Long id, String name) { this.id = id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } } ``` * Add JPA dependency to pom.xml – JPersistence API ``` jakarta.persistence jakarta.persistence-api 3.1.0 ``` * Create a JPA repository to fetch the Plant objects from testdb. ```java package plantsim.PlantSimulatorAPI; import org.springframework.data.jpa.repository.JpaRepository; public interface PlantRepository extends JpaRepository { } ``` * Update the controller to return the Plant object. ```java @Autowired private PlantRepository plantRepository; @GetMapping("/plant") public List getPlants() { return plantRepository.findAll(); } ``` ## Results If I navigate to /plant, the program returns a JSON-formatted string of the all of the plants stored in the database. I will use this as a foundation to later build into the project actual functionality. ```json [ { "name": "Ficus Audrey" }, { "name": "Lucky Bamboo" }, { "name": "Chinese Money Plant" } ] ```