Spring Boot REST
Spring Boot REST
With Spring REST API, we can build REST webservices or we can build REST
clients.
In Java, if you want to build RESTful webservices, then we have two options.
1. JAX-RS API
1. @RestController
2. @RequestMapping
@GetMapping
@PostMapping
@PutMapping
@DeleteMapping
@PatchMapping
3. @RequestParam
4. @RequestBody
5. @PathVariable
6. @ResponseStatus
7. @ExceptionHandler, etc..
@RestController = @Controller + @ResponseBody
@RestController tells the spring that this class handles HTTP request and
the returned data should be directly written to the HTTP response body.
@RequestMapping maps HTTP requests to the handler methods of MVC
controllers and REST controllers.
@RequestMapping can be used at class level and also at method level to
specify the request path and HTTP method,etc.
For ex:
@RestController
@RequestMapping(“/api”)
public class HelloController {
@RequestMapping(value=”/hello”, method=RequestMethod.GET)
public String sayHello() {
return “Hello”;
}
}
@GetMapping: Handles GET requests
@PostMapping: Handles POST requests
@PutMapping: Handles PUT requests
@DeleteMapping: Handles DELETE requests
@PatchMapping: Handles PATCH requests
@RequestParam: Binds request parameters to the method arguments.
@RequestBody: Binds the HTTP request body to a method argument.
This annotation de-serializes the data passed in the
request body with
a format like XML or JSON or any other format into a Java
object.
@PathVariable: While mapping a request path to the controller method, we
can define template variables. This @PathVariable binds the template varaibles
to method arguments.
@RestController
public class ItemController {
@GetMapping(“/item/{id}”)
public Item getItem(@PathVariable(“id”) int itemId) {
//logic
}
@PostMapping(“/create”)
@ResponseStatus(HttpStatus.CREATED)
public Item create(@RequestBody Item newItem) {
}
}
@ResponseStatus marks that when the controller method is returning the
response,
the response should include the given HTTP status code.
For ex:
@RestController
public class ItemController {
@ExceptionHandler(ItemNotFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public String handleItemNotFound() {
//logic
}
}
MVC flow:
REST flow:
YAML file:
YAML ---- YAML Ain’t Markup Language
YAML is a more user-friendly and more readable hierarchical data and
structured with indentation.
We can use YAML file as an alternate for a traditional properties file, to
configure the application configuration properties.
Properties file is a simple configuration file, where the settings are stroed in
the form
key-value pairs, one per line.
YAML files is a good fit for defining both a simple or complex configuration
settings for an application.
The file name could be application.yml or application.yaml at
src/main/resources.
The Spring Boot will look for application.properties in the src/main/resources
and if it is present, then it reads the properties and configures for the
application.
If Spring Boot finds application.yml , then it reads the properties and
configures for the application.
If both the files are defined and if there is any matching key in both the files
then the value loaded from properties file will be overridden with the value
from the yaml file.
ResponseEntity:
ResponseEntity is a class in spring framework, it represents the full HTTP
response that a REST API can send to the client.
A ResponseEntity object, includes status code, response headers and
response body.
While creating a rest controller method, we can use ResponseEntity as a
return type to the controller method.
The controller method returns ResponseEntity object to the
DispatcherServlet.
The DispatcherServlet will fetch/retrieve the data from the ResponseEntity
object and prepares HTTP response, then sends to the client.
RestTemplate class:
. It is a class in spring framework, which can be used to consume REST API in
a spring application.
. With the help of RestTemplate class, a spring application can invoke the
different REST endpoints of a service provider application.
. RestTemplate class has provided methods to access the endpoints with
various HTTP methods like GET, PUT, POST, DELETE and PATCH.
some of the methods of RestTemplate class are,
1. getForObject() : By making GET request, it will fetch a resource and
converts it into a specified Java object.
for ex:
String url = “http://localhost:8080/api/7878”;
Employee e = restTemplate.getForObject(url, Employee.class);
For ex:
String postUrl=”http://localhost:8080/api/add”;
Employee newEmployee = new Employee(2323, “ABCD”,4000,20);
String msg = restTemplate.postForObject(postUrl,newEmployee,
String.class);
4. postForEntity(): By making HTTP POST request, it will send a Java object
in request body and returns a ResponseEntity object.
for ex:
String postUrl=”http://localhost:8080/api/add”;
Employee newEmployee = new Employee(2323, “ABCD”,4000,20);
ResponseEntity<String> re = restTemplate.postForEntity(postUrl,
newEmployee, String.class);
5. exchange(): This method can invoke the given url with a given HTTP
method. Returns ResponseEntity object.
https://github.com/ShekherJava/SB-EmpCRUD-Client.git
================================================
===================
WebClient:
. RestTemplate is a legacy class, can be used to invoke the REST API of a Service
provider application, from a spring client application.
. WebClient is a new class introduced in Spring 5, as part of the Spring WebFlux
module.
. RestTemplate executes the request in a blocking manner, meaning the thread
is blocked until the response is received.
. WebClient operates in a non-blocking manner, meaning the thread is not
blocked until the response is received.
. RestTemplate provides synchronous communication and WebClient provides
asynchronous communication.
If you're using Spring Boot and want to use WebClient, make sure you have the
following dependency in your pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
Mono and Flux are core types provided by the Reactor library (used in
Spring WebFlux) for handling asynchronous, non-blocking, and reactive
programming.
Mono is used when you expect at most one value (e.g., retrieving a single
object).
If no value is emitted, it completes successfully with or without data.
If an error occurs during the operation, it propagates the error .
Flux is used when you expect a stream of data or multiple values (e.g.,
reading a list, a collection, or data in chunks).
Once all values are emitted, it sends a completion signal.
If an error occurs, it propagates the error.
https://github.com/ShekherJava/SB-EmpCRUD-WebClient.git
swagger
When a REST API is developed, it must be made available for the clients to
access.
Clients can understand your REST API, with the help of the document
provided to the clients.
This document can be prepared either manually or with the help of a tool.
To prepare manually, you should use HTML, CSS and Javascript.
Manual preparation is a time taken and each time when the REST API is
updated, the documentation is also need to be updated manually.
So, you have use a tool like swagger to prepare the documentation.
Swagger is a powerful tool, it allows to build the document and also
consume the REST API’s.
It provides a User interface to interact with the endpoints and helps the
clients to understand the endpoints.
To integrate swagger with spring boot, we need to use Springfox or
Springdoc libraries.
Springfox library is not property supporting Spring Boot 3.3.x. But Springdoc
library supports.
To add Springdoc library support, we need to add the below dependency to
the pom.xml file.
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.1.0</version>
</dependency>
- ---
- ---
}
2. @Operation : It is used to customize the individual endpoints by adding a
short message and a detailed message
ex:
@Tag(name=”employees”, description=”Operations on employees”)
@RestController
@RequestMapping(“/api”)
public class EmployeeAPI {
4. @Parameter :
It is used to customize the description for the method parameters.
@GetMapping( value = "/{id}", produces = "application/json")
@ResponseStatus(HttpStatus.OK)
public Employee getEmployeeById(@Parameter(description="ID of the employee
to retrieve") @PathVariable int id) {
return service.fetchEmpById(id);
}
5. @Schema:
It is used to define description for the models and its fields.
ex:
6. @Hidden:
. It is used to hide an endpoint from the documentation.
for ex:
@Hidden
@GetMapping("/internal")
public String internalEndpoint() {
return "This is internal endpoint";
}
=====================================================
=============
@ExceptionHandler(UserNotFoundException.class)
public ResponseEntity<String>
handleUserNotFoundException(UserNotFoundException ex) {
return new ResponseEntity<>("Error : "+ ex.getMessage(),
HttpStatus.NOT_FOUND);
}
@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleException(Exception ex) {
return new ResponseEntity<>("Invalid request : "+ ex.getMessage(),
HttpStatus.BAD_REQUEST);
}
. Global exception handling applies to across the entire spring boot application.
It is not for a specific controller class-level, it is for the entire application-level.
. we can centralize the error handling logic, by creating global exception
handling.
. The annotations for global exception handling are,
@RestControllerAdvice -- used at class level
@ExceptionHandler ---- used at method level
@RestController = @Controller + @ResponseBody
@RestControllerAdvice = @ControllerAdvice + @ResponseBody
For example,
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(UserNotFoundException.class)
public ResponseEntity<String>
handleUserNotFoundException(UserNotFoundException ex) {
return new ResponseEntity<>("Error : "+ ex.getMessage(),
HttpStatus.NOT_FOUND);
}
@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleException(Exception ex) {
return new ResponseEntity<>("Invalid request : "+ ex.getMessage(),
HttpStatus.BAD_REQUEST);
}
https://github.com/ShekherJava/SB-REST-Exceptions.git
Spring Security
. spring security is one of the modules of the spring framework, using which we can
provide security for spring mvc and spirng REST applications.
. It provides support for authentication, authorization and other security features.
. Spring security has provided a group of filters, which is also called security filter chain
and this chain consists multiple filters and each filter will perform the different aspects
of the security.
. This AccessDecisionManager, will evaluate whether the user’s roles are permitted to
access the resource or not.
. If authentication fails, then also the same filter will handle by redirecting the user to
an error page or returns 401(Unauthorized) response.
create two tables in the database like below.
use test;
create table users (
username varchar(50) primary key,
password varchar(200) not null,
enabled boolean not null
);
create table authorities (
username varchar(50),
authority varchar(50),
constraint fk_authorities_users foreign key(username) references
users(username)
);
Data preparation application github link
https://github.com/ShekherJava/SB-Data-Preparation.git
Rest API with Spring security configuration included
https://github.com/ShekherJava/SB-EmpCURD-REST.git
JWT(JSON Web Token):
Flow:
1. The client sends credentials to the server.
2. The server will verify the credentials and generates the JWT token.
3. The server will tranmit the token back to the client.
4. The client will store the token in a local storage.
5. The client will send the token in the subsequent requests, in Authorization header.
6. The server validates the token on each request. If it is valid, the request will
process, otherwise request is rejected.
Spring security relies on server-side sessions. When a user logs in, a session is
created for storing the session data on the server and every time when a user
makes a request, the server will look up for the session and verifies who is the user.
So, Spring security exhibits stateful behaviour.
In JWT, when a user logs in, the server creates a token containing all the necessary
information like user identity, roles, etc, signs it and then sends to the user. Every
time when a user makes a request, the token is also sent in the header and the
server verfies the token, without maintaining any sessions.
So, JWT exhibits stateless behaviour.
In Spring security, if you want to scale the application on to the multiple servers,
you also need to share the sessions between the servers. So, scaling is not too
easy.
In JWT, if you want to scale the application then you can easily do it, because there
is no need to share the sessions between servers.
So, for single server environments, Spring security could be used and for
distributed systems, JWT’s is a preferred way.
JWT token structure:
The JWT token contains 3 parts, separated by dots(.)
1. header
2. payload
3. signature
Header part contains the type of the token i.e., JWT and the algorithm used to
generate the signature either HMACSHA256 or RSA.
Payload part contains the user info like username, roles, email, etc.. and additional
information like token creation time and expire time etc..
Signature part ensures that the JWT token has not been tampared.
“alg”: “HS256”,
“typ”: “jwt”
Then, this JSON is Base64Url encoded to form the first part of the JWT token.
“sub”: “123456789”,
“name”: “john”,
“admin”: true
Then, this JSON is Base64Url encoded to form the second part of the JWT token.
To create the signature part you have to take the encoded header, the
encoded payload, a secret, the algorithm specified in the header, and sign
that.
For example if you want to use the HMAC SHA256 algorithm, the signature
will be created in the following way:
HMACSHA256(
Base64UrlEncode(header)+ “.” + Base64UrlEncode(payload), secret
)
The following shows a JWT that has the previous header and payload encoded, and it
is signed with a secret.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibm
FtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4f
wpMeJf36POk6yJV_adQssw5c
When creating a Spring Boot with JWT application, we create the classes like
JwtUtil, JwtFilter and SecurityConfiguration for the below reasons.
The util class (often called JwtUtil or JwtTokenProvider) is responsible for handling
JWT-related tasks like generating, validating, and parsing JWT tokens. Its purpose is
to isolate token management logic, making the code more modular and reusable.
Token Generation: Generates a JWT when a user successfully logs in, using their
username and a secret key.
Token Validation: Verifies if a token is valid, e.g., by checking its signature and
expiration time.
Extracting Claims: Retrieves claims (such as the username) from the token
payload, which can be used for authentication .
This class verifies the token and, if valid, sets the user details in the
SecurityContext, which Spring Security uses to handle authentication and
authorization.
Extracts the JWT from Request Headers: Parses the Authorization header to
retrieve the JWT.
Token Validation: Calls JwtUtil to check if the token is valid.
Setting Authentication Context: If the token is valid, it loads the user’s details
from the database and sets the SecurityContext with an Authentication object,
effectively logging in the user for that request.
The security configuration class (often called SecurityConfig) is used to define
Spring Security’s behavior and to set up the application’s security parameters.
This class configures what URLs are protected, how authentication is handled, and
which filters to apply.
https://github.com/ShekherJava/SB-Rest-JWT.git
===================================================
=================
OAUTH2
How come Google allowing me to use all it’s products with the same account?
Oauth2 terminology:
1. resource owner: The end user, who own the resources(data)
2. client: It is a website/app, which interacts with Authz server, after
taking the permission from the resource owner.
3. Authz server: This is a server, in which the resource owner have an
account and which has the authorization logic.
4. resource server: This is a server which provides the required
resources to the client, by hosting API’s.
For example,
As a user(resource owner), I have opened udemy.com, on my
browser.
udemy.com shows a button to login with Google, when a user
clicks on that button, it redirects the user to the Google
Authz server.
On successful authorization, a token is granted to the udemy
to access the resources.
With this token, udemy will access the user’s profile data
from the Google Resource server.
In this communication,
1. end user is the resource owner
2. udemy.com is the client
3. Google Authz server is the AuthZ server
4. Google Resource server is the Resource server.
Oauth2 framework has specified different grant types to allow the client to
get access token, from Authz server.
The two grant types that, we need to understand for implementing
OAUTH2 in spring are,
. Authorization code grant type
. client credentials grant type
Note: Tell Authz server that you are fine with this client means,
user clicks on login with google button, on the client’s website.
https://github.com/ShekherJava/SB-MVC-OAuth.git