Skip to main content

Creating REST API With Spring Boot

Let's Create a REST API With Spring Boot
In this post, we will learn how to create REST API with Spring Boot, JPA, Hibernate, and MySQL.
  1. Create the Spring Boot Project.
  2. Define Database configurations.
  3. Create an Entity Class.
  4. Create JPA Data Repository layer.
  5. Create Rest Controllers and map API requests.
  6. Create Unit Testing for API requests and run the unit testing.
  7. Build and run the Project.

Requirement

We need to create a simple REST API to store user data to MySQL database with that API so we can create, update, delete, and get users information.

Create the Spring Boot Project

First, go to Spring Initializr and create a project with below settings
createproject.png
Web — Full-stack web development with Tomcat and Spring MVC
DevTools — Spring Boot Development Tools
JPA — Java Persistence API including spring-data-JPA, spring-orm, and Hibernate
MySQL — MySQL JDBC driver
Actuator — Production-ready features to help you monitor and manage your application
Generate, download, and import to development IDE.

Define Database Configurations

Next Create the database name called user_database in MySQL database server and define connection properties in spring-boot-rest-api-tutorial/src/main/resources/application.properties
## Database Properties
spring.datasource.url = jdbc:mysql://localhost:3306/users_database?useSSL=false
spring.datasource.username = root
spring.datasource.password = root
## Hibernate Properties
# The SQL dialect makes Hibernate generate better SQL for the chosen database
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
# Hibernate ddl auto (create, create-drop, validate, update)
spring.jpa.hibernate.ddl-auto = update

Create Entity Class

@Entity
@Table(name = "users")
@EntityListeners(AuditingEntityListener.class)
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
    @Column(name = "first_name", nullable = false)
    private String firstName;
    @Column(name = "last_name", nullable = false)
    private String lastName;
    @Column(name = "email_address", nullable = false)
    private String email;
    @Column(name = "created_at", nullable = false)
    @CreatedDate
    private Date createdAt;
    @Column(name = "created_by", nullable = false)
    @CreatedBy
    private String createdBy;
    @Column(name = "updated_at", nullable = false)
    @LastModifiedDate
    private Date updatedAt;
    @Column(name = "updated_by", nullable = false)
    @LastModifiedBy
    private String updatedBy;
  /**
   * Gets id.
   *
   * @return the id
   */
  public long getId() {
        return id;
    }
  /**
   * Sets id.
   *
   * @param id the id
   */
  public void setId(long id) {
        this.id = id;
    }
  /**
   * Gets first name.
   *
   * @return the first name
   */
  public String getFirstName() {
        return firstName;
    }
  /**
   * Sets first name.
   *
   * @param firstName the first name
   */
  public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
  /**
   * Gets last name.
   *
   * @return the last name
   */
  public String getLastName() {
        return lastName;
    }
  /**
   * Sets last name.
   *
   * @param lastName the last name
   */
  public void setLastName(String lastName) {
        this.lastName = lastName;
    }
  /**
   * Gets email.
   *
   * @return the email
   */
  public String getEmail() {
        return email;
    }
  /**
   * Sets email.
   *
   * @param email the email
   */
  public void setEmail(String email) {
        this.email = email;
    }
  /**
   * Gets created at.
   *
   * @return the created at
   */
  public Date getCreatedAt() {
        return createdAt;
    }
  /**
   * Sets created at.
   *
   * @param createdAt the created at
   */
  public void setCreatedAt(Date createdAt) {
        this.createdAt = createdAt;
    }
  /**
   * Gets created by.
   *
   * @return the created by
   */
  public String getCreatedBy() {
        return createdBy;
    }
  /**
   * Sets created by.
   *
   * @param createdBy the created by
   */
  public void setCreatedBy(String createdBy) {
        this.createdBy = createdBy;
    }
  /**
   * Gets updated at.
   *
   * @return the updated at
   */
  public Date getUpdatedAt() {
        return updatedAt;
    }
  /**
   * Sets updated at.
   *
   * @param updatedAt the updated at
   */
  public void setUpdatedAt(Date updatedAt) {
        this.updatedAt = updatedAt;
    }
  /**
   * Gets updated by.
   *
   * @return the updated by
   */
  public String getUpdatedBy() {
        return updatedBy;
    }
  /**
   * Sets updated by.
   *
   * @param updatedBy the updated by
   */
  public void setUpdatedBy(String updatedBy) {
        this.updatedBy = updatedBy;
    }
}

Create JPA Data Repository Layer

@Repository
public interface UserRepository extends JpaRepository<User, Long> {}

Create Rest Controllers and Map API Requests


@RestController
@RequestMapping("/api/v1")
public class UserController {
  @Autowired
  private UserRepository userRepository;
  /**
   * Get all users list.
   *
   * @return the list
   */
  @GetMapping("/users")
  public List<User> getAllUsers() {
    return userRepository.findAll();
  }
  /**
   * Gets users by id.
   *
   * @param userId the user id
   * @return the users by id
   * @throws ResourceNotFoundException the resource not found exception
   */
  @GetMapping("/users/{id}")
  public ResponseEntity<User> getUsersById(@PathVariable(value = "id") Long userId)
      throws ResourceNotFoundException {
    User user =
        userRepository
            .findById(userId)
            .orElseThrow(() -> new ResourceNotFoundException("User not found on :: " + userId));
    return ResponseEntity.ok().body(user);
  }
  /**
   * Create user user.
   *
   * @param user the user
   * @return the user
   */
  @PostMapping("/users")
  public User createUser(@Valid @RequestBody User user) {
    return userRepository.save(user);
  }
  /**
   * Update user response entity.
   *
   * @param userId the user id
   * @param userDetails the user details
   * @return the response entity
   * @throws ResourceNotFoundException the resource not found exception
   */
  @PutMapping("/users/{id}")
  public ResponseEntity<User> updateUser(
      @PathVariable(value = "id") Long userId, @Valid @RequestBody User userDetails)
      throws ResourceNotFoundException {
    User user =
        userRepository
            .findById(userId)
            .orElseThrow(() -> new ResourceNotFoundException("User not found on :: " + userId));
    user.setEmail(userDetails.getEmail());
    user.setLastName(userDetails.getLastName());
    user.setFirstName(userDetails.getFirstName());
    user.setUpdatedAt(new Date());
    final User updatedUser = userRepository.save(user);
    return ResponseEntity.ok(updatedUser);
  }
  /**
   * Delete user map.
   *
   * @param userId the user id
   * @return the map
   * @throws Exception the exception
   */
  @DeleteMapping("/user/{id}")
  public Map<String, Boolean> deleteUser(@PathVariable(value = "id") Long userId) throws Exception {
    User user =
        userRepository
            .findById(userId)
            .orElseThrow(() -> new ResourceNotFoundException("User not found on :: " + userId));
    userRepository.delete(user);
    Map<String, Boolean> response = new HashMap<>();
    response.put("deleted", Boolean.TRUE);
    return response;
  }
}

Create Unit Testing for API Requests and Run the Unit Testing

@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class ApplicationTests {
@Autowired
private TestRestTemplate restTemplate;
@LocalServerPort
private int port;
private String getRootUrl() {
return "http://localhost:" + port;
}
@Test
public void contextLoads() {
}
@Test
public void testGetAllUsers() {
HttpHeaders headers = new HttpHeaders();
HttpEntity<String> entity = new HttpEntity<String>(null, headers);
ResponseEntity<String> response = restTemplate.exchange(getRootUrl() + "/users",
HttpMethod.GET, entity, String.class);
Assert.assertNotNull(response.getBody());
}
@Test
public void testGetUserById() {
User user = restTemplate.getForObject(getRootUrl() + "/users/1", User.class);
System.out.println(user.getFirstName());
Assert.assertNotNull(user);
}
@Test
public void testCreateUser() {
User user = new User();
user.setEmail("admin@gmail.com");
user.setFirstName("admin");
user.setLastName("admin");
user.setCreatedBy("admin");
user.setUpdatedBy("admin");
ResponseEntity<User> postResponse = restTemplate.postForEntity(getRootUrl() + "/users", user, User.class);
Assert.assertNotNull(postResponse);
Assert.assertNotNull(postResponse.getBody());
}
@Test
public void testUpdatePost() {
int id = 1;
User user = restTemplate.getForObject(getRootUrl() + "/users/" + id, User.class);
user.setFirstName("admin1");
user.setLastName("admin2");
restTemplate.put(getRootUrl() + "/users/" + id, user);
User updatedUser = restTemplate.getForObject(getRootUrl() + "/users/" + id, User.class);
Assert.assertNotNull(updatedUser);
}
@Test
public void testDeletePost() {
int id = 2;
User user = restTemplate.getForObject(getRootUrl() + "/users/" + id, User.class);
Assert.assertNotNull(user);
restTemplate.delete(getRootUrl() + "/users/" + id);
try {
user = restTemplate.getForObject(getRootUrl() + "/users/" + id, User.class);
} catch (final HttpClientErrorException e) {
Assert.assertEquals(e.getStatusCode(), HttpStatus.NOT_FOUND);
}
}
}

Build and Run the Project

mvn package
java -jar target/spring-boot-rest-api-tutorial-1.0.0.jar
Alternatively, you can run the app without packaging it using:
mvn spring-boot:run
The app will start running at http://localhost:8080.

Comments

Popular posts from this blog

Let's Understand Ten Machine Learning Algorithms

Ten Machine Learning Algorithms to Learn Machine Learning Practitioners have different personalities. While some of them are “I am an expert in X and X can train on any type of data”, where X = some algorithm, some others are “Right tool for the right job people”. A lot of them also subscribe to “Jack of all trades. Master of one” strategy, where they have one area of deep expertise and know slightly about different fields of Machine Learning. That said, no one can deny the fact that as practicing Data Scientists, we will have to know basics of some common machine learning algorithms, which would help us engage with a new-domain problem we come across. This is a whirlwind tour of common machine learning algorithms and quick resources about them which can help you get started on them. 1. Principal Component Analysis(PCA)/SVD PCA is an unsupervised method to understand global properties of a dataset consisting of vectors. Covariance Matrix of data points is analyzed here to un

GraphQL - A Short Intro

Why GraphQL is the future of APIs Since the beginning of the web, developing APIs has been a difficult task for developers. The way we develop our APIs must evolve with time so that we can always build good, intuitive and well-designed APIs. In the last few years, GraphQL has been growing in popularity among developers. A lot of companies have started adopting this technology to build their APIs. GraphQL is a query language developed by Facebook in 2012 and released publicly in 2015. It has been gaining a lot of traction. It has been adopted by a lot of big companies such as Spotify, Facebook, GitHub, NYTimes, Netflix, Walmart, and so on. In this series of tutorials, we’re going to examine GraphQL, understand what it is, and see what features make this query language so intuitive and easy to use. So, let’s get started by examining the problems with REST, and how GraphQL solves them. We will also find out why companies have been building their APIs with GraphQL, and why

gRPC with Java : Build Fast & Scalable Modern API & Microservices using Protocol Buffers

gRPC Java Master Class : Build Fast & Scalable Modern API for your Microservice using gRPC Protocol Buffers gRPC is a revolutionary and modern way to define and write APIs for your microservices. The days of REST, JSON and Swagger are over! Now writing an API is easy, simple, fast and efficient. gRPC is created by Google and Square, is an official CNCF project (like Docker and Kubernetes) and is now used by the biggest tech companies such as Netflix, CoreOS, CockRoachDB, and so on! gRPC is very popular and has over 15,000 stars on GitHub (2 times what Kafka has!). I am convinced that gRPC is the FUTURE for writing API for microservices so I want to give you a chance to learn about it TODAY. Amongst the advantage of gRPC: 1) All your APIs and messages are simply defined using Protocol Buffers 2) All your server and client code for any programming language gets generated automatically for free! Saves you hours of programming 3) Data is compact and serialised 4) API