Azure SQL Database + Spring Boot - Build REST CRUD APIs

Hello everyone, Hope you are doing well. In this tutorial, you will learn how to build REST CRUD APIs with Spring Boot, Spring Data JPA and Microsoft Azure SQL Database.


A little bit of Background

Azure SQL Database

Azure SQL Database is a fully managed platform as a service (PaaS) database engine that handles most of the database management functions such as upgrading, patching, backups, and monitoring without user involvement. Azure SQL Database is always running on the latest stable version of the SQL Server database engine and patched OS with 99.99% availability. PaaS capabilities built into Azure SQL Database enable you to focus on the domain-specific database administration and optimization activities that are critical for your business.

Spring Boot

Spring Boot makes it easy to create stand-alone, production-grade Spring-based Applications that you can "just run". 


Spring Data JPA

Spring Data JPA, part of the larger Spring Data family, makes it easy to easily implement JPA-based repositories. This module deals with enhanced support for JPA-based data access layers. It makes it easier to build Spring-powered applications that use data access technologies. 
Implementing a data access layer of an application has been cumbersome for quite a while. Too much boilerplate code has to be written to execute simple queries as well as perform pagination, and auditing. Spring Data JPA aims to significantly improve the implementation of data access layers by reducing the effort to the amount that’s actually needed. As a developer, you write your repository interfaces, including custom finder methods, and Spring will provide the implementation automatically.


After completing this tutorial what we will build? 

We will build REST APIs  CRUD features: 




Step 1: Sign in to Azure Portal and create a resource group

Sign in to Azure portal https://portal.azure.com/#home and find "Resource groups" like below.



Then, create a resource group like the one below.


Here the resource group name is "Knowledgefactory". Create a resource group by clicking the "Review + create " button.



Step 2: Create an Azure SQL Database

Select "Azure SQL",

You will be taken to a page like the below image, Then click on the "Create Azure SQL resource" button.

Next, Select the SQL deployment option,
Select Resource type as Database server and then click on the "Create" button.

You will be taken to a page like the below image, 
Select/Enter necessary information like the above image and then, click on the "Review + create" button. Don't forget to keep the "Server admin login" name and "Password" somewhere safe.

Then click on the "Create" button.

Now, You can see "Deployment is in progress" like the below image.

Once deployment is completed you can see the "Your deployment is complete" page like the below image.

Then, click on the "Go to resource" button, and y
ou will be taken to a page like the below image, 
Then, click on "Create database"

Create SQL Database,

Then, click on the "Review + create" button,

Then click on the "Create" button. You can see "Deployment is in progress"

Once deployment is completed you can see the "Your deployment is complete" page like the below image.

Click on the "Connection strings",
Copy it and keep it safe for future purposes.

Whitelisting IP Address for Access to Azure SQL DB, like the below image
Then click on the "Save" button



Step 3: Creating a simple spring boot web application.

First, open the Spring initializr https://start.spring.io/

Then, Provide the Group and Artifact name. We have provided Group name com.knf.dev.demo and Artifact spring-boot-azure-sql-crud. Here I selected the Maven project - language Java - Spring Boot 2.7.1 and add Spring web dependency, Spring Data JPA, and MS SQL Server Driver. 

Then, click on the Generate button. When we click on the Generate button, it starts packing the project in a .zip(spring-boot-azure-sql-crud.zip) file and downloads the project. 
Then, Extract the Zip file.

Import the project on your favourite IDE,

Final Project Directory:



Pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.knf.dev.demo</groupId>
<artifactId>spring-boot-azure-sql-crud</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-boot-azure-sql-crud</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>17</java.version>
</properties>
<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>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

</project>


application.yaml

spring:
datasource:
username: <username>
password: <password>
url: jdbc:sqlserver://<servername>:1433;database=demo_db;encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.windows.net;loginTimeout=30;
jpa:
show-sql: 'true'
hibernate:
ddl-auto: update
logging:
level:
org:
hibernate:
SQL: DEBUG
**Important note** Do not publish the fields directly for security. It would be a good choice to define these variables as environment variables or use the Azure Key Vault. 


Create a User Entity

package com.knf.dev.demo.springbootazuresqlcrud.entity;

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 = "_user")
public class User {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
@Column(name = "email", nullable = false, length = 200)
private String email;

public User() {
super();
}

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getFirstName() {
return firstName;
}

public void setFirstName(String firstName) {
this.firstName = firstName;
}

public String getLastName() {
return lastName;
}

public void setLastName(String lastName) {
this.lastName = lastName;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}

public User(String firstName, String lastName, String email) {
super();
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
}
}


Create User Repository

package com.knf.dev.demo.springbootazuresqlcrud.repository;

import org.springframework.data.repository.CrudRepository;
import com.knf.dev.demo.springbootazuresqlcrud.entity.User;

public interface UserRepository
extends CrudRepository<User, Long> {

}


Global Exception Handling

package com.knf.dev.demo.springbootazuresqlcrud.exception;

import java.util.Date;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;

@ControllerAdvice
public class GlobalExceptionHandler {

@ExceptionHandler(UserNotFound.class)
public ResponseEntity<ErrorMessage>
userNotFound(Exception ex, WebRequest request) {

ErrorMessage errors = new ErrorMessage
(404, new Date(), ex.getMessage(),
"User Not Found");

return new ResponseEntity<>(errors, HttpStatus.NOT_FOUND);
}
}


Create UserNotFoundException

package com.knf.dev.demo.springbootazuresqlcrud.exception;

public class UserNotFound extends RuntimeException {
private static final long serialVersionUID = 1L;

public UserNotFound(String msg) {
super(msg);
}
}


ErrorMessage

package com.knf.dev.demo.springbootazuresqlcrud.exception;

import java.util.Date;

public class ErrorMessage {

private Integer statusCode;
private Date timestamp;
private String message;
private String description;

public Integer getStatusCode() {
return statusCode;
}

public void setStatusCode(Integer statusCode) {
this.statusCode = statusCode;
}

public Date getTimestamp() {
return timestamp;
}

public void setTimestamp(Date timestamp) {
this.timestamp = timestamp;
}

public String getMessage() {
return message;
}

public void setMessage(String message) {
this.message = message;
}

public String getDescription() {
return description;
}

public void setDescription(String description) {
this.description = description;
}

public ErrorMessage(Integer statusCode,
Date timestamp, String message,
String description) {
super();
this.statusCode = statusCode;
this.timestamp = timestamp;
this.message = message;
this.description = description;
}
}


Create UserController

package com.knf.dev.demo.springbootazuresqlcrud.controller;

import java.util.ArrayList;
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.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.knf.dev.demo.springbootazuresqlcrud.entity.User;
import com.knf.dev.demo.springbootazuresqlcrud.exception.UserNotFound;
import com.knf.dev.demo.springbootazuresqlcrud.repository.UserRepository;

@RestController
@RequestMapping("/api/v1/users")
public class UserController {

@Autowired
UserRepository userRepository;

// Create user
@PostMapping
public ResponseEntity<User> createUser
(@RequestBody User user) {

User newuser = new User(user.getFirstName(),
user.getLastName(), user.getEmail());
userRepository.save(newuser);
return new ResponseEntity<>(newuser, HttpStatus.CREATED);

}

// Update user
@PutMapping("/{id}")
public ResponseEntity<User> updateUser
(@PathVariable("id") Long id, @RequestBody User user) {

Optional<User> userdata = userRepository.findById(id);
if (userdata.isPresent()) {
User _user = userdata.get();
_user.setEmail(user.getEmail());
_user.setFirstName(user.getFirstName());
_user.setLastName(user.getLastName());
return new ResponseEntity<>
(userRepository.save(_user), HttpStatus.OK);
} else {
throw new UserNotFound("Invalid User Id");
}
}

// Get all Users
@GetMapping
public ResponseEntity<List<User>> getAllUsers() {

List<User> users = new ArrayList<User>();
userRepository.findAll().forEach(users::add);
return new ResponseEntity<>(users, HttpStatus.OK);

}

// Get user by ID
@GetMapping("/{id}")
public ResponseEntity<User> getUserByID
(@PathVariable("id") Long id) {

Optional<User> userdata = userRepository.findById(id);
if (userdata.isPresent()) {
return new ResponseEntity<>(userdata.get(),
HttpStatus.OK);
} else {
throw new UserNotFound("Invalid User Id");
}

}

// Delete user
@DeleteMapping("/{id}")
public ResponseEntity<User> deleteUser
(@PathVariable("id") Long id) {

Optional<User> userdata = userRepository.findById(id);
if (userdata.isPresent()) {
userRepository.deleteById(id);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
} else {
throw new UserNotFound("Invalid User Id");
}
}
}


Spring Boot Main Driver

package com.knf.dev.demo.springbootazuresqlcrud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

Step 4: Local Setup and Run the application

Step 1: Download or clone the source code from GitHub to the local machine - Click here


Step 2: mvn clean install


Step 3: Run the Spring Boot application - 

mvn spring-boot:run


Step 5: Test the APIs using postman

1. Add User:


2. Get User By Id:


3. Update User:


4. Get All Users:


5. Delete User:

Popular posts from this blog

Learn Java 8 streams with an example - print odd/even numbers from Array and List

Java Stream API - How to convert List of objects to another List of objects using Java streams?

Registration and Login with Spring Boot + Spring Security + Thymeleaf

Java, Spring Boot Mini Project - Library Management System - Download

ReactJS, Spring Boot JWT Authentication Example

Spring Boot + Mockito simple application with 100% code coverage

Top 5 Java ORM tools - 2024

Java - Blowfish Encryption and decryption Example

Spring boot video streaming example-HTML5

Google Cloud Storage + Spring Boot - File Upload, Download, and Delete