What is Disributed Application
What is Intereoperability
What is HTTP Protocol
HTTP Methods
HTTP Status Codes
HTTP Request Structure
HTTP Response Structure
Working with XML and JAX-B
Working with JSON and Jackson
+++++++++++++++++++++++++++++++
How to develop REST API using Java
+++++++++++++++++++++++++++++++++
-> To develop RESFul Services/ REST APIs using java SUN Microsystem released 'JAX-
RS' API
-> JAX-RS api having 2 implementations
1) Jersey (Sun Microsystems)
2) REST Easy (JBOSS)
Note: We can develop RESTFul Services using any one of the above implementation
-> Spring framework also provided support to develop RESTFul Services using 'Spring
Web MVC' module.
+++++++++++++++++++++++++
RESTFul Services Architecture
+++++++++++++++++++++++++
-> We will have 2 actors in RESTful services
1) Provider / Resource
2) Consumer / Client
-> The application which is providing services to other applications is called as
Provider or Resource application
-> The application which is accessing services from other applications is called as
Consumer or Client application
-> Client application and Resource application will exchange data in intereoperable
format (like XML & JSON)
request
client app <------------------------> resource app
response
Note: RESTful Services are used to develop B2B communications (No presentation
logic, No view Resolver)
+++++++++++++++++++++++++++++++++++
Develop First REST API Using Spring Boot
+++++++++++++++++++++++++++++++++++
1) Create Spring starter application with below dependencies
a) web-starter
b) devtools
2) Create RestController with Required methods
Note: To represent java class as Rest Controller we will use @RestController
annotation
@RestController = @Controller + @ResponseBody
Note: Every RestController method should be binded to HTTP Protocol method
Ex: @GetMapping, @PostMapping, @PutMapping & @DeleteMapping
3) Run the application and test it.
Note: To test REST APIs we will use POSTMAN tool (It is free)
Note: Download postman tool to test our REST API functionality
+++++++++++++++++++++++++++++++++++
@RestController
public class WelcomeRestController {
@GetMapping("/welcome")
public ResponseEntity<String> getWelcomeMsg() {
String respPayload = "Welcome to Ashok IT";
return new ResponseEntity<>(respPayload, HttpStatus.OK);
}
@GetMapping("/greet")
public String getGreetMsg() {
String respPayload = "Good Morning..!!";
return respPayload;
}
}
+++++++++++++++++++++++++++++++++++
Note: GET Request will not contain Request Body to send data
-> We can use Query Params and Path Params to send data in GET Request
-> Query Params & Path Params will represent data in URL directlry
++++++++++++++
Query Params
++++++++++++++
-> Query Params are used to send data to server in URL directly
-> Query Params will represent data in key-value format
-> Query Params will start with '?'
-> Query Parameters will be seperated by '&'
-> Query Parameters should present only at the end of the URL
Ex: www.ashokit.in/courses?name=SBMS&trainer=Ashok
-> To read Query Parameters from the URL we will use @RequestParam annotation
@GetMapping("/welcome")
public ResponseEntity<String> getWelcomeMsg(@RequestParam("name") String
name) {
String respPayload = name + ", Welcome to Ashok IT";
return new ResponseEntity<>(respPayload, HttpStatus.OK);
}
URL : http://localhost:8080/welcome?name=Raju
+++++++++++++++++++++++++++++++++
Working with 2 Query Params in URL
+++++++++++++++++++++++++++++++++++
@RestController
public class CourseRestController {
@GetMapping("/course")
public ResponseEntity<String> getCourseFee(@RequestParam("cname") String
cname,
@RequestParam("tname") String tname) {
String respBody = cname + " By " + tname + " Fee is 7000 INR";
return new ResponseEntity<>(respBody, HttpStatus.OK);
}
}
URL : http://localhost:8080/course?cname=JRTP&tname=Ashok
++++++++++++++++++++++++++++
Path Parameter or URI variables
+++++++++++++++++++++++++++++
-> Path Parameters are also used to send data to server in URL
-> Path Params will represent data directley in URL (no keys)
-> Path Params can present anywhere in the URL
-> Path Params will be seperated by / (slash)
-> Path Params should be represented in Method URL pattern (Template Pattern)
Ex: www.ashokit.in/courses/{cname}/trainer/{tname}
-> To read Path Parameters we will use @PathVariable annotation
@RestController
public class BookRestController {
@GetMapping("/book/{name}")
public ResponseEntity<String> getBookPrice(@PathVariable("name") String name)
{
String respBody = name + " Price is 400 $";
return new ResponseEntity<>(respBody, HttpStatus.OK);
}
@GetMapping("/book/name/{bname}/author/{aname}")
public ResponseEntity<String> getBook(@PathVariable("bname") String bname,
@PathVariable("aname") String aname) {
String respBody = bname + " By " + aname + " is out of stock";
return new ResponseEntity<>(respBody, HttpStatus.OK);
}
}
URL-1 : http://localhost:8080/book/spring
URL-2 : http://localhost:8080/book/name/spring/author/rodjohnson
+++++++++++++++++++++++++++++++++++++++
Q) When to use Path Params & Query Params ?
++++++++++++++++++++++++++++++++++++++++
-> To retrieve more than one record/resource we will use Query Params (filtering)
-> To retreive specific/unique record we will use Path Params (single)
################
What is Produces
#################
-> "produces" is a media type
-> It represents the response formats supported by REST Controller Method
-> One method can support multiple response formats (xml and json)
produces = { "application/xml", "application/json" }
-> Client should send a request with "Accept" http header
-> Accept header represents in which format client expecting response from the REST
api
-> Based on Accept header value 'Message Converter' will convert the response into
client expected format
@Data
@XmlRootElement
@NoArgsConstructor
@AllArgsConstructor
public class Product {
private Integer pid;
private String pname;
private Double price;
@RestController
public class ProductRestController {
@GetMapping(
value = "/product",
produces = { "application/xml", "application/json" }
)
public ResponseEntity<Product> getProduct() {
Product p1 = new Product(101, "Monitor", 8000.00);
return new ResponseEntity<>(p1, HttpStatus.OK);
}
@GetMapping("/products")
public ResponseEntity<List<Product>> getProducts(){
Product p1 = new Product(101, "Monitor", 8000.00);
Product p2 = new Product(102, "RAM", 6000.00);
Product p3 = new Product(103, "CPU", 15000.00);
List<Product> products = Arrays.asList(p1,p2,p3);
return new ResponseEntity<>(products, HttpStatus.OK);
}
}
##############################
Working with HTTP POST Request
#############################
-> HTTP POST request is used to create new resource/record at server
-> POST request contains request body
-> Client can send data to server in Request Body
-> To bind Rest Controller method to POST request we willl use @PostMapping
-> To read data from Requet body we will use @RequestBody annotation
-> "consumes" represents in which formats method can take input
-> "Content-Type" header represents in which format client sending data in request
body.
@Data
@XmlRootElement
public class Book {
private Integer id;
private String name;
private Double price;
}
---------------------------
@RestController
public class BookRestController {
@PostMapping(
value = "/book",
consumes = { "application/json", "application/xml" }
)
public ResponseEntity<String> addBook(@RequestBody Book book) {
System.out.println(book);
// logic to store in DB
String msg = "Book Added Succesfully";
return new ResponseEntity<String>(msg, HttpStatus.CREATED);
}
}
----------------
{
"id" : 101,
"name" : "Java",
"price" : 450.00
}
------------------------
-> produces vs consumes
-> Content-Type vs Accept
-> produces attribute represents in which formats Method can provide response data
to clients
-> consumes attribute represents in which formats Method can take request data from
clients
-> Accept header represents in which format client expecting response from REST API
-> Content-Type header represents in which format client is sending request data to
REST API
Note: We can use both Consumes & Produces in single REST API method.
++++++++++++++++++++++++++++++++++++++++++++++++++
Requirement : Develop IRCTC REST API to book a train ticket
++++++++++++++++++++++++++++++++++++++++++++++++++++
-> To develop any REST API first we have to understand the requirement
-> Identify input / request data
-> Identify output / response data
-> Create request & response binding classes
-> Create REST Controller with required methods.
-> Test REST API methods behaviour using Postman
@Data
public class PassengerInfo {
private String name;
private Long phno;
private String jdate;
private String from;
private String to;
private Integer trainNum;
@Data
public class TicketInfo {
private Integer ticketId;
private String pnr;
private String ticketStatus;
@RestController
public class TicketRestController {
@PostMapping(
value = "/ticket",
produces = {"application/json"},
consumes = {"application/json"}
)
public ResponseEntity<TicketInfo> bookTicket(@RequestBody PassengerInfo
request){
System.out.println(request);
//logic to book ticket
TicketInfo tinfo = new TicketInfo();
tinfo.setTicketId(1234);
tinfo.setPnr("JLJL6868");
tinfo.setTicketStatus("CONFIRMED");
return new ResponseEntity<>(tinfo, HttpStatus.CREATED);
}
}
-------------------------------
{
"name" : "Ashok",
"phno" : 12345678,
"jdate" : "05-08-2022",
"from" : "hyd",
"to" : "pune",
"trainNum" : 8574
}
{
"ticketId": 1234,
"pnr": "JLJL6868",
"ticketStatus": "CONFIRMED"
}
#################
HTTP PUT Request
#################
-> PUT request is used to update an existing record / resource at server
-> PUT Request can take data in URL and in Request Body
-> To bind our method to PUT request we will use @PutMapping
@PutMapping("/ticket")
public ResponseEntity<String> updateTicket(@RequestBody PassengerInfo
request){
System.out.println(request);
//logic to update ticket
return new ResponseEntity<>("Ticket Updated", HttpStatus.OK);
}
####################
HTTP DELETE Request
####################
-> DELETE request is used to delete an existing record / resource at server
-> DELETE Request can take data in URL and in Request Body
-> To bind our method to DELETE request we will use @DeleteMapping
@DeleteMapping("/ticket/{ticketId}")
public ResponseEntity<String> deleteTicket(@PathVariable("ticketId") Integer
ticketId){
//logic to delete the ticket
return new ResponseEntity<>("Ticket Deleted", HttpStatus.OK);
}
------------------------------------------
What is RestController ?
REST Controller Methods
@GetMapping
@PostMapping
@PutMapping
@DeleteMapping
Query Params
Path Params
Request Body
Response Body
@RequestParam
@PathVariable
@RequestBody
produces
consumes
Accept
Content-Type
Message Converters
ResponseEntity
Q) Can we write the logic to update a record in POST request method ?
Ans) Yes, we can do it but not recommended. We need to follow HTTP Protocol
standards while developing REST API.
+++++++++
Swagger
+++++++
-> Swagger is used to generate documentation for REST APIs
-> Swagger UI is used to test REST API with user interface
Assignment : https://youtu.be/ARlz2-Twm-g (watch Swagger video & practise it)
-> Add below 2 dependencies in pom.xml file
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.8.0</version>
<scope>compile</scope>
</dependency>
-> Add below property in application.properties file
spring.mvc.pathmatch.matching-strategy = ANT_PATH_MATCHER
-> Create Swagger Config class like below
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket apiDoc() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("in.ashokit.re
st"))
.paths(PathSelectors.any())
.build();
}
}
-> We can access swagger ui using below URL
http://localhost:8080/swagger-ui.html#/
-> We can access swagger documentation using below url
http://localhost:8080/v2/api-dcos
++++++++++++++++++++++++++++++++++++++++++++
CRUD Operations using REST API with MySQL DB
++++++++++++++++++++++++++++++++++++++++++++
-> Download & install MySQL Database (DB Server)
-> Download & install MySQL Workbench (DB client)
SQL Queries
DB client ----------------------------> DB server
-> Develop REST API using Layered Architecture
1) Web Layer
2) Business / Serice Layer
3) DAO Layer
@Data
@Entity
@Table(name = "BOOK_DTLS")
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "BOOK_ID")
private Integer bookId;
@Column(name = "BOOK_NAME")
private String bookName;
@Column(name = "BOOK_PRICE")
private Double bookPrice;
public interface BookRepository extends JpaRepository<Book, Serializable>{
public interface BookService {
public String upsertBook(Book book);
public List<Book> getAllBooks();
public String deleteBook(Integer bookId);
}
@Service
public class BookServiceImpl implements BookService {
private BookRepository repository;
public BookServiceImpl(BookRepository repository) {
this.repository = repository;
}
@Override
public String upsertBook(Book book) {
Integer bookId = book.getBookId();
System.out.println(book);
repository.save(book);
System.out.println(book);
if (bookId == null) {
return "Record Inserted";
} else {
return "Record Updated";
}
}
@Override
public List<Book> getAllBooks() {
return repository.findAll();
}
@Override
public String deleteBook(Integer bookId) {
repository.deleteById(bookId);
return "Book Deleted";
}
}
@RestController
public class BookRestController {
@Autowired
private BookService service;
@PostMapping("/book")
public ResponseEntity<String> addBook(@RequestBody Book book) {
String msg = service.upsertBook(book);
return new ResponseEntity<>(msg, HttpStatus.CREATED);
}
@GetMapping("/books")
public ResponseEntity<List<Book>> getAllBooks() {
List<Book> allBooks = service.getAllBooks();
return new ResponseEntity<>(allBooks, HttpStatus.OK);
}
@PutMapping("/book")
public ResponseEntity<String> updateBook(@RequestBody Book book) {
String msg = service.upsertBook(book);
return new ResponseEntity<>(msg, HttpStatus.OK);
}
@DeleteMapping("/book/{bookId}")
public ResponseEntity<String> deleteBook(@PathVariable Integer bookId) {
String msg = service.deleteBook(bookId);
return new ResponseEntity<>(msg, HttpStatus.OK);
}
}
-----------------------------------------------------------------------------------
---------------------------------------------------------------------
######################
Embedded Database (H2)
######################
-> Embedded Databases are temporary databases / in-memory databases
-> Embedded Databases are used for POC development (Proof of concept)
-> We no need to download and install embedded databases
-> Embedded Databases will come along with our application by adding one dependency
-> When we start application then embedded db will start and when we stop the
application then embedded db will be stopped
Note: Data is not permenent in the embedded db (when we stop the application we
will loose the data)
Note: In Memory DBs are not used for realtime project development in the company
-> We can use H2 DB as an in-memory db for practise purpose
-> Add below dependency in pom.xml to
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
-> Configure H2 Datasource properties
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.username=sa
spring.datasource.password=sa
spring.datasource.driver-class-name=org.h2.Driver
-> Run the application and access h2-console using below URL
http://localhost:8080/h2-console