From 2b84540dc59910aaa6cb15254c1c890ac66d5c55 Mon Sep 17 00:00:00 2001 From: Lucas Holter Date: Thu, 14 Aug 2025 13:46:44 +0200 Subject: [PATCH 1/4] Add implementation of api --- settings.gradle | 7 ++ .../java/com/booleanuk/api/product/Main.java | 11 ++++ .../controllers/ProductController.java | 65 +++++++++++++++++++ .../booleanuk/api/product/models/Product.java | 45 +++++++++++++ .../repositories/ProductRepository.java | 36 ++++++++++ 5 files changed, 164 insertions(+) create mode 100644 src/main/java/com/booleanuk/api/product/Main.java create mode 100644 src/main/java/com/booleanuk/api/product/controllers/ProductController.java create mode 100644 src/main/java/com/booleanuk/api/product/models/Product.java create mode 100644 src/main/java/com/booleanuk/api/product/repositories/ProductRepository.java diff --git a/settings.gradle b/settings.gradle index 0bc3ae4..55e2ff3 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1,8 @@ +pluginManagement { + repositories { + mavenCentral() + gradlePluginPortal() + } +} + rootProject.name = 'jave.api.mvc.in.memory' diff --git a/src/main/java/com/booleanuk/api/product/Main.java b/src/main/java/com/booleanuk/api/product/Main.java new file mode 100644 index 0000000..bc18173 --- /dev/null +++ b/src/main/java/com/booleanuk/api/product/Main.java @@ -0,0 +1,11 @@ +package com.booleanuk.api.product; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Main { + public static void main(String[] args) { + SpringApplication.run(Main.class, args); + } +} diff --git a/src/main/java/com/booleanuk/api/product/controllers/ProductController.java b/src/main/java/com/booleanuk/api/product/controllers/ProductController.java new file mode 100644 index 0000000..8fe6ef8 --- /dev/null +++ b/src/main/java/com/booleanuk/api/product/controllers/ProductController.java @@ -0,0 +1,65 @@ +package com.booleanuk.api.product.controllers; + +import com.booleanuk.api.product.models.Product; +import com.booleanuk.api.product.repositories.ProductRepository; +import org.springframework.http.HttpStatus; +import org.springframework.http.HttpStatusCode; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.server.ResponseStatusException; + +import java.util.ArrayList; +import java.util.List; + +@RestController +@RequestMapping("products") +public class ProductController { + private ProductRepository productRepository; + + public ProductController() { + this.productRepository = new ProductRepository(new ArrayList<>()); + } + + @GetMapping + public List getAll(){ + return this.productRepository.getAll(); + } + + @GetMapping("{id}") + public Product getById(@PathVariable int id){ + Product prod = this.productRepository.getById(id); + nullCheckForSearch(prod); + return prod; + } + + @PostMapping + @ResponseStatus(HttpStatus.CREATED) + public Product addProduct(@RequestBody Product product){ + this.productRepository.add(product); + return product; + } + + @PutMapping("{id}") + public Product putProduct(@RequestBody Product product, @PathVariable int id){ + Product foundProd = this.productRepository.getById(id); + nullCheckForSearch(foundProd); + foundProd.setName(product.getName()); + foundProd.setCategory(product.getCategory()); + foundProd.setPrice(product.getPrice()); + + return foundProd; + } + + @DeleteMapping("{id}") + public Product deleteProduct(@PathVariable int id){ + Product removed = this.productRepository.removeProduct(id); + nullCheckForSearch(removed); + return removed; + } + + private void nullCheckForSearch(Product product){ + if(product == null){ + throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Product not found."); + } + } + +} diff --git a/src/main/java/com/booleanuk/api/product/models/Product.java b/src/main/java/com/booleanuk/api/product/models/Product.java new file mode 100644 index 0000000..5109547 --- /dev/null +++ b/src/main/java/com/booleanuk/api/product/models/Product.java @@ -0,0 +1,45 @@ +package com.booleanuk.api.product.models; + +public class Product { + private static int nextId; + private String name; + private String category; + private String price; + private int id; + + public Product(String name, String category, String price) { + this.name = name; + this.category = category; + this.price = price; + this.id = nextId; + nextId++; + } + + public String getName() { + return name; + } + + public String getCategory() { + return category; + } + + public String getPrice() { + return price; + } + + public int getId() { + return id; + } + + public void setName(String name) { + this.name = name; + } + + public void setCategory(String category) { + this.category = category; + } + + public void setPrice(String price) { + this.price = price; + } +} diff --git a/src/main/java/com/booleanuk/api/product/repositories/ProductRepository.java b/src/main/java/com/booleanuk/api/product/repositories/ProductRepository.java new file mode 100644 index 0000000..9d5afa4 --- /dev/null +++ b/src/main/java/com/booleanuk/api/product/repositories/ProductRepository.java @@ -0,0 +1,36 @@ +package com.booleanuk.api.product.repositories; + +import com.booleanuk.api.product.models.Product; + +import java.util.List; + +public class ProductRepository { + private List products; + + public ProductRepository(List products) { + this.products = products; + } + + public List getAll(){ + return this.products; + } + + public void add(Product product){ //Void for now, would return db return if connected to db + this.products.add(product); + } + + public Product getById(int id){ + for(Product product : this.products){ + if(product.getId() == id){ + return product; + } + } + return null; + } + + public Product removeProduct(int id){ + Product removeProd = this.getById(id); + this.products.remove(removeProd); + return removeProd; //Return null if not found + } +} From f6329824fc92a0e9af46053c9d64516831c4db80 Mon Sep 17 00:00:00 2001 From: Lucas Holter Date: Thu, 14 Aug 2025 14:17:16 +0200 Subject: [PATCH 2/4] Add extension --- .../controllers/ProductController.java | 28 +++++++++++++------ .../repositories/ProductRepository.java | 12 +++++++- 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/booleanuk/api/product/controllers/ProductController.java b/src/main/java/com/booleanuk/api/product/controllers/ProductController.java index 8fe6ef8..42fa5e0 100644 --- a/src/main/java/com/booleanuk/api/product/controllers/ProductController.java +++ b/src/main/java/com/booleanuk/api/product/controllers/ProductController.java @@ -3,7 +3,6 @@ import com.booleanuk.api.product.models.Product; import com.booleanuk.api.product.repositories.ProductRepository; import org.springframework.http.HttpStatus; -import org.springframework.http.HttpStatusCode; import org.springframework.web.bind.annotation.*; import org.springframework.web.server.ResponseStatusException; @@ -21,27 +20,38 @@ public ProductController() { @GetMapping public List getAll(){ - return this.productRepository.getAll(); + List allProds = this.productRepository.getAll(); + if(allProds.isEmpty()){ + throw new ResponseStatusException(HttpStatus.NOT_FOUND, "No products found"); + } + return allProds; } @GetMapping("{id}") public Product getById(@PathVariable int id){ Product prod = this.productRepository.getById(id); - nullCheckForSearch(prod); + nullCheck(prod, HttpStatus.NOT_FOUND, "Product not found."); return prod; } @PostMapping @ResponseStatus(HttpStatus.CREATED) public Product addProduct(@RequestBody Product product){ - this.productRepository.add(product); - return product; + if(productRepository.checkNameConflict(product)){ + throw new ResponseStatusException(HttpStatus.CONFLICT, "Product with provided name already exists"); + } + return this.productRepository.add(product); } @PutMapping("{id}") public Product putProduct(@RequestBody Product product, @PathVariable int id){ + + if(productRepository.checkNameConflict(product)){ + throw new ResponseStatusException(HttpStatus.CONFLICT, "Product with provided name already exists"); + } + Product foundProd = this.productRepository.getById(id); - nullCheckForSearch(foundProd); + nullCheck(foundProd, HttpStatus.NOT_FOUND, "Product not found."); foundProd.setName(product.getName()); foundProd.setCategory(product.getCategory()); foundProd.setPrice(product.getPrice()); @@ -52,13 +62,13 @@ public Product putProduct(@RequestBody Product product, @PathVariable int id){ @DeleteMapping("{id}") public Product deleteProduct(@PathVariable int id){ Product removed = this.productRepository.removeProduct(id); - nullCheckForSearch(removed); + nullCheck(removed, HttpStatus.NOT_FOUND, "Product not found."); return removed; } - private void nullCheckForSearch(Product product){ + private void nullCheck(Product product, HttpStatus status, String message){ if(product == null){ - throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Product not found."); + throw new ResponseStatusException(status, message); } } diff --git a/src/main/java/com/booleanuk/api/product/repositories/ProductRepository.java b/src/main/java/com/booleanuk/api/product/repositories/ProductRepository.java index 9d5afa4..06dc774 100644 --- a/src/main/java/com/booleanuk/api/product/repositories/ProductRepository.java +++ b/src/main/java/com/booleanuk/api/product/repositories/ProductRepository.java @@ -15,8 +15,18 @@ public List getAll(){ return this.products; } - public void add(Product product){ //Void for now, would return db return if connected to db + public boolean checkNameConflict(Product product){ + for(Product curr : this.products){ + if(curr.getName().equals(product.getName())){ + return true; + } + } + return false; + } + + public Product add(Product product){ //Void for now, would return db return if connected to db this.products.add(product); + return product; } public Product getById(int id){ From 17d52fc00a45850d5ab72c30ba3c2f40b41df9f5 Mon Sep 17 00:00:00 2001 From: Lucas Holter Date: Thu, 14 Aug 2025 14:30:59 +0200 Subject: [PATCH 3/4] Add get products by categories --- .../api/product/controllers/ProductController.java | 10 ++++++++++ .../api/product/repositories/ProductRepository.java | 12 ++++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/main/java/com/booleanuk/api/product/controllers/ProductController.java b/src/main/java/com/booleanuk/api/product/controllers/ProductController.java index 42fa5e0..0d811bd 100644 --- a/src/main/java/com/booleanuk/api/product/controllers/ProductController.java +++ b/src/main/java/com/booleanuk/api/product/controllers/ProductController.java @@ -72,4 +72,14 @@ private void nullCheck(Product product, HttpStatus status, String message){ } } + @GetMapping({"categories/{category}"}) + public List getAllByCategory(@PathVariable String category){ + List prods = this.productRepository.getAllByCategory(category); + + if(prods.isEmpty()){ + throw new ResponseStatusException(HttpStatus.NOT_FOUND); + } + return prods; + } + } diff --git a/src/main/java/com/booleanuk/api/product/repositories/ProductRepository.java b/src/main/java/com/booleanuk/api/product/repositories/ProductRepository.java index 06dc774..5fa0e33 100644 --- a/src/main/java/com/booleanuk/api/product/repositories/ProductRepository.java +++ b/src/main/java/com/booleanuk/api/product/repositories/ProductRepository.java @@ -2,6 +2,7 @@ import com.booleanuk.api.product.models.Product; +import java.util.ArrayList; import java.util.List; public class ProductRepository { @@ -43,4 +44,15 @@ public Product removeProduct(int id){ this.products.remove(removeProd); return removeProd; //Return null if not found } + + public List getAllByCategory(String cat){ + List found = new ArrayList<>(); + for(Product curr : this.products){ + if(cat.equals(curr.getCategory())){ + found.add(curr); + } + } + return found; + + } } From b3b1be27fba2e1e3fe6ef100844ff235a9cfc72d Mon Sep 17 00:00:00 2001 From: Lucas Holter Date: Thu, 14 Aug 2025 14:44:05 +0200 Subject: [PATCH 4/4] Add product specific get as parameter on getAll --- .../controllers/ProductController.java | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/booleanuk/api/product/controllers/ProductController.java b/src/main/java/com/booleanuk/api/product/controllers/ProductController.java index 0d811bd..dc55e87 100644 --- a/src/main/java/com/booleanuk/api/product/controllers/ProductController.java +++ b/src/main/java/com/booleanuk/api/product/controllers/ProductController.java @@ -19,7 +19,15 @@ public ProductController() { } @GetMapping - public List getAll(){ + public List getAll(@RequestParam(defaultValue="") String category){ + if(!category.isEmpty()){ + List filteredProd = this.productRepository.getAllByCategory(category); + if(filteredProd.isEmpty()){ + throw new ResponseStatusException(HttpStatus.NOT_FOUND, "No products with that category found"); + } + return filteredProd; + } + List allProds = this.productRepository.getAll(); if(allProds.isEmpty()){ throw new ResponseStatusException(HttpStatus.NOT_FOUND, "No products found"); @@ -72,14 +80,4 @@ private void nullCheck(Product product, HttpStatus status, String message){ } } - @GetMapping({"categories/{category}"}) - public List getAllByCategory(@PathVariable String category){ - List prods = this.productRepository.getAllByCategory(category); - - if(prods.isEmpty()){ - throw new ResponseStatusException(HttpStatus.NOT_FOUND); - } - return prods; - } - }