[JAVA-15353] Update code for GraphQL vs REST article (#12849)

This commit is contained in:
Haroon Khan
2022-10-12 16:38:39 +01:00
committed by GitHub
parent 13960eaadb
commit b622c42414
23 changed files with 182 additions and 254 deletions

View File

@@ -0,0 +1,21 @@
package com.baeldung.graphqlvsrest;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
@SpringBootApplication
@EnableAutoConfiguration(exclude = {
SecurityAutoConfiguration.class,
HibernateJpaAutoConfiguration.class
})
public class GraphqlVsRestApplication {
public static void main(String[] args) {
System.setProperty("spring.profiles.default", "rest-vs-graphql");
SpringApplication.run(GraphqlVsRestApplication.class, args);
}
}

View File

@@ -0,0 +1,8 @@
package com.baeldung.graphqlvsrest.configuration;
import org.springframework.context.annotation.Configuration;
@Configuration
public class GraphqlConfiguration {
}

View File

@@ -0,0 +1,24 @@
package com.baeldung.graphqlvsrest.controller;
import com.baeldung.graphqlvsrest.entity.Order;
import com.baeldung.graphqlvsrest.repository.OrderRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("order")
public class OrderController {
@Autowired
OrderRepository orderRepository;
@GetMapping()
public List<Order> getOrders(@RequestParam("product-id") Integer productId){
return orderRepository.getOrdersByProduct(productId);
}
}

View File

@@ -0,0 +1,44 @@
package com.baeldung.graphqlvsrest.controller;
import com.baeldung.graphqlvsrest.entity.Product;
import com.baeldung.graphqlvsrest.model.ProductModel;
import com.baeldung.graphqlvsrest.repository.ProductRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("product")
public class ProductController {
@Autowired
ProductRepository productRepository;
@GetMapping
public List<Product> getProducts(Pageable pageable) {
return productRepository.getProducts(pageable.getPageSize(), pageable.getPageNumber());
}
@GetMapping("/{product-id}")
public Product getProduct(@PathVariable("product-id") Integer productId) {
return productRepository.getProduct(productId);
}
@PostMapping
public Product save(@RequestBody ProductModel productModel) {
return productRepository.save(productModel);
}
@PutMapping("/{product-id}")
public Product update(@PathVariable("product-id") Integer productId, @RequestBody ProductModel productModel) {
return productRepository.update(productId, productModel);
}
}

View File

@@ -0,0 +1,51 @@
package com.baeldung.graphqlvsrest.controller;
import com.baeldung.graphqlvsrest.entity.Order;
import com.baeldung.graphqlvsrest.entity.Product;
import com.baeldung.graphqlvsrest.model.ProductModel;
import com.baeldung.graphqlvsrest.repository.OrderRepository;
import com.baeldung.graphqlvsrest.repository.ProductRepository;
import org.springframework.graphql.data.method.annotation.Argument;
import org.springframework.graphql.data.method.annotation.MutationMapping;
import org.springframework.graphql.data.method.annotation.QueryMapping;
import org.springframework.graphql.data.method.annotation.SchemaMapping;
import org.springframework.stereotype.Controller;
import java.util.List;
@Controller
public class ProductGraphQLController {
private final ProductRepository productRepository;
private final OrderRepository orderRepository;
public ProductGraphQLController(ProductRepository productRepository, OrderRepository orderRepository) {
this.productRepository = productRepository;
this.orderRepository = orderRepository;
}
@QueryMapping
public List<Product> products(@Argument int size, @Argument int page) {
return productRepository.getProducts(size, page);
}
@QueryMapping
public Product product(@Argument int id) {
return productRepository.getProduct(id);
}
@MutationMapping
public Product saveProduct(@Argument ProductModel product) {
return productRepository.save(product);
}
@MutationMapping
public Product updateProduct(@Argument Integer id, @Argument ProductModel product) {
return productRepository.update(id, product);
}
@SchemaMapping(typeName="Product", field="orders")
public List<Order> getOrders(Product product) {
return orderRepository.getOrdersByProduct(product.getId());
}
}

View File

@@ -0,0 +1,58 @@
package com.baeldung.graphqlvsrest.entity;
public class Order {
private Integer id;
private Integer productId;
private String customerId;
private String status;
private String address;
private String creationDate;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getProductId() {
return productId;
}
public void setProductId(Integer productId) {
this.productId = productId;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getCustomerId() {
return customerId;
}
public void setCustomerId(String customerId) {
this.customerId = customerId;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getCreationDate() {
return creationDate;
}
public void setCreationDate(String creationDate) {
this.creationDate = creationDate;
}
}

View File

@@ -0,0 +1,115 @@
package com.baeldung.graphqlvsrest.entity;
import com.baeldung.graphqlvsrest.model.ProductModel;
import java.util.List;
public class Product {
private Integer id;
private String name;
private String description;
private String status;
private String currency;
private Double price;
private List<String> imageUrls;
private List<String> videoUrls;
private Integer stock;
private Float averageRating;
public Product(Integer id, ProductModel productModel) {
this.id = id;
this.name = productModel.getName();
this.description = productModel.getDescription();
this.currency = productModel.getCurrency();
this.price = productModel.getPrice();
this.stock = productModel.getStock();
this.imageUrls = productModel.getImageUrls();
this.videoUrls = productModel.getVideoUrls();
this.averageRating = 0F;
this.status = productModel.getStatus();
}
public Product(){
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getCurrency() {
return currency;
}
public void setCurrency(String currency) {
this.currency = currency;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
public List<String> getImageUrls() {
return imageUrls;
}
public void setImageUrls(List<String> imageUrls) {
this.imageUrls = imageUrls;
}
public List<String> getVideoUrls() {
return videoUrls;
}
public void setVideoUrls(List<String> videoUrls) {
this.videoUrls = videoUrls;
}
public Integer getStock() {
return stock;
}
public void setStock(Integer stock) {
this.stock = stock;
}
public Float getAverageRating() {
return averageRating;
}
public void setAverageRating(Float averageRating) {
this.averageRating = averageRating;
}
}

View File

@@ -0,0 +1,92 @@
package com.baeldung.graphqlvsrest.model;
import java.util.List;
public class ProductModel {
private String name;
private String description;
private String status;
private String currency;
private Double price;
private List<String> imageUrls;
private List<String> videoUrls;
private Integer stock;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getCurrency() {
return currency;
}
public void setCurrency(String currency) {
this.currency = currency;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
public List<String> getImageUrls() {
return imageUrls;
}
public void setImageUrls(List<String> imageUrls) {
this.imageUrls = imageUrls;
}
public List<String> getVideoUrls() {
return videoUrls;
}
public void setVideoUrls(List<String> videoUrls) {
this.videoUrls = videoUrls;
}
public Integer getStock() {
return stock;
}
public void setStock(Integer stock) {
this.stock = stock;
}
@Override
public String toString() {
return "ProductModel{" +
"name='" + name + '\'' +
", description='" + description + '\'' +
", status='" + status + '\'' +
", currency='" + currency + '\'' +
", price=" + price +
", imageUrls=" + imageUrls +
", videoUrls=" + videoUrls +
", stock=" + stock +
'}';
}
}

View File

@@ -0,0 +1,9 @@
package com.baeldung.graphqlvsrest.repository;
import com.baeldung.graphqlvsrest.entity.Order;
import java.util.List;
public interface OrderRepository {
List<Order> getOrdersByProduct(Integer productId);
}

View File

@@ -0,0 +1,14 @@
package com.baeldung.graphqlvsrest.repository;
import com.baeldung.graphqlvsrest.entity.Product;
import com.baeldung.graphqlvsrest.model.ProductModel;
import java.util.List;
public interface ProductRepository {
List<Product> getProducts(Integer pageSize, Integer pageNumber);
Product getProduct(Integer id);
Product save(ProductModel productModel);
Product update(Integer productId, ProductModel productModel);
}

View File

@@ -0,0 +1,37 @@
package com.baeldung.graphqlvsrest.repository.impl;
import com.baeldung.graphqlvsrest.entity.Order;
import com.baeldung.graphqlvsrest.repository.OrderRepository;
import org.springframework.stereotype.Repository;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
@Repository
public class OrderRepositoryImpl implements OrderRepository {
private static final List<Order> ORDER_LIST = new ArrayList<>();
public OrderRepositoryImpl() {
for (int i = 1; i <= 100; i++) {
Order order = new Order();
order.setId(i);
order.setProductId(i % 10);
order.setAddress(i + " A Street");
order.setCustomerId(UUID.randomUUID().toString());
order.setCreationDate(new Date(System.currentTimeMillis()).toString());
order.setStatus("Delivered");
ORDER_LIST.add(order);
}
}
@Override
public List<Order> getOrdersByProduct(Integer productId) {
return ORDER_LIST.stream()
.filter(order -> order.getProductId().equals(productId))
.collect(Collectors.toList());
}
}

View File

@@ -0,0 +1,81 @@
package com.baeldung.graphqlvsrest.repository.impl;
import com.baeldung.graphqlvsrest.entity.Product;
import com.baeldung.graphqlvsrest.model.ProductModel;
import com.baeldung.graphqlvsrest.repository.ProductRepository;
import org.springframework.stereotype.Repository;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import static java.util.Collections.singletonList;
@Repository
public class ProductRepositoryImpl implements ProductRepository {
private static final List<Product> PRODUCT_LIST = new ArrayList<>();
public ProductRepositoryImpl() {
for (int i = 1; i <= 10; i++) {
Product product = new Product();
product.setId(i);
product.setName(String.format("Product %d", i));
product.setDescription(String.format("Product %d description", i));
product.setCurrency(String.format("Product %d currency", i));
product.setPrice((double) (i ^ 2));
product.setStock(10);
product.setAverageRating(0F);
product.setImageUrls(singletonList(String.format("www.baeldung.com/imageurl/%d", i)));
product.setVideoUrls(singletonList(String.format("www.baeldung.com/videourl/%d", i)));
PRODUCT_LIST.add(product);
}
}
@Override
public List<Product> getProducts(Integer pageSize, Integer pageNumber) {
return PRODUCT_LIST.stream()
.skip((long) pageSize * pageNumber)
.limit(pageSize)
.collect(Collectors.toList());
}
@Override
public Product getProduct(Integer id) {
return PRODUCT_LIST.stream()
.filter(product -> product.getId().equals(id))
.findFirst().orElse(null);
}
@Override
public Product save(ProductModel productModel) {
Product product = new Product(PRODUCT_LIST.size() + 1, productModel);
PRODUCT_LIST.add(product);
return product;
}
@Override
public Product update(Integer productId, ProductModel productModel) {
Product product = getProduct(productId);
if (product != null) {
update(product, productModel);
}
return product;
}
private void update(Product product, ProductModel productModel) {
if (productModel != null) {
System.out.println(productModel);
Optional.ofNullable(productModel.getName()).ifPresent(product::setName);
Optional.ofNullable(productModel.getDescription()).ifPresent(product::setDescription);
Optional.ofNullable(productModel.getCurrency()).ifPresent(product::setCurrency);
Optional.ofNullable(productModel.getImageUrls()).ifPresent(product::setImageUrls);
Optional.ofNullable(productModel.getStock()).ifPresent(product::setStock);
Optional.ofNullable(productModel.getStatus()).ifPresent(product::setStatus);
Optional.ofNullable(productModel.getVideoUrls()).ifPresent(product::setVideoUrls);
Optional.ofNullable(productModel.getPrice()).ifPresent(product::setPrice);
}
}
}

View File

@@ -0,0 +1,11 @@
server:
port: 8081
spring:
graphql:
schema:
locations: classpath:graphql-vs-rest/
jackson:
parser:
allow-unquoted-control-chars: true

View File

@@ -0,0 +1,57 @@
type Product {
id: ID
name: String!
description: String
status: String
currency: String!
price: Float
imageUrls: [String]
videoUrls: [String]
stock: Int
averageRating: Float
orders:[Order]
}
type Order{
id:ID
productId:Int
customerId:String
address:String
status:String
creationDate:String
}
input ProductModel {
name: String!
description: String
status: String
currency: String!
price: Float
imageUrls: [String]
videoUrls: [String]
stock: Int
}
input ProductUpdateModel {
name: String
description: String
status: String
currency: String
price: Float
imageUrls: [String]
videoUrls: [String]
stock: Int
}
# The Root Query for the application
type Query {
products(size: Int, page: Int): [Product]!
product(id: Int): Product!
}
# The Root Mutation for the application
type Mutation {
saveProduct(product: ProductModel) : Product!
updateProduct(id: Int, product: ProductUpdateModel) : Product!
}