0% found this document useful (0 votes)
510 views

Microservices Notes

The document discusses monolith vs microservices architecture. A monolith architecture involves developing all application functionalities in a single application, while a microservices architecture develops functionalities as multiple independent services/APIs. The document outlines advantages and disadvantages of each approach, and provides steps to implement a sample microservices-based application using technologies like Eureka, Admin Server, Zipkin, API Gateway, and Feign clients.

Uploaded by

Akash Patil
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
510 views

Microservices Notes

The document discusses monolith vs microservices architecture. A monolith architecture involves developing all application functionalities in a single application, while a microservices architecture develops functionalities as multiple independent services/APIs. The document outlines advantages and disadvantages of each approach, and provides steps to implement a sample microservices-based application using technologies like Eureka, Admin Server, Zipkin, API Gateway, and Feign clients.

Uploaded by

Akash Patil
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 33

Monlith Vs Microservices

1) Application can be developed in 2 ways


a. Monolith Architecture
b. Microservices Architecture
2) If we develop all the functionalities in one single application then it is called as Monolith Application

Advantages
1) Development is easy
2) Deployment is easy
3) Performance
4) Easy Testing
5) Easy Debugging
6) KT is easy

1) Dis-Advantages
1) Single point of failure
2) Whole Application Re-Deployment
3) Scalability ( Increasing & Decreasing resources based on demand )
4) Reliability (Strong)
5) Availability (Zero Downtime)
1. If we develop the functionalities in multiple services/apis then it is called as Microservices Architecture
Based Application.
2. Every Microservice will have its own goal

Advantages
1) Loosely coupled
2) Fast Development
3) Quick Releases
4) Flexibility
5) Scalability
6) No Single Point of failure
7) Technology independence
Challenges
1) Bounded context (identifying no.of services to develop)
2) Lot of configurations
3) Visibility
4) Testing is difficult
5) Debugging

Microservices Architecture
1. Microservices is an architectural design pattern to develop our applications
2. There is no fixed architecture for Microservices Based Applications
3. People are customizing Microservices Architecture according to their requirement

Let us see generalized architecture of Microservices


1) Service Registry
2) Admin Server
3) Zipkin Server
4) Services (REST APIs)
5) FeignClient
6) API Gateway
7) ServiceRegistry is used to register all our backend services/apis
8) Service Registry will maintain services names, urls and status of each service
9) We can use EurekaServer as a service registry
10) Note: EurekaServer provided by Spring Cloud Netflix Library
11) AdminServer is used to monitor and manage all our backend services at one place
12) AdminServer will provide user interface to monitor and manage our services
13) Using AdminServer user interface we can access Actuator Endpoints of our services at one place
14) Note: AdminServer and Admin Client provided by 'Code Centric' company (we can integrate with
boot)
15) ZipkinServer is used for Distributed Log Tracing
16) ZipkinServer will provide user interface to monitor application execution details
17) How many services involved and which service took more time to process the request can be
monitored using Zipkin
18) Note: Zipkin is third party open source server (can be integrated with spring boot)
19) Backend services are nothing but REST APIs (which are also called as Microservices)
20) Backend REST APIs contains actual business logic of our application
21) One project will have multiple REST APIs in the backend
22) Each Backend api will act as client for Service Registry + Admin Server + Zipkin Server
23) With in the same application If one backend api communicating with another backend api then
it is called as Interservice communication
24) FeignClient will be used to perform Interservice Communication
25) Note: Based on requirement our backend apis can communicate with 3 rd party apis using
RestTemplate or WebClient
26) Api Gateway will act as an Entry point for our backend apis
27) It acts as mediator between endusers and backend apis
28) API Gateway contains Filters and Routing
29) Filters we can use to authenticate incoming requests
30) Routing will decide which request should go to which backend api
31) Note: In previous versions we have Zuul Proxy as API Gateway but now it got removed from latest
version of boot
32) Spring Cloud Gateway we can use as API Gateway for our application

Microservices Mini Project Implementation


Step- 1) Create Service Registry Application using Eureka Server
1) Create Spring Boot app with below dependencies
a) 'Spring-cloud-starter-netflix-eureka-server'
b) web starter
c) devtools
2) Configure @EnableEurekaServer annotation at boot start class
3) Configure below properties in application.yml file
server:
port: 8761
eureka:
client:
register-with-eureka: false
4) Run the application and access in browser
URL : http://localhost:8761/
Step-2 ) Create Spring Boot Application with Admin Server
1) Create Boot application with below dependencies
a) web-starter
b) devtools
c) admin-server (code centric)
2) Configure @EnableAdminServer annotation at boot start class
3) Configure Embedded Container Port Number (we can use any port)
4) Run the application and access the application in browser

URL : http://localhost:port/
Step-3) Download & Run Zipkin Server
1) Download zipkin jar from below URL
URL : https://search.maven.org/remote_content?g=io.zipkin&a=zipkin-server&v=LATEST&c=exec
2) Run the zipkin server jar file using below command
$ java -jar <zipkin-server-jar>
Step-4) Develop REST API (WELCOME API)

1) Create boot application with below dependencies


a) eureka-discovery-client
b) admin-client
c) zipkin client
d) sleuth (It is for logging)
e) web-starter
f) devtools
g) actuatoR
2) Configure @EnableDiscoveryClient annotation at start class (It will search and register with Eureka)
3) Create Rest Controller with required methods
4) Configure below properties in application.yml
a. server port
b. admin server url
c. actuator endpoints
d. applicaion name
server:
port: 8081
spring:
application:
name: WELCOME-API
boot:
admin:
client:
url: http://localhost:1111/
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
management:
endpoints:
web:
exposure:
include: '*'
5) Run the application and check Eureka Dashboard, Admin Server Dashboard and Zipkin Dashboard
Step-5) Develop REST API (GREET API)
1) Create boot application with below dependencies
(1) eureka-discovery-client
(2) admin-client
(3) zipkin client
(4) sleuth (It is for logging)
(5) web-starter
(6) devtools
(7) actuator
(8) feign-client
2) Configure @EnableDiscoveryClient & @EnableFeignClients annotations at start class
3) Create FeginClient to access WELCOME-API
@FeignClient(name = "WELCOME-API")
public interface WelcomeApiClient {
@GetMapping("/welcome")
public String invokeWelcomeApi();
}
4) Create Rest Controller with required methods
5) Configure below properties in application.yml
- server port
- admin server url
- actuator endpoints
- applicaion name
server:
port: 9091
spring:
application:
name: GREET-API
boot:
admin:
client:
url: http://localhost:1111/
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
management:
endpoints:
web:
exposure:
include: '*'
6) Run the application and check Eureka Dashboard, Admin Server Dashboard and Zipkin Dashboard
Step-6 :: Develop API-Gateway Application
1) Create boot application with below dependencies
- cloud-gateway
- eureka-client
- web-starter
- devtools
2) Configure @EnableDiscoveryClient annotation at boot start class
3) Configure Server Port & API Routings in application.yml file
server:
port: 3333
spring:
application:
name: API-GATEWAY
cloud:
gateway:
discovery:
locator:
enabled: true
lower-case-service-id: true
routes:
- id: one
uri: lb://WELCOME-API
predicates:
- Path=/welcome
- id: two
uri: lb://GREET-API
predicates:
- Path=/greet
4) Run the application and Test it.

 We can access Client sent request information using Filter


 The client request information we can use to validate that request
 Create below Filter in API Gateway (It will execute for every request)

@Component
public class MyPreFilter implements GlobalFilter {
Logger logger = LoggerFactory.getLogger(MyPreFilter.class);
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
logger.info("filter() method executed....");
// Access request information
ServerHttpRequest request = exchange.getRequest();
HttpHeaders headers = request.getHeaders();
Set<String> keySet = headers.keySet();
keySet.forEach(key -> {
List<String> values = headers.get(key);
System.out.println(key + "::" + values);
});
return chain.filter(exchange);
}
}
 When we send request to REST API using POSTMAN, it will send POSTMAN Token in reuqest header.
Using this token we can differentiate request came from other apps or from POSTMAN.

Load Balancing

1) If we run our application on Single Server then all requests will be sent to single server
2) Burden will be increased on the server
3) When burden got increased request processing gets delayed
4) Sometimes our server might crash due to heavy load
To overcome above problems we will use Load Balancing concept
 Load Balancing is the process of distributing load to multiple servers
LBR implementation in Mini Project
 Make below changes in WelcomeApi Rest Controller
@RestController
public class WelcomeRestController {
@Autowired
private Environment env;
@GetMapping("/welcome")
public String welcomeMsg() {
String port = env.getProperty("server.port");
String msg = "Welcome to Ashok IT..!!" + " (Port :: " + port + ")";
return msg;
}
}
 Run Welcome API with 3 instances
-> Righ Click on API
-> Run As -> Run Configurations
-> Select Application
-> Arguments
-> VM Arguments (-Dserver.port=8082)
-> Apply & Run it
 Check Eureka Dashboard
What is Cache ?
1) Cache is a temporary storage
2) When our application wants to access same data frequently then we will use Cache memory
3) Cache will improve performance of our application by reducing database calls
4) Note: Database calls are always costly which will take more time to execute
5) To reduce no.of round trips between application and database we will use 'Cache'

Redis Cache
1) Redis is one of the distributed cache available in the market
2) Redis will store data in key-value pair
3) Multiple Applications can connect with Redis Cache at a time...
4) The open source, in-memory data store used by millions of developers as a database, cache, streaming
engine, and message broker.

Redis Setup
1) Download Redis Software
2) URL : https://redis.io/download/#redis-downloads
3) Run 'redis-server.exe' file
4) Note: By default it runs on '6379' port number
5) Run 'Redis-cli.exe' file
6) Type 'ping' command in Redis CLI
7) Note: Server willl repond with 'PONG' as response

SPRING BOOT WITH REDIS INTEGRATION


1) Spring Boot provided starter pom to connect with Redis Server
2) Create JedisConnectionFactory bean
3) Create RedisTemplate and Inject JedisConnectionFactory into RedisTemplate
4) Using RedisTemplate get HashOperations object
5) Using HashOperations we can perform storing/retrieving/deleting operations with Redis Server

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<exclusions>
<exclusion>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>

@Configuration
public class RedisConfig {
@Bean
public JedisConnectionFactory getJedisConnection() {
JedisConnectionFactory factory = new JedisConnectionFactory();
// factory.setHostName(hostName);
// factory.setPassword(password);
// factory.setPort(port);;
return factory;
}
@Bean
@Primary
public RedisTemplate<String, User> getRedisTemplate(JedisConnectionFactory factory) {
RedisTemplate<String, User> rt = new RedisTemplate<>();
rt.setConnectionFactory(factory);
return rt;
}
}
package in.ashokit.binding;
import java.io.Serializable;
import lombok.Data;
@Data
public class User implements Serializable{
private Integer uid;
private String name;
private Integer age;
}

@RestController
public class UserRestController {
private HashOperations<String, Integer, User> hashOps;
public UserRestController(RedisTemplate<String, User> redisTemplate) {
hashOps = redisTemplate.opsForHash();
}
@PostMapping("/user")
public String storeData(@RequestBody User user) {
hashOps.put("PERSONS", user.getUid(), user);
return "success";
}
@GetMapping("/user/{uid}")
public User getData(@PathVariable Integer uid) {
User value = (User) hashOps.get("PERSONS", uid);
return value;
}
@GetMapping("/users")
public List<User> getAllUsers(){
return hashOps.values("PERSONS");
}
@DeleteMapping("/user/{uid}")
public String deleteUser(@PathVariable Integer uid) {
hashOps.delete("PERSONS", uid);
return "User Deleted";
}
}

Spring Boot Actuators


1) Actuator is one of the powerful feature introduced in Spring Boot
2) Actuators are used to monitor and manage our application
3) Actuators are giving Production ready features for our boot application

Actuator Endpoints

1) /health : To get application health status


2) /info : To get application information
3) /beans : To get what beans loaded by our application
4) /mappings: To get what URL patterns available in our application
5) /configProps : To get configuration properties loaded by our application
6) /heapdump : To download heap data
7) /threaddump : To get threads information
8) /shutdown : To stop our application (This is special, it is binded to POST request)

 To work with actuators we have to use 'spring-boot-starter-actuator' dependency


<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
We can see actuator exposed endpoints using below URL
URL : http://localhost:8080/actuator
Note: /health is a default endpoint which we can access directly
We can expose other actuator endpoints using below property
application.yml
management:
endpoints:
web:
exposure:
include: '*'
Note: To expose endpoints using application.properties we will use below property
management.endpoints.web.exposure.include=*

Working with shutdown


1) IT is used to stop our application
2) We need to enable this manually
3) It is binded to http post request

management:
endpoints:
web:
exposure:
include: '*'
endpoint:
shutdown:
enabled: true

application.properties file vs application.yml file


1) When we create spring boot application by default application.properties will be created
2) We can avoid hard coded values by configuring app properties in this application.properties file
3) properties file will represent data only in key-value format
i. Ex:
ii. server.port = 9090
iii. spring.mvc.view.prefix = /views/
iv. spring.mvc.view.suffix = .jsp
4) properties file will represent data in sequential format
5) properties file will be supported by only java
6) For every profile we need to create a seperate properties file

As an alternate to .properties file we can use .yml file in spring boot


1) YML stands YET ANOTHER MARKUP Language
2) YML represents data in hierarchial format
i. server:
ii. port: 9090
3) YML supports key-value, list and map values also
4) YML supported by other programming languages also (It is universal)
5) All the profiles can be configured in single YML file

Working with Dynamic Properties


application.yml
server:
port: 9090
spring:
application:
name: sb-rest-api
messages:
welcome: Welcome to Ashok IT..!!
greet: Good Morning

@RestController
public class WelcomeRestController {
@Value("${messages.welcome}")
private String welcomeMsg;
@Value("${messages.greet}")
private String greetMsg;
@GetMapping("/welcome")
public String welcomeMsg() {
return welcomeMsg;
}
@GetMapping("/greet")
public String greetMsg() {
return greetMsg;
}
}

 application messages and REST ENdpoint URLS are not recommended to hardcode in java classes.
Because if we change any message or any url then we have to compile and package entire application.
 To avoid this problem we will configure messages and URLs in application.properties file or in
application.yml file
 When we change application.properties file or application.yml file we no need to compile and build
entire project .

Working with App Properties


application.yml
spring:
application:
name: sb-yml-app
ashokit:
messages:
welcomeMsg: Welcome To Ashok IT
greetMsg: Good Morning
wishMsg: All the best
AppProperties.java
@Data
@Configuration
@EnableConfigurationProperties
@ConfigurationProperties(prefix="ashokit")
public class AppProperties {
private Map<String, String> messages = new HashMap<>();
}
DemoRestController.java
@RestController
public class DemoRestController {
@Autowired
private AppProperties props;
@GetMapping("/welcome")
public String getWelcomeMsg() {
Map<String, String> messages = props.getMessages();
String value = messages.get("welcomeMsg");
return value;
}
@GetMapping("/greet")
public String getGreetMsg() {
Map<String, String> messages = props.getMessages();
System.out.println(messages);
String value = messages.get("greetMsg");
return value;
}
@GetMapping("/wish")
public String getWishMsg() {
return props.getMessages().get("wishMsg");
}
}
Config Server
1) As part of our application development we will use several configuration properties
a. Ex:
a) data source properties
b) actuator properties
c) security properties
d) smtp properties
e) kafka properties
f) application messages etc..
2) As of now we configured those configuration properties in application.properties / application.yml file
3) application.properties / application.yml file will be available with in the project
4) When we package our boot application for depeloyment our configuration properites will be part of that
packaged file
5) Note: If we want to change any configuration properties then we have to package our application again
and we have to re-deploy our application (This is not recommended).
6) To avoid this problem we will keep configuration properties outside of the project.

Config server is used to externalize application configuration properties


1) Using Config Server we can load Configuration Properties from outside of the project
2) When we want to change any configuration properties we no need to re-package and re-deploy our
application
3) Using Config Server we can de-couple our application and configuration properties

1) Create Git Hub Repository and keep configuration properties in git hub repo
Note: We need use application name for configuration properties/yml file name
Ex:
welcome.yml
welcome-dev.yml
welcome-prod.yml
admin.yml
admin-dev.yml
admin-prod.yml
reports.yml
reports-dev.yml
reports-prod.yml

Git Repo URL : https://github.com/ashokitschool/configuration_properties.git

Config Server Project


1) Create Boot application with below dependencies
a) config-server
b) actuator
2) Write @EnableConfigServer annotation at boot start class
3) Configure below properties in application.yml file
spring:
cloud:
config:
server:
git:
uri: https://github.com/ashokitschool/configuration_properties
clone-on-start: true
management:
security:
enabled: false

Microservice To Load Config Properties using Config Server (Config Client App)
1) Create Boot application with below dependencies
a) config-client
b) web-starter
c) cloud-bootstrap
2) Configure application name, application port, config-server-url, profile
a) bootstrap.yml (app-name & config-server-url)
spring:
application:
name: welcome
cloud:
config:
uri: http://localhost:8080
b) application.yml (server port)
server:
port: 9090
3) Create Rest Controller with required methods
@RestController
@RefreshScope
public class WelcomeRestController {
@Value("${msg:Config Server Not Working}")
private String msg;
@GetMapping("/")
public String getWelcomeMsg() {
return msg;
}
}
4) Run the application and test it.

Exception Handling In REST API


1) Exception is an unexpected and unwanted situation occuring in the application
2) When exception occured our program will terminate abnormally
3) To achieve graceful termination of the program we need to handle the exception
4) In Java we have below keywords to handle the exceptions

1) try : It is used to keep risky code


2) catch : Catch block is used to handle the exception
3) throw : It is used to re-throw the exception
4) throws : It is used to ignore the exception
5) finally : It is used to execute clean up logic (closing files, closing connection, release resources....)
Note: When we get exception in REST API we should convey that exception information to client / client
application in json format
Ex:
{
msg : "Exception Reason"
code : "SBI0004"
}
Note: In project, for every exception we will use one CODE i.e exception code
 In Spring web mvc we can handle exceptions in 2 ways
1) Controller Based Exception Handling
- Exception Handlers applicable for only particular controller
2) Global Exception Handling
- Exception Handlers applicable for all the classes in the project
@Data
public class ExceptionInfo {

private String msg;


private String code;

}
@RestController
public class DemoRestController {
private Logger logger = LoggerFactory.getLogger(DemoRestController.class);
@GetMapping("/")
public String doAction() {
String msg = "Action in progress";
try {
int i = 10 / 0;
} catch (Exception e) {
logger.error("Exception Occured ::" + e, e);
throw new ArithmeticException(e.getMessage());
}
return msg;
}
@ExceptionHandler(value=ArithmeticException.class)
public ResponseEntity<ExceptionInfo> handleAE(ArithmeticException ae) {
ExceptionInfo exception = new ExceptionInfo();
exception.setMsg(ae.getMessage());
exception.setCode("AIT0004");
return new ResponseEntity<>(exception, HttpStatus.INTERNAL_SERVER_ERROR);
}
}

Spring Security
1) To implement security for our applications Spring provided 'security' module
2) To use Spring Security in our project 'spring-security-starter' we need to add in pom.xml file
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
3) By default it will secure all the endpoints of our application
Default uname : user
Default Pwd: Will be printed on the console
4) To override default credentials we can configure credentails in application.properties file
spring.security.user.name=admin
spring.security.user.password=admin@123

5) Create Rest Controller class with required method


Rest Client To access Secured REST API
@Service
public class WelcomeService {
private String apiUrl = "http://localhost:8080";
public void invokeWelcomeApi() {
RestTemplate rt = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setBasicAuth("admin", "admin@123");
HttpEntity<String> reqEntity = new HttpEntity<>(headers);
ResponseEntity<String> responseEntity = rt.exchange(apiUrl, HttpMethod.GET, reqEntity, String.class);
String body = responseEntity.getBody();
System.out.println(body);
}
public void invokeWelcome() {
WebClient webClient = WebClient.create();
String block = webClient.get()
.uri(apiUrl)
.headers(headers -> headers.setBasicAuth("admin", "admin@123"))
.retrieve()
.bodyToMono(String.class)
.block();
System.out.println(block);
}
}
Mono & Flux Objects
1) Mono means single object
2) Flux means stream of objects
3) Create spring boot application with below 3 dependencies
a) web-starter
b) webflux
c) lombok

--------------------------------
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CustomerEvent {
private String name;
private Date createDate;
}
---------------------------------
@RestController
public class CustomerRestController {
@GetMapping(value = "/event", produces = "application/json")
public ResponseEntity<Mono<CustomerEvent>> getEvent() {
CustomerEvent event = new CustomerEvent("Ashok", new Date());
Mono<CustomerEvent> customerMono = Mono.just(event);
return new ResponseEntity<Mono<CustomerEvent>>(customerMono, HttpStatus.OK);
}
@GetMapping(value = "/events", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public ResponseEntity<Flux<CustomerEvent>> getEvents() {
// creating binding object with data
CustomerEvent event = new CustomerEvent("Ashok", new Date());
// creating stream for binding object
Stream<CustomerEvent> customerStream = Stream.generate(() -> event);
// create flux object using stream
Flux<CustomerEvent> cflux = Flux.fromStream(customerStream);
// setting response interval
Flux<Long> intervalFlux = Flux.interval(Duration.ofSeconds(5));
// combine interval flux and customer event flux
Flux<Tuple2<Long, CustomerEvent>> zip = Flux.zip(intervalFlux, cflux);
// Getting Tuple value as T2
Flux<CustomerEvent> fluxMap = zip.map(Tuple2::getT2);
//sending response
return new ResponseEntity<>(fluxMap, HttpStatus.OK);
}
}

1) Angular is a client side framework developed by Google company


2) Angular framework is developed based on TypeScript
3) Angular is mainley used for Single Page Applications
4) Angular supports multiple devices (Mobiles & Desktops)
5) Angular supports multiple browsers
6) Angular is free and open source
7) Angular JS and Angular both are not same
8) From Angular 2 version onwards it is called as Angular Framework
9) Note: The current version of Angular is 14

Angular Building Blocks

1) Component
2) Metadata
3) Template
4) Data Binding
5) Module
6) Service
7) Dependency Injection
8) Directive
9) Pipes
10) Angular application is collection of components. In components we will write logic to send data to
template and capture data from template. Components are TypeScript classes.
11) Metadata nothing data about the data. It provides information about components.
12) Template is a view where we will write our presentation logic. In Angular application template is a HTML
file. Every Component contains its own Template.
13) Data Binding is the process of binding data between component property and view element in template
file.
14) Module is a collection of components directives and pipes
15) Service means it contains re-usable business logic. Service classes we will inject in Components using
Depdency Injection.
16) Dependency Injection is the process of injecting dependent object into target object. In Angular
applications services will be injected into components using DI.
17) Directives are used to manipulate DOM elements.
18) Pipes are used to transform the data before displaying

 Environment Setup For Angular Applications


1) Install Node JS
2) Install TypeScript
3) Install Angular CLI
4) Install Visual Studio Code IDE
19) Angular 2+ framework is available as a collection of packages, those packages are available in "Node".
To use those packages "npm" (Node Package Manager) is must and should..
a. URL : https://nodejs.org/en/
20) After installing node software, open cmd and type node -v. It should display node version number then
installation is successfull.
21) Angular framework itself is developed based on TypeScript. In Angular applications we will write code
using TypeScript only.
22) We can install Typescript using Node Package Manager (npm). Open command prompt and execute
below command to install TS.
a. $ npm install -g typescript
23) After TypeScript installation got completed we can verify version number using below command in cmd.
If it displays version number then installtion is successfull.
a. $ tsc -v
24) Install Angular CLI software using below command in TypeScript.
a. $ npm install @angular/cli -g
25) Check angular installation using below command
a. $ ng v
-> Download and install VS code IDE
URL : https://code.visualstudio.com/download

1) Note: We are done with angular setup... lets start building angular applications What is Unit testing ?
2) It is the process of testing unit amount of work
3) When we implement code, we need to test weather that code is working or not
4) With the help of unit testing we can identify issues in the code
5) To perform Unit testing we will use Junit
6) Junit is an open source & free framework to perform unit testing for java applications

Mocking
1) Mocking is the process of creating substitute object for the real object
2) Using Mock Objects we can perform isolated unit testing

@Service
public class WelcomeService {
public String getMsg() {
String msg = "Good Morning";
return msg;
}
}
-----------------------------------------------------------
@RestController
public class WelcomeRestController {
@Autowired
private WelcomeService service;
@GetMapping("/welcome")
public String welcomeMsg() {
String msg = service.getMsg();
return msg;
}
}
@WebMvcTest(value = WelcomeRestController.class)
public class WelcomeRestControllerTest {
@MockBean
private WelcomeService service;
@Autowired
private MockMvc mockMvc;
@Test
public void welcomeMsgTest() throws Exception {
// defining mock obj behaviour
when(service.getMsg()).thenReturn("Welcome to Ashok IT");
// preparing request
MockHttpServletRequestBuilder reqBuilder = MockMvcRequestBuilders.get("/welcome");
// sending request
MvcResult mvcResult = mockMvc.perform(reqBuilder).andReturn();
// get the response
MockHttpServletResponse response = mvcResult.getResponse();
// validate response status code
int status = response.getStatus();
assertEquals(200, status);
}
}

Create Spring Boot Application with below starters


a. web-starter
b. data-jpa
c. h2
d. project lombok
e. devtools
Create Entity class
@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;
}

Create Repository interface


public interface BookRepository extends JpaRepository<Book, Serializable>{
}

Create Service interface and impl class


public interface BookService {
public String upsertBook(Book book);
public List<Book> getAllBooks();
}
@Service
public class BookServiceImpl implements BookService {
private BookRepository repository;
public BookServiceImpl(BookRepository repository) {
this.repository = repository;
}
@Override
public String upsertBook(Book book) {
repository.save(book);
return "Record Inserted";
}
@Override
public List<Book> getAllBooks() {
return repository.findAll();
}
}
Create Rest Controller
@RestController
@CrossOrigin
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);
}
}
Configure below properties in application.properties file
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.username=sa
spring.datasource.password=sa
spring.datasource.driver-class-name=org.h2.Driver
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
Run the boot application and insert the data using POST Request
Create Angular application
$ ng new bookapp
Create Book class to represent json response in object format
$ ng generate class Book
export class Book {
bookId:number;
bookName:string;
bookPrice:number;
constructor(a:number,b:string,c:number){
this.bookId = a;
this.bookName = b;
this.bookPrice = c;
}
}
Import HttpClientModule & FormsModule in AppModule
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { FormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule, FormsModule, HttpClientModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }

Write REST Call logic in AppComponent


import { HttpClient } from '@angular/common/http';
import { Component, Inject } from '@angular/core';
import { Book } from './book';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
msg:string="";
book:Book = new Book(1,"Spring", 200);
books:Book[] = [];
constructor(@Inject(HttpClient)private http:HttpClient){}
getData(){
this.http.get<Book[]>("http://localhost:8080/books", {responseType : 'json'})
.subscribe(data => {
this.books = data;
});
}
onInsertClick(){
this.http.post("http://localhost:8080/book", this.book, {responseType:"text"})
.subscribe(data => {
this.msg = data;
});
}
}
Write presentation logic in template
<div>
<h3>Angular UI + Boot REST API</h3>
<form>
Book ID : <input type="text" name="bookId" [(ngModel)]="book.bookId"/><br/>
Book Name : <input type="text" name="bookName" [(ngModel)]="book.bookName"/><br/>
Book Price : <input type="text" name="bookPrice" [(ngModel)]="book.bookPrice"/><br/>
<input type="submit" value="Save Book" (click)="onInsertClick()"/><br/>
{{msg}}
</form>
</div>
<div>
<h3>Book Details</h3>
<input type="button" value="Get Data" (click)="getData()"/>
<table border="1">
<tr>
<th>Book Id</th>
<th>Book Name</th>
<th>Book Price</th>
</tr>
<tr *ngFor="let book of books">
<td>{{book.bookId}}</td>
<td>{{book.bookName}}</td>
<td>{{book.bookPrice}}</td>
</tr>
</table>
</div>

Run the Angular Application

You might also like