From 8f90eef5d4c16c88e659109fe877292cdb525cf9 Mon Sep 17 00:00:00 2001 From: Florian THIERRY Date: Thu, 18 Sep 2025 17:31:37 +0200 Subject: [PATCH] Add item endpoints into virtual threads app. --- .../domain/item/ItemService.java | 25 ++++++++++++ .../domain/item/model/Item.java | 22 +++++++++++ .../domain/item/port/ItemPort.java | 11 ++++++ .../exposition/item/ItemController.java | 34 ++++++++++++++++ .../item/model/CreateItemRequest.java | 3 ++ .../exposition/item/model/ItemDto.java | 15 +++++++ .../infrastructure/item/ItemJpaAdapter.java | 32 +++++++++++++++ .../item/model/ItemJpaEntity.java | 39 +++++++++++++++++++ .../item/repository/ItemJpaRepository.java | 10 +++++ 9 files changed, 191 insertions(+) create mode 100644 virtual-threads-app/src/main/java/com/zeenea/experiments/virtualthreads/virtualthreadsapp/domain/item/ItemService.java create mode 100644 virtual-threads-app/src/main/java/com/zeenea/experiments/virtualthreads/virtualthreadsapp/domain/item/model/Item.java create mode 100644 virtual-threads-app/src/main/java/com/zeenea/experiments/virtualthreads/virtualthreadsapp/domain/item/port/ItemPort.java create mode 100644 virtual-threads-app/src/main/java/com/zeenea/experiments/virtualthreads/virtualthreadsapp/exposition/item/ItemController.java create mode 100644 virtual-threads-app/src/main/java/com/zeenea/experiments/virtualthreads/virtualthreadsapp/exposition/item/model/CreateItemRequest.java create mode 100644 virtual-threads-app/src/main/java/com/zeenea/experiments/virtualthreads/virtualthreadsapp/exposition/item/model/ItemDto.java create mode 100644 virtual-threads-app/src/main/java/com/zeenea/experiments/virtualthreads/virtualthreadsapp/infrastructure/item/ItemJpaAdapter.java create mode 100644 virtual-threads-app/src/main/java/com/zeenea/experiments/virtualthreads/virtualthreadsapp/infrastructure/item/model/ItemJpaEntity.java create mode 100644 virtual-threads-app/src/main/java/com/zeenea/experiments/virtualthreads/virtualthreadsapp/infrastructure/item/repository/ItemJpaRepository.java diff --git a/virtual-threads-app/src/main/java/com/zeenea/experiments/virtualthreads/virtualthreadsapp/domain/item/ItemService.java b/virtual-threads-app/src/main/java/com/zeenea/experiments/virtualthreads/virtualthreadsapp/domain/item/ItemService.java new file mode 100644 index 0000000..f1873c9 --- /dev/null +++ b/virtual-threads-app/src/main/java/com/zeenea/experiments/virtualthreads/virtualthreadsapp/domain/item/ItemService.java @@ -0,0 +1,25 @@ +package com.zeenea.experiments.virtualthreads.virtualthreadsapp.domain.item; + +import com.zeenea.experiments.virtualthreads.virtualthreadsapp.domain.item.model.Item; +import com.zeenea.experiments.virtualthreads.virtualthreadsapp.domain.item.port.ItemPort; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public class ItemService { + private final ItemPort itemPort; + + public ItemService(ItemPort itemPort) { + this.itemPort = itemPort; + } + + public List getAllItems() { + return itemPort.getAll(); + } + + public void create(String name, Boolean shared) { + Item newItem = new Item(name, shared); + itemPort.save(newItem); + } +} diff --git a/virtual-threads-app/src/main/java/com/zeenea/experiments/virtualthreads/virtualthreadsapp/domain/item/model/Item.java b/virtual-threads-app/src/main/java/com/zeenea/experiments/virtualthreads/virtualthreadsapp/domain/item/model/Item.java new file mode 100644 index 0000000..43588c2 --- /dev/null +++ b/virtual-threads-app/src/main/java/com/zeenea/experiments/virtualthreads/virtualthreadsapp/domain/item/model/Item.java @@ -0,0 +1,22 @@ +package com.zeenea.experiments.virtualthreads.virtualthreadsapp.domain.item.model; + +import java.time.ZonedDateTime; +import java.util.UUID; + +public record Item( + UUID id, + String name, + ZonedDateTime sharedDate +) { + public Item(String name, Boolean shared) { + this( + UUID.randomUUID(), + name, + shared ? ZonedDateTime.now() : null + ); + } + + public boolean isShared() { + return sharedDate != null; + } +} diff --git a/virtual-threads-app/src/main/java/com/zeenea/experiments/virtualthreads/virtualthreadsapp/domain/item/port/ItemPort.java b/virtual-threads-app/src/main/java/com/zeenea/experiments/virtualthreads/virtualthreadsapp/domain/item/port/ItemPort.java new file mode 100644 index 0000000..69d23f2 --- /dev/null +++ b/virtual-threads-app/src/main/java/com/zeenea/experiments/virtualthreads/virtualthreadsapp/domain/item/port/ItemPort.java @@ -0,0 +1,11 @@ +package com.zeenea.experiments.virtualthreads.virtualthreadsapp.domain.item.port; + + +import com.zeenea.experiments.virtualthreads.virtualthreadsapp.domain.item.model.Item; + +import java.util.List; + +public interface ItemPort { + List getAll(); + void save(Item newItem); +} diff --git a/virtual-threads-app/src/main/java/com/zeenea/experiments/virtualthreads/virtualthreadsapp/exposition/item/ItemController.java b/virtual-threads-app/src/main/java/com/zeenea/experiments/virtualthreads/virtualthreadsapp/exposition/item/ItemController.java new file mode 100644 index 0000000..c39286f --- /dev/null +++ b/virtual-threads-app/src/main/java/com/zeenea/experiments/virtualthreads/virtualthreadsapp/exposition/item/ItemController.java @@ -0,0 +1,34 @@ +package com.zeenea.experiments.virtualthreads.virtualthreadsapp.exposition.item; + +import com.zeenea.experiments.virtualthreads.virtualthreadsapp.domain.item.ItemService; +import com.zeenea.experiments.virtualthreads.virtualthreadsapp.exposition.item.model.CreateItemRequest; +import com.zeenea.experiments.virtualthreads.virtualthreadsapp.exposition.item.model.ItemDto; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +import static org.springframework.http.HttpStatus.CREATED; + +@RestController +@RequestMapping("/api/items") +public class ItemController { + private final ItemService itemService; + + public ItemController(ItemService itemService) { + this.itemService = itemService; + } + + @PostMapping + @ResponseStatus(CREATED) + public void createAnItem(@RequestBody CreateItemRequest request) { + itemService.create(request.name(), request.isShared()); + } + + @GetMapping + public List getAll() { + return itemService.getAllItems() + .stream() + .map(ItemDto::new) + .toList(); + } +} diff --git a/virtual-threads-app/src/main/java/com/zeenea/experiments/virtualthreads/virtualthreadsapp/exposition/item/model/CreateItemRequest.java b/virtual-threads-app/src/main/java/com/zeenea/experiments/virtualthreads/virtualthreadsapp/exposition/item/model/CreateItemRequest.java new file mode 100644 index 0000000..7ec7e72 --- /dev/null +++ b/virtual-threads-app/src/main/java/com/zeenea/experiments/virtualthreads/virtualthreadsapp/exposition/item/model/CreateItemRequest.java @@ -0,0 +1,3 @@ +package com.zeenea.experiments.virtualthreads.virtualthreadsapp.exposition.item.model; + +public record CreateItemRequest(String name, Boolean isShared) {} diff --git a/virtual-threads-app/src/main/java/com/zeenea/experiments/virtualthreads/virtualthreadsapp/exposition/item/model/ItemDto.java b/virtual-threads-app/src/main/java/com/zeenea/experiments/virtualthreads/virtualthreadsapp/exposition/item/model/ItemDto.java new file mode 100644 index 0000000..6f968ab --- /dev/null +++ b/virtual-threads-app/src/main/java/com/zeenea/experiments/virtualthreads/virtualthreadsapp/exposition/item/model/ItemDto.java @@ -0,0 +1,15 @@ +package com.zeenea.experiments.virtualthreads.virtualthreadsapp.exposition.item.model; + +import com.zeenea.experiments.virtualthreads.virtualthreadsapp.domain.item.model.Item; + +import java.util.UUID; + +public record ItemDto( + UUID id, + String name, + Boolean isShared +) { + public ItemDto(Item item) { + this(item.id(), item.name(), item.isShared()); + } +} diff --git a/virtual-threads-app/src/main/java/com/zeenea/experiments/virtualthreads/virtualthreadsapp/infrastructure/item/ItemJpaAdapter.java b/virtual-threads-app/src/main/java/com/zeenea/experiments/virtualthreads/virtualthreadsapp/infrastructure/item/ItemJpaAdapter.java new file mode 100644 index 0000000..453211c --- /dev/null +++ b/virtual-threads-app/src/main/java/com/zeenea/experiments/virtualthreads/virtualthreadsapp/infrastructure/item/ItemJpaAdapter.java @@ -0,0 +1,32 @@ +package com.zeenea.experiments.virtualthreads.virtualthreadsapp.infrastructure.item; + +import com.zeenea.experiments.virtualthreads.virtualthreadsapp.domain.item.model.Item; +import com.zeenea.experiments.virtualthreads.virtualthreadsapp.domain.item.port.ItemPort; +import com.zeenea.experiments.virtualthreads.virtualthreadsapp.infrastructure.item.model.ItemJpaEntity; +import com.zeenea.experiments.virtualthreads.virtualthreadsapp.infrastructure.item.repository.ItemJpaRepository; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component +public class ItemJpaAdapter implements ItemPort { + private final ItemJpaRepository itemJpaRepository; + + public ItemJpaAdapter(ItemJpaRepository itemJpaRepository) { + this.itemJpaRepository = itemJpaRepository; + } + + @Override + public List getAll() { + return itemJpaRepository.findAll() + .stream() + .map(ItemJpaEntity::toDomain) + .toList(); + } + + @Override + public void save(Item newItem) { + ItemJpaEntity newItemJpaEntity = new ItemJpaEntity(newItem); + itemJpaRepository.save(newItemJpaEntity); + } +} diff --git a/virtual-threads-app/src/main/java/com/zeenea/experiments/virtualthreads/virtualthreadsapp/infrastructure/item/model/ItemJpaEntity.java b/virtual-threads-app/src/main/java/com/zeenea/experiments/virtualthreads/virtualthreadsapp/infrastructure/item/model/ItemJpaEntity.java new file mode 100644 index 0000000..0b54354 --- /dev/null +++ b/virtual-threads-app/src/main/java/com/zeenea/experiments/virtualthreads/virtualthreadsapp/infrastructure/item/model/ItemJpaEntity.java @@ -0,0 +1,39 @@ +package com.zeenea.experiments.virtualthreads.virtualthreadsapp.infrastructure.item.model; + +import com.zeenea.experiments.virtualthreads.virtualthreadsapp.domain.item.model.Item; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import java.time.ZonedDateTime; +import java.util.UUID; + +@Entity +@Table(name = "item") +@AllArgsConstructor +@NoArgsConstructor +@Getter +@Setter +public class ItemJpaEntity { + @Id + private UUID id; + @Column(nullable = false) + private String name; + @Column + private ZonedDateTime sharedDate; + + public ItemJpaEntity(Item item) { + id = item.id(); + name = item.name(); + sharedDate = item.sharedDate(); + } + + public Item toDomain() { + return new Item(id, name, sharedDate); + } +} diff --git a/virtual-threads-app/src/main/java/com/zeenea/experiments/virtualthreads/virtualthreadsapp/infrastructure/item/repository/ItemJpaRepository.java b/virtual-threads-app/src/main/java/com/zeenea/experiments/virtualthreads/virtualthreadsapp/infrastructure/item/repository/ItemJpaRepository.java new file mode 100644 index 0000000..7f5c646 --- /dev/null +++ b/virtual-threads-app/src/main/java/com/zeenea/experiments/virtualthreads/virtualthreadsapp/infrastructure/item/repository/ItemJpaRepository.java @@ -0,0 +1,10 @@ +package com.zeenea.experiments.virtualthreads.virtualthreadsapp.infrastructure.item.repository; + +import com.zeenea.experiments.virtualthreads.virtualthreadsapp.infrastructure.item.model.ItemJpaEntity; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.UUID; + +@Repository +public interface ItemJpaRepository extends JpaRepository {}