[JAVA-15353] Update code for GraphQL vs REST article (#12849)
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.baeldung.graphqlvsrest.configuration;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
public class GraphqlConfiguration {
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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 +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
server:
|
||||
port: 8081
|
||||
|
||||
spring:
|
||||
graphql:
|
||||
schema:
|
||||
locations: classpath:graphql-vs-rest/
|
||||
|
||||
jackson:
|
||||
parser:
|
||||
allow-unquoted-control-chars: true
|
||||
@@ -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!
|
||||
}
|
||||
Reference in New Issue
Block a user