refactor: Streamlined the API of the services
[demos/kafka/chat] / src / main / java / de / juplo / kafka / chat / backend / api / ChatBackendController.java
1 package de.juplo.kafka.chat.backend.api;
2
3 import de.juplo.kafka.chat.backend.domain.ChatHome;
4 import de.juplo.kafka.chat.backend.domain.ChatRoom;
5 import de.juplo.kafka.chat.backend.persistence.StorageStrategy;
6 import lombok.RequiredArgsConstructor;
7 import org.springframework.http.codec.ServerSentEvent;
8 import org.springframework.web.bind.annotation.*;
9 import reactor.core.publisher.Flux;
10 import reactor.core.publisher.Mono;
11
12 import java.util.UUID;
13
14
15 @RestController
16 @RequiredArgsConstructor
17 public class ChatBackendController
18 {
19   private final ChatHome chatHome;
20   private final StorageStrategy storageStrategy;
21
22
23   @PostMapping("create")
24   public Mono<ChatRoomTo> create(@RequestBody String name)
25   {
26     return chatHome.createChatroom(name).map(ChatRoomTo::from);
27   }
28
29   @GetMapping("list")
30   public Flux<ChatRoomTo> list()
31   {
32     return chatHome.list().map(chatroom -> ChatRoomTo.from(chatroom));
33   }
34
35   @GetMapping("list/{chatroomId}")
36   public Flux<MessageTo> list(@PathVariable UUID chatroomId)
37   {
38     return chatHome
39         .getChatroom(chatroomId)
40         .flatMapMany(chatroom -> chatroom
41             .getMessages()
42             .map(MessageTo::from));
43   }
44
45   @GetMapping("get/{chatroomId}")
46   public Mono<ChatRoomTo> get(@PathVariable UUID chatroomId)
47   {
48     return chatHome.getChatroom(chatroomId).map(chatroom -> ChatRoomTo.from(chatroom));
49   }
50
51   @PutMapping("put/{chatroomId}/{username}/{messageId}")
52   public Mono<MessageTo> put(
53       @PathVariable UUID chatroomId,
54       @PathVariable String username,
55       @PathVariable Long messageId,
56       @RequestBody String text)
57   {
58     return
59         chatHome
60             .getChatroom(chatroomId)
61             .flatMap(chatroom -> put(chatroom, username, messageId, text));
62   }
63
64   public Mono<MessageTo> put(
65       ChatRoom chatroom,
66       String username,
67       Long messageId,
68       String text)
69   {
70     return
71         chatroom
72             .addMessage(
73                 messageId,
74                 username,
75                 text)
76             .switchIfEmpty(chatroom.getMessage(username, messageId))
77             .map(message -> MessageTo.from(message));
78   }
79
80   @GetMapping("get/{chatroomId}/{username}/{messageId}")
81   public Mono<MessageTo> get(
82       @PathVariable UUID chatroomId,
83       @PathVariable String username,
84       @PathVariable Long messageId)
85   {
86     return
87         chatHome
88             .getChatroom(chatroomId)
89             .flatMap(chatroom -> get(chatroom, username, messageId));
90   }
91
92   private Mono<MessageTo> get(
93       ChatRoom chatroom,
94       String username,
95       Long messageId)
96   {
97     return
98         chatroom
99             .getMessage(username, messageId)
100             .map(message -> MessageTo.from(message));
101   }
102
103   @GetMapping(path = "listen/{chatroomId}")
104   public Flux<ServerSentEvent<MessageTo>> listen(@PathVariable UUID chatroomId)
105   {
106     return chatHome
107         .getChatroom(chatroomId)
108         .flatMapMany(chatroom -> listen(chatroom));
109   }
110
111   private Flux<ServerSentEvent<MessageTo>> listen(ChatRoom chatroom)
112   {
113     return chatroom
114         .listen()
115         .log()
116         .map(message -> MessageTo.from(message))
117         .map(messageTo ->
118             ServerSentEvent
119                 .builder(messageTo)
120                 .id(messageTo.getSerial().toString())
121                 .event("message")
122                 .build());
123   }
124
125   @PostMapping("/store")
126   public void store()
127   {
128     storageStrategy.writeChatrooms(chatHome.list());
129   }
130 }