TP Angular microservices spring boot
TP Angular microservices spring boot
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.h2.console.enabled=true
spring.jpa.hibernate.ddl-auto=update
Explanation:
• Configures the server port to 8080.
• Sets up an in-memory H2 database.
• Enables the H2 console for database inspection.
• Automatically updates the database schema based on JPA entities.
1.3 Create Product Entity
Create a Product entity class in the com.example.productservice.model package:
package com.example.productservice.model;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
@Entity
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private double price;
import com.example.productservice.model.Product;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
import java.util.Optional;
@Service
public class ProductService {
import com.example.productservice.model.Product;
import com.example.productservice.service.ProductService;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Optional;
@CrossOrigin(origins = "http://localhost:4200")
@RestController
@RequestMapping("/products")
public class ProductController {
@Autowired
public ProductController(ProductService productService) {
this.productService = productService;
}
@GetMapping
public List<Product> getAllProducts() {
return productService.getAllProducts();
}
@GetMapping("/{id}")
public Optional<Product> getProductById(@PathVariable Long id) {
return productService.getProductById(id);
}
@PostMapping
public Product createProduct(@RequestBody Product product) {
return productService.saveProduct(product);
}
@PutMapping("/{id}")
public Product updateProduct(@PathVariable Long id, @RequestBody Product product) {
product.setId(id);
return productService.saveProduct(product);
}
@DeleteMapping("/{id}")
public void deleteProduct(@PathVariable Long id) {
productService.deleteProduct(id);
}
}
Explanation:
• @CrossOrigin(origins = "http://localhost:4200"): Enables CORS for requests from the
Angular frontend running on localhost:4200.
• @RestController: Marks the class as a REST controller.
• @RequestMapping("/products"): Maps requests to /products.
• getAllProducts(): Handles GET requests to retrieve all products.
• getProductById(Long id): Handles GET requests to retrieve a product by ID.
• createProduct(@RequestBody Product product): Handles POST requests to create a
new product.
• updateProduct(@PathVariable Long id, @RequestBody Product product): Handles PUT
requests to update an existing product.
• deleteProduct(@PathVariable Long id): Handles DELETE requests to delete a product by
ID.
1.7 Run the Spring Boot Application
Run the application by executing the ProductServiceApplication class. The backend should be
up and running on http://localhost:8080.
Step 2: Setting Up the Angular Frontend
2.1 Create an Angular Project
1. Open a terminal and run the following command to create a new Angular project:
ng new product-client defaults --standalone=false
2. Navigate to the project directory:
cd product-client
2.2 Install Dependencies
Install Bootstrap for styling:
npm install bootstrap
Add Bootstrap to angular.json:
"styles": [
"src/styles.css",
"node_modules/bootstrap/dist/css/bootstrap.min.css"
],
2.3 Create Angular Services and Components
2.3.1 Create Product Service
Generate the ProductService:
ng generate service services/product
Edit product.service.ts:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class ProductService {
getAllProducts(): Observable<any> {
return this.http.get(`${this.baseUrl}`);
}
@Component({
selector: 'app-product-list',
templateUrl: './product-list.component.html',
styleUrls: ['./product-list.component.css']
})
export class ProductListComponent implements OnInit {
products: any[] = [];
ngOnInit(): void {
this.productService.getAllProducts().subscribe(data => {
this.products = data;
});
}
deleteProduct(id: number) {
this.productService.deleteProduct(id).subscribe(() => {
this.products = this.products.filter(product => product.id !== id);
});
}
}
Edit product-list.component.html:
<div class="container mt-5">
<div class="row">
<div class="col-md-12">
<h2>Product List</h2>
<a routerLink="/add-product" class="btn btn-primary mb-3">Add Product</a>
<table class="table table-striped">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Price</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let product of products">
<td>{{ product.id }}</td>
<td>{{ product.name }}</td>
<td>{{ product.price }}</td>
<td>
<a [routerLink]="['/edit-product', product.id]" class="btn btn-info btn-sm">Edit</a>
<button (click)="deleteProduct(product.id)" class="btn btn-danger btn-
sm">Delete</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
Edit product-form.component.ts:
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { ProductService } from '../../services/product.service';
@Component({
selector: 'app-product-form',
templateUrl: './product-form.component.html',
styleUrls: ['./product-form.component.css']
})
export class ProductFormComponent implements OnInit {
product: any = { name: '', price: 0 };
isEditMode: boolean = false;
constructor(private productService: ProductService, private route: ActivatedRoute, private
router: Router) { }
ngOnInit(): void {
const id = this.route.snapshot.paramMap.get('id');
if (id) {
this.isEditMode = true;
this.productService.getProductById(Number(id)).subscribe(data => {
this.product = data;
});
}
}
saveProduct() {
if (this.isEditMode) {
this.productService.updateProduct(this.product.id, this.product).subscribe(() => {
this.router.navigate(['/products']);
});
} else {
this.productService.createProduct(this.product).subscribe(() => {
this.router.navigate(['/products']);
});
}
}
}
Edit product-form.component.html:
<div class="container mt-5">
<div class="row justify-content-center">
<div class="col-md-6">
<div class="card">
<div class="card-header">
<h2>{{ isEditMode ? 'Edit Product' : 'Add Product' }}</h2>
</div>
<div class="card-body">
<form (ngSubmit)="saveProduct()">
<div class="form-group">
<label for="name">Name</label>
<input type="text" id="name" class="form-control" [(ngModel)]="product.name"
name="name" required>
</div>
<div class="form-group">
<label for="price">Price</label>
<input type="number" id="price" class="form-control" [(ngModel)]="product.price"
name="price" required>
</div>
<button type="submit" class="btn btn-primary">{{ isEditMode ? 'Update' : 'Save'
}}</button>
<a routerLink="/products" class="btn btn-secondary ml-2">Cancel</a>
</form>
</div>
</div>
</div>
</div>
</div>
2.4 Update Angular Routing
Edit app-routing.module.ts:
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { ProductListComponent } from './components/product-list/product-list.component';
import { ProductFormComponent } from './components/product-form/product-
form.component';
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
Explanation:
• Defines routes for the product list and product form components.
• Redirects the root path to the product list component.
2.5 Update Angular App Module
Edit app.module.ts:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';