How to Create REST APIs with Java and Spring Boot

November 30, 2021
Written by
Nida Khan
Contributor
Opinions expressed by Twilio contributors are their own
Reviewed by
Diane Phan
Twilion

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:

         

spring initializr

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:

eclipse project 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 like Service,  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.

new package details

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.

add new connection

A Setup New Connection pop-up opens. Enter "spring-boot-test" as the connection name. In Default Schema, enter "employee-schema".

set up new connection

Click on OK. A new MySQL connection is created on the home page.

mysql workbench

To open the connection, click on spring-boot-test on the home page. Under employee-schema, right click on Tables 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:

create table

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.

 

create new java class

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 property name 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. The name 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 the emp_id column as auto-increment in the database while creating the employee table. Now when you 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 the empRepository.save() function, which will return the Employee object after saving it to the database. The parameter passed to the createEmployee method is the Employee model containing all the details to save.
  • Similarly, getEmployees() and deleteEmployee() call the respective JpaRepository 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 the emp_id in the table is equal to the empId 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 the emp 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 updated emp 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": "example@gmail.com"
}

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": "newemail@gmail.com"
}

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 add RequestMethod.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...

 

maven build

An Edit Configuration pop-up will open. Type spring-boot:run in Goals.

spring boot run command

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.

add new environment variable

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:

spring boot build

 

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:

  1. Open the Postman app.
  2. Select Workspace dropdown and click on New workspace.

 

postman create workspace
  1. Enter the name of the workspace such as "Spring Boot REST API Workspace".
  2. 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..
  3. Click on the Create Workspace button on the bottom left hand corner.

new workspace configuration

To create a collection, click on Create new Collection icon in the left panel.

new collection postman

Click on the Edit icon beside the collection name and enter your “Employee collection”.

edit new 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.

view more actions
list of actions on collection

Give the request name as “Create Employee”. A new request is created as shown below:

new request created

Change the HTTP method to POST.

http method

In the Enter Request URL field, enter “https://localhost:8080/api/employees”.

enter api url

 

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.

body tab in postman

Enter the data below in the provided textbox:

{
    "firstName":"Nida",
    "lastName":"Khan",
    "emailId":"example1@gmail.com"
}

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": "example1@gmail.com"
}

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;

mysql table

 

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.

 

get employee

 

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": "example2@gmail.com"
}

edit employee

 

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.

 

delete employee

 

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:

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.