How to Create REST APIs with Java and Spring Boot
Posted by Khan Nida on 14 Jan, 2022 • 24 min
Learn how to build and test REST APIs using Java, Spring Boot, and Postman with a sample database on MySQL
Table of Contents
I’ve been using Twilio’s REST APIs for quite some time now. I was always amazed to see how REST APIs are used in establishing communication between client and server over HTTP. You call an API, which calls the server. The server then performs the whole business logic and returns the result.
I always wanted to know how these APIs are developed so that I can create APIs myself. This led me to explore various frameworks such as Spring Boot. After developing several REST APIs using Spring Boot, I decided to write this tutorial to help beginners get started with Spring Boot.
In this tutorial, you will develop REST APIs in Spring Boot to perform CRUD operations on an employee database.
Prerequisites
- Some prior knowledge of Java or a willingness to learn.
- Java Development Kit (JDK) version 8 or newer.
- Maven 3.3 or newer.
- MySQL is the database service you’ll use to store the employee data and access in your application through REST APIs. You can follow the guide for detailed steps to setup MySQL with Workbench.
- Eclipse IDE for code development. When running the installer, it will ask for the specific package to install, choose “Eclipse IDE for Java EE Developers”. Make sure to configure Maven in Eclipse IDE.
- Postman desktop application to test the APIs. During installation, create a free account when prompted.
Advantages of using Spring Boot
Spring Boot is a Java framework, built on top of the Spring, used for developing web applications. It allows you to create REST APIs with minimal configurations. A few benefits of using Spring Boot for your REST APIs include:
- No requirement for complex XML configurations.
- Embedded Tomcat server to run Spring Boot applications.
- An auto-configuration feature by Spring Boot that configures your application automatically for certain dependencies. If the dependency is available in your classpath, Spring Boot will auto-create the beans for it. Beans in Spring are objects that are instantiated and managed by Spring through Spring IoC containers. You don't have to create and configure the beans as Spring Boot will do it for you.
Overall, Spring Boot makes a great choice for devs to build their applications because it provides boilerplate code with all the necessary configurations to start with the coding right away.
Create and import Spring Boot project
To create the Spring Boot application, you’ll use a tool called Spring Intializr. This tool provides the basic structure of a Spring Boot project for you to get started quickly.
Go to the Spring Initializr site. Under Project, choose “Maven” and then “Java” as the language. Note that this tutorial is built with Spring Boot version 2.5.6, so select the same version in Spring Initializr.
Include the following identifiers under Project Metadata for your project:
- Group - this is the base package name indicating the organization or group that is creating the project. This follows the Java package naming convention. You can keep it as a default value.
- Artifact - this is the name of your project. Since you are creating an application for accessing and manipulating employee details, you can provide “employee”.
- Name - this is the display name for your application which Spring Boot will use when creating the entry point for the project. You can keep it the same as the artifact name, "employee".
- Description - provide a description about the project.
Choose “Jar” as the Packaging type as the application will run in the embedded Tomcat server provided by Spring Boot.
This tutorial is written in Java 8. Hence, you can choose the same Java version to follow along.
Add the following Dependencies to the project:
- Spring Web: required for building RESTful web applications.
- Spring Data JPA: required to access the data from the database. JPA (Java Persistence API) is a Java Specification that maps Java objects to database entities, also known as ORM (Object Relational Mapping). The Spring Data JPA is an abstraction over JPA that provides utility methods for various operations on databases such as creating, deleting, and updating a record. It eliminates the need of writing queries as you do with JDBC.
- MySQL Driver: required to connect with MySQL database.
Your Spring Boot application should look similar to the image below:
Click the Generate button at the bottom of the screen. This will download a zip file containing your project boilerplate. Extract the zip file to your preferred folder location.
Open Eclipse IDE and go to File and select Import. Under Maven, choose Existing Maven Projects. Click on Next.
Browse the directory where you extracted the zip file, select the root folder where the pom.xml file is present. Click on Finish to import your project into your Eclipse IDE.
Explore the file structure
You’ll see the following folders in file explorer:
- The src/main/java/com/example/employee subdirectory consists of all the Java classes for the tutorial.
- The application.properties file under the resource folder contains the properties your Spring Boot will use to configure the application. You’ll add database configuration details such as database URL, username, and password to this file later in the tutorial.
- pom.xml contains all the dependencies that you added while creating the Spring Boot project in Spring Initializr.
Notice that there is a file named EmployeeApplication.java. This is the entry point that will launch the Spring Boot application.
The @SpringBootApplication
includes the features of the below Spring Boot annotations:
@EnableAutoConfiguration
- this will enable the auto-configuration feature of Spring Boot discussed earlier.@Configuration
- it specifies a configuration class, where you’ll provide all the bean definitions that your application is using. Spring Boot will use the bean definitions provided in the configuration class to instantiate them at runtime.@ComponentScan
- allows Spring Boot to scan the package for components likeService
,Controller
,Repository
, etc. and register beans for each of those classes.
Add sub-packages to the project
Let's understand the main layers that a Spring Boot application consists of. You’ll create sub-packages for each of these layers in the project:
- DAO - The DAO (data access layer) provides an interface to connect with the database and access the data stored in the database. A single DAO class can deal with queries retrieving different types of entities.
- Repository - This layer is similar to the DAO layer which connects to the database and accesses the data. However the repository layer provides a greater abstraction compared to the DAO layer. Every class is responsible for accessing and manipulating one entity. This tutorial will use the repository layer.
- Service - This layer calls the DAO layer to get the data and perform business logic on it. The business logic in the service layer could be - performing calculations on the data received, filtering data based on some logic, etc.
- Model - The model contains all the Java objects that will be mapped to the database table using. The DAO will fetch the data from the database and populate the respective model with that data and return it to the service layer and vice versa.
- Controller - This is the topmost layer, called when a request comes for a particular REST API. The controller will process the REST API request, calls one or more services and returns an HTTP response to the client.
To create individual folders for the above components, in Eclipse,right-click on the com.example.employee package and Select New then Package as seen below:
A new pop-up will open, in the Name field, enter “com.example.employee.repository” and click Finish.
This will create the folder for repository components. Repeat the steps above for the following packages:
- com.example.employee.controller
- com.example.employee.model
- com.example.employee.service
Before writing code for the application in each of these sub-packages, let's create the table and configure the MySQL connection details in Spring Boot that you’ll use in this tutorial.
Create table and configure MySQL details in Spring Boot
Open MySQL workbench. In the home page, click on the [+] icon besides MySQL Connections.
A Setup New Connection pop-up opens. Enter "spring-boot-test" as the connection name. In Default Schema, enter "employee-schema".
Click on OK. A new MySQL connection is created on the home page.
To open the connection, click on spring-boot-test on the home page. Under employee-schema, right click on Table and select Create Table.
Add four columns - emp_id, first_name, last_name, email_id. For emp_id, select the Primary Key, Not Null and Auto Increment checkbox. Your table should look similar to the image below:
Click on Apply then Finish.
To connect this MySQL instance in your application, you’ll have to provide the database details to Spring Boot. Open the application.properties file and add the below content:
spring.datasource.url = jdbc:mysql://127.0.0.1:3306/employee-schema
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
3306
is the port number where the MySQL instance is running. Change it to the port number where your instance is running.MySQL5InnoDBDialect
is a dialect used to inform Spring Boot of the database being used. Based on this, Spring Boot will generate SQL queries for that particular database.
With this information, Spring Boot will auto-configure the database connection for you.
Now that the table is ready, let's move to adding the code for various layers of the application.
Create the model class
Go back to the Eclipse IDE and right click on com.example.employee.model package for the option to create a new class.
A new pop-up with Class details will appear. In the Name field enter “Employee”. Click Finish.
Add the contents to the file:
package com.example.employee.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "employee")
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="emp_id")
private Long id;
@Column(name="first_name")
private String firstName;
@Column(name="last_name")
private String lastName;
@Column(name="email_id")
private String emailId;
}
Let's break down the code in the file:
@Entity
annotation specifies that this Java class is mapped to the database table.@Table
with the help of the propertyname
specifies which particular table this class is mapped to.@Column
on each Java instance variable allows defining a set of properties like name, length etc. Thename
property will be the name of the field in the database table that this instance variable will map to.@Id
on a field tells Spring Boot that this particular field is the primary key in the table@GeneratedValue
specifies the strategy that will be used for generating primary keys.
There are four primary key generation strategies as described below:
GenerationType.AUTO
- This is the default strategy used by Spring Boot. If you use this strategy, the JPA provider will decide on an appropriate strategy to generate the primary key depending on the dialect given in the application.properties file.GenerationType.IDENTITY
- this strategy uses the database identity column to determine the primary key strategy. For example, you defined theemp_id
column as auto-increment in the database while creating the employee table. Now when u use this strategy then a unique primary key is generated by starting from 1 and incrementing every time a new row is inserted in the table.GenerationType.SEQUENCE
- this strategy uses database sequence to generate the primary keys.GenerationType.TABLE
- this strategy uses a database table to generate primary keys.
Also, you’ll create setters and getters for the above instance variable. To auto-generate them in Eclipse, right click the Employee.java file and select Source. Choose Generate Getters and Setters. Click on Select All then the Generate button.
In the next section, you’ll create the repository class that will use this model class to access employee details from the database.
Create the repository class
Create a class named EmployeeRepository under the com.example.employee.repository package and replace the code with the following contents:
package com.example.employee.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.example.employee.model.Employee;
@Repository
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
}
The @Repository
on the class indicates that the class is a data repository that will contain CRUD operations. CRUD is an acronym that stands for the four basic operations of the database - Create, Read, Update, Delete.
The EmployeeRepository
extends JpaRepository
. You have two parameters passed to the JpaRepository
- first parameter is the model class that will be managed by this repository, second is the data type of the primary key.
The JpaRepository
interface provided by Spring Data JPA makes it possible for the repository class to retrieve, update, delete records in the employee table.
This interface also defines methods such as save()
, findAll()
, delete()
, to operate on the database. The implementation of these methods is provided by the default implementation class called SimpleJpaRepository
. You have to make a call to these methods thus saving you from writing queries for these operations.
In the next section you’ll create the service class that will call the JpaRepository
implementation methods.
Create the service class
The service component contains business logic. Create a class named EmployeeService under the com.example.employee.service package and replace the code with the contents below:
package com.example.employee.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.example.employee.model.Employee;
import com.example.employee.repository.EmployeeRepository;
import java.util.List;
@Service
public class EmployeeService {
@Autowired
EmployeeRepository empRepository;
}
In Spring, you use @Autowired
annotation for instantiating a class object.
The @Repository
annotation from the EmployeeRepository
class enabled the creation of a bean of this class through the @ComponentScan
feature of Spring. This bean is then used in the service class using @Autowired
annotation. This is called Dependency Injection in Spring.
You’ll now create methods in the service layer. Each of these methods will call JpaRepository
methods extended by EmployeeRepository
.
Add these methods to the EmployeeService
class after EmployeeRepository empRepository
:
// CREATE
public Employee createEmployee(Employee emp) {
return empRepository.save(emp);
}
// READ
public List<Employee> getEmployees() {
return empRepository.findAll();
}
// DELETE
public void deleteEmployee(Long empId) {
empRepository.deleteById(empId);
}
- The
createEmployee
method calls theempRepository.save()
function, which will return theEmployee
object after saving it to the database. The parameter passed to thecreateEmployee
method is theEmployee
model containing all the details to save. - Similarly,
getEmployees()
anddeleteEmployee()
call the respectiveJpaRepository
methods extended by EmployeeRepository. - The
findAll()
function returns the list of all employee details in the database. - The
deleteById(empId)
function will delete an employee record where theemp_id
in the table is equal to theempId
passed.
To updating employee details, add the following function after the deleteEmployee(Long empId)
method:
// UPDATE
public Employee updateEmployee(Long empId, Employee employeeDetails) {
Employee emp = empRepository.findById(empId).get();
emp.setFirstName(employeeDetails.getFirstName());
emp.setLastName(employeeDetails.getLastName());
emp.setEmailId(employeeDetails.getEmailId());
return empRepository.save(emp);
}
Let's breakdown the method above:
- The
updateEmployee
method accepts two parameters - an employee ID (primary key) and the employee object containing the new employee details. - To update an existing employee, you’ll first retrieve the employee object where employee ID in the database equals
empId
and store it in theemp
variable. - After getting the old employee object, you’ll use the setters defined in Employee.java to update the fields with new values stored in
employeeDetails
. - Lastly, the
empRespository.save(emp)
function will save the updatedemp
object to the database.
Create the controller class
Create a class named EmployeeController under the com.example.employee.controller package and replace the code with the contents below:
package com.example.employee.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.example.employee.model.Employee;
import com.example.employee.service.EmployeeService;
@RestController
@RequestMapping("/api")
public class EmployeeController {
@Autowired
EmployeeService empService;
}
@RequestMapping
annotation on the class defines a base URL for all the REST APIs created in this controller. This base URL is followed by individual REST endpoints given to each of the controller methods.@RestController
on the class is a combination of:@Controller
- tells Spring Boot that this class is a controller.@ResponseBody
- indicates that the return value of the methods inside the controller will be returned as the response body for the REST API.
EmployeeService
is injected as a dependency using@Autowired
annotation.
Create methods to perform CRUD operations
Before proceeding with the implementation of REST API requests in the controller, let’s discuss the structure of these REST APIs:
To create an employee, a POST method is created with the endpoint api/employees
. The request body consists of the data sent from the client to your API. In this case, the data is the new employee details to save in the database. It will be a JSON similar to the content below:
{
"firstName": "Joe",
"lastName": "B",
"emailId": "[email protected]"
}
To get employee details, a GET method is created with the endpoint api/employees
.
To update employee details, a PUT HTTP method is created with the endpoint api/employees/{empId}
where the {empId}
is a path parameter containing the employee ID, sent to the API. The request body consists of the new employee details to update in the database formatted as seen below:
{
"firstName": "Joe",
"lastName": "B",
"emailId": "[email protected]"
}
To delete an employee, a DELETE HTTP method is created with the endpoint /emp/{empId}
where {empId} - is the employee ID whose data has to be deleted.
Let’s create the methods for these four REST APIs. Add the below method to the EmployeeController class after EmployeeService empService
:
@RequestMapping(value="/employees", method=RequestMethod.POST)
public Employee createEmployee(@RequestBody Employee emp) {
return empService.createEmployee(emp);
}
Let's breakdown the newly added code:
value
- is the endpoint. In your case, it’s /employees. Note that the endpoint given in the value field is only “/employees” and not “/API/employees”. Since “/api” is common for all the endpoints, this was added as the base URL in the@RequestMapping
annotation on the class.method
- this is the HTTP method type represented by an enum. For the create employee endpoint, the HTTP method is POST. Hence, you’ll addRequestMethod.POST
as its value.@RequestBody
annotation is used to map the request body of the endpoint to the method parameter.emp
will contain the request JSON passed to this endpoint.
Similarly, you’ll add code for all the other REST APIs. Add these methods to EmployeeController class after the createEmployee
method:
@RequestMapping(value="/employees", method=RequestMethod.GET)
public List<Employee> readEmployees() {
return empService.getEmployees();
}
@RequestMapping(value="/employees/{empId}", method=RequestMethod.PUT)
public Employee readEmployees(@PathVariable(value = "empId") Long id, @RequestBody Employee empDetails) {
return empService.updateEmployee(id, empDetails);
}
@RequestMapping(value="/employees/{empId}", method=RequestMethod.DELETE)
public void deleteEmployees(@PathVariable(value = "empId") Long id) {
empService.deleteEmployee(id);
}
Notice that some methods include @PathVariable
, meaning that the API endpoint has a path parameter involved. The @PathVariable
will map the path variable provided in the value
parameter of the endpoint to the Java method field.
Build the application
Before you build, here is the completed project in a GitHub repository for your reference.
Right click on the employee folder in the Project Explorer on Eclipse and select Run As then choose 4 Maven build...
An Edit Configuration pop-up will open. Type spring-boot:run in Goals.
Go to the Environment tab and click on Add. A New Environment Variable pop-up will open.
In the Name field, enter "spring.datasource.username". For Value, enter your MySQL username. Click OK.
Similarly, add a new environment variable with "spring.datasource.password" in Name and your MySQL password in Value. Click on Apply then Run.
The application will now start building. A successful build will display the following on the console:
If you see the last few lines in the console, it will state that the application has started running on the default port 8080. If this port is unavailable, Spring Boot will find a different available port.
You'll receive a Whitelabel Error Page in the browser for https://localhost:8080.
In the next section, you’ll learn how to test the four CRUD APIs.
Test the APIs
Postman is an application that helps in developing, testing, and documenting APIs. Create a free account if you have not done so already.
You’ll create a workspace in Postman which can be used to collaborate with teammates on projects. Each workspace can have one or more collections containing folders with a set of APIs defined.
To create a workspace in Postman, follow the below steps:
- Open the Postman app.
- Select Workspace dropdown and click on New workspace
- Enter the name of the workspace such as "Spring Boot REST API Workspace".
- The Visibility section lets you choose whether you want to make the workspace visible to your teammates or yourself. You can choose either option for this article..
- Click on the Create Workspace button on the bottom left hand corner.
To create a collection, click on Create new Collection icon in the left panel.
Click on the Edit icon beside the collection name and enter your “Employee collection”.
Next, you’ll create and test requests in your collection for each of the four REST APIs created in your Spring Boot application.
Create and test a request in Postman
In the left panel, click on View more actions for the collection you created, select Add request.
Give the request name as “Create Employee”. A new request is created as shown below:
Change the HTTP method to POST.
In the Enter Request URL field, enter “https://localhost:8080/api/employees”.
The endpoint /api/employees, is preceded by the server and port where the application is running. If your application is running in a different port, replace the 8080
in the URL.
To send request body to this request URL endpoint, navigate to the Body tab, choose the raw checkbox with JSON as the request body format.
Enter the data below in the provided textbox:
{
"firstName": "Nida",
"lastName": "Khan",
"emailId": "[email protected]"
}
These are the employee details that will be added to the database. Click on Save then Send. Below is the response you get in Postman:
{
"id": 1,
"firstName": "Nida",
"lastName": "Khan",
"emailId": "[[email protected]](mailto:[email protected])"
}
Notice the 200 OK
response status and that the response body is a JSON containing the employee record details that were saved in the database.
Go to MySQL Workbench and verify that a new row gets created with the above employee details with emp_id=1
by executing the query:
SELECT * FROM employee;
Similarly, you’ll create and run requests to GET, DELETE, and UPDATE employees.
To GET
employees, enter “http://localhost:8080/api/employees/” in the Enter Request URL field. Leave the Body empty and click Send.
To UPDATE
the employee with a specific ID, create a PUT
request. Enter “http://localhost:8080/api/employees/1” in the Enter Request URL field. Enter the following details in the raw JSON body and click Send:
{
"firstName": "Nida",
"lastName": "K",
"emailId": "[email protected]"
}
To DELETE
an employee record, create a DELETE
request. Enter “http://localhost:8080/api/employees/1” in the Enter Request URL field. Leave the Body empty and click Send.
What's next for Java Spring Boot projects?
In this tutorial, you learned how to build REST APIs with Spring Boot and how to test the APIs in Postman.
Challenge yourself next by checking out these articles and implementing Twilio APIs in your Spring Boot application:
- Send SMS in Your Spring Boot App
- Creating an SMS dashboard in Java with Spring Boot
- Transcribing Phone Calls using Twilio Media Streams with Java, WebSockets and Spring Boot
Nida is a full stack developer. She is a hands-on learner, hence prefers learning new technologies through development. In her free time, she explores new technologies, reads tech blogs and solves problems on Data Structures and Algorithms. Follow her on GitHub or LinkedIn.
Tags
- spring boot
- rest api
- java
- postman