SEARCH BY

All

  • All
  • Java8
  • Spring

Rest API development with spring boot application

Post a Comment


Here we are going to develop spring boot based REST API application. In this application we are going to use @RestController, Spring Boot JPA, MYSQL as database server.

DataBase Tables

CREATE TABLE `person` (
 `pid` INT(11) NOT NULL AUTO_INCREMENT,
 `pname` VARCHAR(200) NOT NULL DEFAULT '0',
 `pgender` SMALLINT(1) NOT NULL DEFAULT '0',
 `pdob` DATE NOT NULL,
 PRIMARY KEY (`pid`)
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
;


CREATE TABLE `relation_string` (
 `rsid` INT(11) NOT NULL AUTO_INCREMENT,
 `rslabel` VARCHAR(100) NOT NULL DEFAULT '0',
 PRIMARY KEY (`rsid`)
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
;

CREATE TABLE `realtions` (
 `realtionid` INT(11) NOT NULL AUTO_INCREMENT,
 `rsid` INT(11) NULL DEFAULT '0',
 `pid` INT(11) NULL DEFAULT '0',
 PRIMARY KEY (`realtionid`),
 INDEX `FK__relation_string` (`rsid`),
 INDEX `FK__person` (`pid`),
 CONSTRAINT `FK__person` FOREIGN KEY (`pid`) REFERENCES `person` (`pid`) ON UPDATE CASCADE ON DELETE CASCADE,
 CONSTRAINT `FK__relation_string` FOREIGN KEY (`rsid`) REFERENCES `relation_string` (`rsid`) ON UPDATE CASCADE ON DELETE CASCADE
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
;



After creating database schema with the above details , where data base details are

Database name: jai43
Database username: jai43user
Database user password: 123456

Database connection configurations

you can choose your own database name and userdetails, then update details in application.properties file of application

# Database connection details
spring.datasource.url=jdbc:mysql://localhost:3306/jai43?useSSL=false&serverTimezone=UTC&useLegacyDatetimeCode=false
spring.datasource.username=jai43user
spring.datasource.password=123456

You have to include above database configurations in application.properties file which is located at resources folder of application

Dependencies

Then we have to add the following dependencies to pom.xml file

   org.springframework.boot
   spring-boot-starter-web
  

  
  
   org.springframework.boot
   spring-boot-starter-data-jpa
  
  
  
   org.springframework.boot
   spring-boot-devtools
   runtime
  
  
  
   mysql
   mysql-connector-java
   runtime
  


you can see there we have added spring boot starters for web, JPA and devtools( for auto refresh of changes ) and mysql connector

Project directory structure

Project directory structure

In the above you can see number of packages created for clear separation of classes which are controllers, DAO, Business classes, entities and DTO classes.

Enabling Hibernate as JPA implementation

We are using Hibernate as JPA implementation to develop this application, so that we have to add spring jpa properties hibernate dailect property in application.properties file, to enable hibernate implementation for JPA in our application we have to add the following property in application.properties file

# the following property is to enable hibernate as a JPA implementation
# here we have used mysql_dialect for hinernate dialect to perform SQL operations effectively on our MYSQL database
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect


Project Architecture


Here we have use DAO pattern for implementing this application/example. Following image shows flow of actions in this application which include controller, service, DAO and DTO/Model.
Flow of actions

To demonstrate a simple CRUD application we are going to work with only Person database table ( with in this tutorial) .

As our first task we need to create an Entity class for database table person. Here Entity will map with database table ( this is called as Object mapping with database table  which will be happen in ORM technologies like hibernate )

Create Person Entity class


@Entity is a class level annotation to convert normal class into an entity class.
@Table is a class level annotation to specify table properties to map with class name, if table is equal to class name then @Table annotation is optional, but if table name is different than entity  class name then we must specify name property of @Table annotation , in this example database table name is person and Entity class name is Person, so there is no big use with @Table annotation at this movement.

package com.jai43.jsite.entities;

import java.io.Serializable;
import java.sql.Date;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.validation.constraints.NotBlank;

@Entity
@Table(name = "person")
public class Person implements Serializable   {

 @Id
 @GeneratedValue(strategy = GenerationType.IDENTITY)
 private Long pid;
 
 @NotBlank(message = "Person name must not be empty")
 private String pname;
 
 
 private int pgender;
 
 
 private Date pdob;


 public Long getPid() {
  return pid;
 }


 public void setPid(Long pid) {
  this.pid = pid;
 }


 public String getPname() {
  return pname;
 }


 public void setPname(String pname) {
  this.pname = pname;
 }


 public int getPgender() {
  return pgender;
 }


 public void setPgender(int pgender) {
  this.pgender = pgender;
 }


 public Date getPdob() {
  return pdob;
 }


 public void setPdob(Date pdob) {
  this.pdob = pdob;
 }


 @Override
 public int hashCode() {
  final int prime = 31;
  int result = 1;
  result = prime * result + ((pdob == null) ? 0 : pdob.hashCode());
  result = prime * result + pgender;
  result = prime * result + ((pid == null) ? 0 : pid.hashCode());
  result = prime * result + ((pname == null) ? 0 : pname.hashCode());
  return result;
 }


 @Override
 public boolean equals(Object obj) {
  if (this == obj)
   return true;
  if (obj == null)
   return false;
  if (getClass() != obj.getClass())
   return false;
  Person other = (Person) obj;
  if (pdob == null) {
   if (other.pdob != null)
    return false;
  } else if (!pdob.equals(other.pdob))
   return false;
  if (pgender != other.pgender)
   return false;
  if (pid == null) {
   if (other.pid != null)
    return false;
  } else if (!pid.equals(other.pid))
   return false;
  if (pname == null) {
   if (other.pname != null)
    return false;
  } else if (!pname.equals(other.pname))
   return false;
  return true;
 }
 
 
}

Creating Repository: Person Repository class


Here we have used JpaRepository class to create PersonRepository.java class , this has inbuilt methods to perform database operations like findByID(),save(),delete() etc...

/**
 * 
 */
package com.jai43.jsite.repositories;

import java.util.List;
import java.util.Optional;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import com.jai43.jsite.entities.Person;

/**
 * @author Admin
 *
 */
@Repository
public interface PersonRepository extends JpaRepository<Person, Long> {


}

In the line 19 we have mentioned Person and Long as a generic parameters, so that this repository can perform database operations on table person and its primary key type is long( this mapping done with Person.java entity class ).

@Repository annotation used to created repository class.

DAO classes


In this section we are going to discuss about DAO implementaion. We have created DAO interface and then we are creating DAO interface implementation class.



@Component is here used as a class level annotation , this annotation tells to the spring container that the class annotated with @Component is a bean which will be initiated during bootstrap of spring container.

package com.jai43.jsite.dao;

import java.util.List;

import org.springframework.stereotype.Component;

@Component
public interface PersonsDAO<Person> {

 List<Person> getAllPersons();

 Person getPersonByID(long id) throws Exception;

 Person addNewPerson(Person p);

 void deletePersonByID(long id);

 Person updatePerson(Person person);
}

The above interface ( PersonsDAO.java ) is going to be implemented in the following class

package com.jai43.jsite.dao.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.jai43.jsite.dao.PersonsDAO;
import com.jai43.jsite.entities.Person;
import com.jai43.jsite.repositories.PersonRepository;

@Component
public class PersonsDAOImpl implements PersonsDAO<Person> {
 @Autowired
 PersonRepository personRepository;

 @Override
 public List<Person> getAllPersons() {
  // TODO Auto-generated method stub

  return personRepository.findAll();
 }

 @Override
 public Person getPersonByID(long id) throws Exception {
  // TODO Auto-generated method stub
  return personRepository.findById(id).orElseThrow(() -> new Exception("Couldn't find a person with id: " + id));
 }

 @Override
 public Person addNewPerson(Person p) {
  // TODO Auto-generated method stub
  return personRepository.save(p);
 }

 @Override
 public void deletePersonByID(long id) {
  // TODO Auto-generated method stub
  personRepository.deleteById(id);
 }

 @Override
 public Person updatePerson(Person person) {
  // TODO Auto-generated method stub
  return personRepository.save(person);

 }
}

The above implementation class autowired a repository class.

Service Layer


In this section we are going to create service layer of our application, where business logic will be produced to REST endpoints.

@Service annotation lets the spring container to turn normal class into service class.

package com.jai43.jsite.services;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.jai43.jsite.dao.PersonsDAO;
import com.jai43.jsite.dao.impl.PersonsDAOImpl;

@Service
public class PersonService<Person> {

 @Autowired
 PersonsDAO<Person> personsDAO;

 public List<Person> getAllPersons() {

  return personsDAO.getAllPersons();
 }

 public Person getPersonById(long id) throws Exception {

  return personsDAO.getPersonByID(id);
 }

 public Person addNewPerson(Person p) {

  return personsDAO.addNewPerson(p);
 }

 public void deletePersonByID(long id) {

  personsDAO.deletePersonByID(id);
 }

 public Person updatePerson(Person person) {
  return personsDAO.updatePerson(person);
 }
}

Controller for Person CRUD operations



Finally this is the time to create REST entdpoints in a rest controller. This application is an API so our controller must be annotated with @RestController.

package com.jai43.jsite.controller;

import java.util.List;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
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.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.jai43.jsite.entities.Person;
import com.jai43.jsite.services.PersonService;

@RestController
@RequestMapping("/person")
public class PersonController {

 @Autowired
 PersonService<Person> personService;

 @GetMapping("/all")
 public List<Person> getAllPersons() {
  return personService.getAllPersons();
 }

 @GetMapping("/p/{pid}")
 Person getPErsonByID(@PathVariable(name = "pid") long id) throws Exception {
  return personService.getPersonById(id);
 }

 @GetMapping("/w")
 public String welcome() {
  return "Iam jai";
 }

 @PostMapping("/addNewPerson")
 Person addNewPerson(@Valid @RequestBody Person p) {
  return personService.addNewPerson(p);
 }

 @DeleteMapping("/deletePerson/{id}")
 ResponseEntity<Person> deletePersonById(@PathVariable(name = "id") long pid) throws Exception {
  Person person = personService.getPersonById(pid);
  HttpHeaders headers = new HttpHeaders();
  headers.add("Responded", "PersonController");
  personService.deletePersonByID(pid);
  return ResponseEntity.ok().headers(headers).body(person);
 }

 @PutMapping("/update")
 Person updatePerson(@Valid @RequestBody Person p) {
  return personService.updatePerson(p);
 }

}

Output screens

Following are screen shots of output


view all persons






If we want to get gender as Male or Female as a JSON result for rest endpoints, it is not possible in this example...

You can find an article by clicking on the following link to know how to use modelmapping to customise rest endpoint results

https://code123.info/2020/04/modelmappingspringboot.html

jaya
I love software designing, coding, writing and teaching...

Share this article

Related Posts

Post a Comment

Place your code in <em> </em> tags to send in comments | Do not add hyper links in commnet

Close

Subscribe our newsletter for the latest articles directly into your email inbox