Rest
Rest
Rest
3) Distributed Technologies
4) Provider Development
6) Swagger
7) Consumer Development
8) Exception Handling
9) Microservices
15) FeignClient
17) Kafka
18) Redis
20) Security
======================
Types of applications
======================
===================================
What is Distributed application ?
===================================
Ex:
==========================================
Why to develop distributed applications ?
==========================================
======================================
Distributed Application Architecture
======================================
ex: IRCTC
===========================
What is Intereoperability
===========================
-> Irrespective of platform and language if two apps are communicating then those
are called as intereoperable applications.
=> XML & JSON formats are univeral, all languages will understand these formats.
==========================
Distributed Technologies
==========================
1) CORBA
2) RMI
3) EJB
- JAX-RPC
- JAX-WS
- JAX-RS (outdated)
- Spring REST (trending)
======
JSON
======
=> In Distributed applications we will use JSON as a mediator between Consumer &
Provider.
Syntax:
"id" : 101,
"name" : "ashok",
"gender" : "male"
=> To convert java object to json data and json data to java object we will use
"Jackson" API.
jackson api
java obj <---------------------> json data
ObjectMapper mapper = new ObjectMapper ( );
=============================
Java with Jackson API Example
==============================
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.16.1</version>
</dependency>
--------------------------------------------------------------------------------
System.out.println("completed....");
}
}
-----------------------------------------------------------------------------------
--
========================================
REST API development using Spring Boot
========================================
-> As part of REST API (Provider) development we will use below annotations
-------------------------------------------------------------------
@RestController
public class MsgRestController {
@GetMapping("/welcome")
public String getWelcomeMsg() {
String msg = "Welcome to REST API..!!";
return msg;
}
@GetMapping("/greet")
public String getGreetMsg(@RequestParam("name") String name) {
String msg = name + ", Good Morning..!!";
return msg;
}
-------------------------------------------------------------
==============
HTTP Methods
================
=> POST, PUT and DELETE methods will have request body.
=> Request Body is used to send payload from consumer to provider in the form xml
or json.
Ex:
===================
HTTP Status Codes
===================
=> Provider will send response to consumer using HTTP Status code.
-------------------------------------------------
@RestController
public class MsgRestController {
@GetMapping("/greet")
public String getGreetMsg(@RequestParam("name") String name) {
String msg = name+", Good Morning..!!";
return msg;
}
@GetMapping("/welcome/{name}")
public ResponseEntity<String> getWelcomeMsg(@PathVariable("name") String
name) {
String msg = name+", Welcome to REST API..!!";
return new ResponseEntity<>(msg, HttpStatus.OK);
}
@GetMapping("/action")
public ResponseEntity<Void> doAction() {
System.out.println("doAction () metdod called...");
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
=============================
REST API with JSON Response
=============================
-----------------------------------------------------------------------
public class Customer {
-------------------------------------------------------------------------
-----------------------------------------------------------------------
@RestController
public class CustomerRestController {
}
------------------------------------------------------------------------
consumes : It represents in which format our rest api method can take input data
from request body
produces : It represents in which format our rest api method can provide response
to consumer in response body.
----------------------------------------------------------------
Assignment-1 : Develop REST API to perform CRUD operations with H2 DB and test it
using POSTMAN.
Reference : https://youtu.be/_rOUDhCE-x4?si=QQqNl9kS3WUrgI2t
----------------------------------------------------------------
=========
Swagger
=========
=> Provider app dev team should provide swagger documentation to consumer app dev
team.
=> Consumer app team will understand provider details using swagger documentation.
==========================
Spring Boot 3.x + Swagger
===========================
=> Add below dependency in pom.xml file
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.1.0</version>
</dependency>
=> Run the application and access swagger-ui page with below url
URL : http://localhost:8080/swagger-ui.html
-----------------------------------------------------------------
============================
IRCTC REST API development
=================-===========
input : N/A
outupt : all tickets data
### Step-1 ) Identify request structure and create req binding class
name
email
doj
from
to
trainNum
### Step-2 ) Identify response structure and create resp binding class
ticket-num
name
doj
from
to
trainNum
status
======================================
Deploying Provider API in AWS cloud
======================================
URL : http://public-ip:8080/swagger-ui/index.html
----------------------------------------------------------------
Provider URL : http://43.205.144.253:8080/swagger-ui/index.html
----------------------------------------------------------------
======================
Consumer Development
======================
=> The application which is accessing services from other applications is called as
consumer application.
@Service
public class MakeMyTripService {
ResponseEntity<Ticket> forEntity =
rt.postForEntity(apiUrl, p, Ticket.class);
ResponseEntity<Ticket[]> forEntity =
rt.getForEntity(apiUrl, Ticket[].class);
return tickets;
----------------------------------------------------------------------
@Controller
public class MakeMyTripController {
@Autowired
private MakeMyTripService service;
@PostMapping("/ticket")
public String ticketBooking(@ModelAttribute("p") Passenger p, Model model) {
Ticket bookTicket = service.bookTicket(p);
model.addAttribute("msg", "Your Ticket Booked, ID : "+
bookTicket.getTicketNum());
return "bookTicket";
}
@GetMapping("/book-ticket")
public String bookTicket(Model model) {
model.addAttribute("p", new Passenger());
return "bookTicket";
}
@GetMapping("/")
public String index(Model model) {
List<Ticket> allTickets = service.getAllTickets();
model.addAttribute("tickets", allTickets);
return "index";
}
}
-------------------------------------------------------------------------
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Bootstrap demo</title>
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/
Dwwykc2MPK8M2HN" crossorigin="anonymous">
</head>
<body>
<div class="container">
integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL"
crossorigin="anonymous"></script>
</body>
</html>
-----------------------------------------------------------------------
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Bootstrap demo</title>
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/
Dwwykc2MPK8M2HN" crossorigin="anonymous">
</head>
<body>
<div class="container">
<a href="book-ticket" class="btn btn-primary">Book Ticket</a>
<h1>View Tickets</h1>
integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL"
crossorigin="anonymous"></script>
</body>
</html>
--------------------------------------------------------------------------
===============
Rest Template
===============
1) getForEntity(..)
2) postForEntity(..)
3) putForEntity(..)
4) deleteForEntity(..)
=> Synchronus means, after sending request, consumer side thread will wait until we
get response from provider.
Note: Asynchronus means after sending request, consumer side thread will not wait
for provider response.
=> To work with Asynchronus communication we will use WebClient which introduced in
spring 6.x version.
@Service
public class MakeMyTripService {
.body(BodyInserters.fromValue(p))
.retrieve()
.bodyToMono(Ticket.class);
return bodyToMono;
}
==================================================================================
@Controller
public class MakeMyTripController {
@Autowired
private MakeMyTripService service;
@PostMapping("/ticket")
public String ticketBooking(@ModelAttribute("p") Passenger p, Model model) {
Mono<Ticket> bookTicket = service.bookTicket(p);
model.addAttribute("ticket", bookTicket);
model.addAttribute("msg", "Your Ticket Booked");
return "bookTicket";
}
@GetMapping("/book-ticket")
public String bookTicket(Model model) {
model.addAttribute("p", new Passenger());
model.addAttribute("ticket", new Ticket());
return "bookTicket";
}
@GetMapping("/")
public String index(Model model) {
Mono<Ticket[]> allTickets = service.getAllTickets();
model.addAttribute("tickets", allTickets);
return "index";
}
}
===============================
Exception Handling in REST API
==============================
----------------------------------------------------------------------------
public class ProductNotFoundException extends RuntimeException{
public ProductNotFoundException() {
@GetMapping("/product/{pid}")
public String getProductInfo(@PathVariable Integer pid) {
@ExceptionHandler(value = Exception.class)
public ResponseEntity<ExInfo> handleEx(Exception e) {
@ExceptionHandler(value = ProductNotFoundException.class)
public ResponseEntity<ExInfo> handleProductNFEx(ProductNotFoundException e) {
====================================
Working with XML data in REST API
====================================
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
-----------------------------------------------------------------------------------
-----------
@RestController
public class BookRestController {
@PostMapping(
value = "/book",
consumes= {"application/xml", "application/json"},
produces = "text/plain"
)
public String addBook(@RequestBody Book b) {
System.out.println(b);
// logic to save in db
return "Book Added";
}
@GetMapping(
value = "/book",
produces = {"application/xml", "application/json"}
)
public Book getBook() {
Book book = new Book(101, "Java", 543.00);
return book;
}
}
=================
Spring Data REST
=================
a) rest-repositories (data-rest)
b) data-jpa
c) mysql-connector-j
d) devtools
@Entity
@Table(name = "book_tbl")
public class Book {
@Id
private Integer id;
private String name;
private Double price;
@RepositoryRestResource(path = "books")
public interface BookRepository extends JpaRepository<Book, Integer>{
POST : http://localhost:9090/books
{
"id": 103,
"name": "DevOps",
"price": 1500.20
}
PUT : http://localhost:9090/books/103
{
"id": 103,
"name": "DevOps",
"price": 2500.20
}
GET : http://localhost:9090/books
GET : http://localhost:9090/books/101
GET : http://localhost:9090/books/search/findByName?name=Java
DELETE : http://localhost:9090/books/101
========================================================
How to disable HTTP Requests in Data REST application ?
========================================================
=> Add below class in Data REST Application to disable PUT and DELETE methods.
Note: With below configuration our api will not accept PUT and DELETE methods.
------------------------------------------------------------------------
@Configuration
public class MyDataRestConfig implements RepositoryRestConfigurer {
@Override
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration
config, CorsRegistry cors) {
config.getExposureConfiguration()
.forDomainType(Book.class)
.withItemExposure((metadata, http) ->
http.disable(unsupportedMethods))
.withCollectionExposure((metadata,http) ->
http.disable(unsupportedMethods));
}
}
-------------------------------------------------------------------------
Assignment : How to send Async request using WebClient.
=> In below class getQuoteV1() method will act as synchronus client and
getQuoteV2() method will act as asynchronus client.
-------------------------------------------------------------------------
@Service
public class QuoteService {
client.get()
.uri(QUOTE_ENDPOINT)
.header("Accept", "application/json")
.retrieve()
.bodyToMono(String.class)
.subscribe(QuoteService::handleResponse);
System.out.println(bodyToMono.block());
--------------------------
REST API classes summary
--------------------------