In this article, we will see How to create a REST API in Spring Boot. We will be using JPA Repository to store data in the database. In order to go ahead, let’s first understand what is REST API.
What is REST API?
REST stands for Representational State Transfer. It is an architectural style that defines a set of rules to create web services. In this architecture, data and functionality are resources. These resources are accessed by Uniform Resource Identifiers(URIs).
For example, the user is requesting the data of covid cases in India then we will create an object on the server-side. But, what happens here, is that we don’t send the object to the client instead we send the state of an object. That is why It is known as Representational State Transfer.
Methods of REST API
If you are a web application developer you must be well aware of the CRUD operations. Here, we have HTTP methods to create, read, update, and delete resources.
- GET: To read a resource.
- POST: To add a resource.
- PUT: To update a resource.
- DELETE: To delete a resource.
For example, to get a resource present on the web, we will just use the HTTP method GET. To create a resource, we will call the POST method and so on.
Let us build a Spring Boot Application implementing REST API.
Technologies & Tools Needed:
- Java
- Spring STS
- Spring Data JPA
- MYSQL DB
- POSTMAN – It will act as a client to test the API.
One of the features of Spring Boot is that it is used for creating REST API. Creating REST API is pretty easy here. Follow this steps
Step 1: Open IDE STS- Spring Tool Suite
Step 2: Go to File > Spring Starter Project.
Step 3: Now, Fill all the fields as shown below and click Next.
Step 4: Now, Add the dependencies as per your requirement, I have added Spring Web Dependency and Spring Data JPA click Next > Finish.
Note: Here, also add the Lombok dependencies
Here, we will follow the Spring Boot architecture as shown in the following diagram
Once the project is created, see the maven file required for this project. Make sure these dependencies are added in the pom.xml file.
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
- spring-boot-starter-data-jpa: It will download the files required for spring data JPA.
- spring-boot-starter-web: It is used to create web-based applications.
- mysql-connector-java: It is used to connect with MySQL database.
- Lombok: To give support for lombok libarray.
Configure application. properties file
This is the file provided by spring boot to configure JDBC URL, username, password, and driver class name. Also, configure JPA-related information.
spring.jpa.hibernate.ddl-auto=update spring.datasource.url=jdbc:mysql://localhost:3306/db_demo spring.datasource.username=root spring.datasource.password=root spring.datasource.driver-class-name =com.mysql.jdbc.Driver spring.jpa.show-sql= true ## Hibernate Properties # The SQL dialect makes Hibernate generate better SQL for the chosen database spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect #To format SQL queries generated by Hibernate spring.jpa.properties.hibernate.format_sql=true #change the port server.port=8888
- spring.jpa.hibernate.ddl-auto is set to update so that whatever changes we will do will be reflected in the schema.
- spring.datasource.url is used to set the URL of the MYSQL DB.
- spring.datasource.username is used to set the username and spring. datasource. password is used to set the password.
- spring.datasource.driver-class-name is used to set the driver class name.
- spring.jpa.show-sql is set to true to show SQL generated by the Hibernate.
- spring.jpa.properties.hibernate.dialect is used to generate better SQL for the chosen database.
- spring.jpa.properties.hibernate.format_sql is set to true to format SQL queries.
- server.port is set to 8888.
Create an Entity Class
Here, we will create an Entity that would be mapped to the database tables. It is nothing but the Java POJO class.
Account.java
package com.abc.example.rest.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; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.Setter; @Setter @Getter @AllArgsConstructor @RequiredArgsConstructor @Table(name = "account") @Entity public class Account { @Id @GeneratedValue private long id; private String accountHolderName; private double balance; }
- @Entity annotation mark this class as a JPA entity. It tells hibernate to make a table out of it.
- @Id annotation specifies the primary key of an entity.
- @GeneratedValue is applied to the primary key.
- @Column annotation the property of the class with the table column.
- @Setter is applied on the class level to generate setter.
- @Getter is applied on the class level to generate getter.
- In the same way, @AllArgsConstructor & @RequiredArgsConstructor generate constructor.
Create Repository Interface
The repository here is the DAO layer, which performs all the database operations. AccountRepository interface is created which will extends JPARepository<ClassName, ID>
package com.abc.example.rest.repository; import org.springframework.data.jpa.repository.JpaRepository; import com.abc.example.rest.model.Account; public interface AccountRepositoryInt extends JpaRepository<Account, Long>{ }
Create a Service Layer
This layer is responsible to handle business logic. Here, we will create the AccountServiceInt and its Implementation class AccountServiceImpl.
AccountServiceInt
package com.abc.example.rest.service; import java.util.List; import java.util.Optional; import com.abc.example.rest.model.Account; public interface AccountServiceInt { public List<Account> getAccounts(); public Optional<Account> getAccount(long accId); public Account addAccount(Account acc); public Account updateAccount(Account acc); public void deleteAccount(long accId); }
AccountServiceImpl
package com.abc.example.rest.service; import java.util.List; import java.util.Optional; import javax.transaction.Transactional; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.abc.example.rest.model.Account; import com.abc.example.rest.repository.AccountRepositoryInt; @Service public class AccountServiceImpl implements AccountServiceInt { @Autowired private AccountRepositoryInt dao; @Override public List<Account> getAccounts() { // TODO Auto-generated method stub return (List<Account>) dao.findAll(); } @Override public Optional<Account> getAccount(long accId) { // TODO Auto-generated method stub return dao.findById(accId); } @Override public Account addAccount(Account acc) { // TODO Auto-generated method stub return dao.save(acc); } @Override @Transactional public Account updateAccount(Account acc) { // TODO Auto-generated method stub System.out.println(""); dao.saveAndFlush(acc); return acc; } @Override public void deleteAccount(long accId) { // TODO Auto-generated method stub System.out.println("hello "+accId); Account a =dao.getById(accId); System.out.println(a.getAccountHolderName()); dao.delete(a); } }
- @Service is applied on the class level to indicate that this particular class is holding business logic.
Create a Controller
The client request first will go to the controller which will map the request based on the URI.
package com.abc.example.rest.controller; import java.util.List; import java.util.Optional; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import com.abc.example.rest.model.Account; import com.abc.example.rest.repository.AccountRepositoryInt; import com.abc.example.rest.service.AccountServiceInt; @RestController public class AccountController { @Autowired private AccountServiceInt service; //1. Get all Account Info @GetMapping("/accounts") public List<Account> getAllAccountInfo(){ return service.getAccounts(); } //2. Create an Account @PostMapping("/accounts") public Account createAccount(@RequestBody Account acc) { return service.addAccount(acc); } //3. Get Account By Id @GetMapping("/accounts/{accountId}") public Optional<Account> getAccountById(@PathVariable(value = "accountId") String id) { return service.getAccount(Long.parseLong(id)); } //4. Update an Account @PutMapping("/accounts") public Account updateAccount(@RequestBody Account account) { System.out.println("id"+account.getId()+"name"+account.getAccountHolderName()+"***"+account.getBalance()); return this.service.updateAccount(account); } //5. Delete an Account @DeleteMapping("/accounts/{accountId}") public ResponseEntity<HttpStatus> deleteAccount(@PathVariable (value = "accountId") long accountId) { System.out.println("delte"); try { this.service.deleteAccount(accountId); return new ResponseEntity<>(HttpStatus.OK); } catch (Exception e) { // TODO: handle exception return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); } } }
- Mark this class as @RestController(It is used to simplify the creation of REST APIs).
- The @GETMapping is used to map HTTP GET requests on specific handler methods.
- The @POSTMapping is used to map HTTP POST requests on specific handler methods.
- The @PUTMapping is used to map HTTP PUT requests on specific handler methods.
- The @DELETEMapping is used to map HTTP DELETE requests on specific handler methods.
Run the Application
Now, open the SpringrestexampleApplication.java and click on Run as Spring Boot App.
Now, we will use the POSTMAN Application to test the APIs. Make sure you have POSTMAN installed on your machine.
In this way, we create REST API using Spring Boot.