Ich will gerade eine Web Anwendung schreiben – und wollte dazu zuerst noch euren Rat einholen.
Es ist eine REST Anwendung die eigentlich nur Daten aus einer Datenbank zur Verfügung stellt (Read only).
Das Problem ist, dass die Datenbank-Struktur schon vorgegeben ist (und das blöd – aber daran kann ich nichts ändern):
Entries
- ENTRY_ID
- USER
- IP
- DATETIME
- CATEGORY (ENUM)
- CATEGORY-SUB (ENUM)
- DESCRIPTION
In der Datenbank ist es so aufgeteilt (Unnötig aber nicht änderbar!):
SQL Table: ENTRIES_PART_1
- ENTRY_ID
- DATETIME
- CATEGORY (ENUM)
- IP
SQL Table: ENTRIES_PART_2
- ENTRY_ID
- USER
- CATEGORY-SUB (ENUM)
- DESCRIPTION
Folgende Rest-Endpoints solls geben:
/entries --> Einträge können abgerufen werden - mit Filterung (auf alles außer Description) & Paging.
/info -> so Sachen wie summen für diverse Kategorien heraus holen (wie oft in einem Zeitfenster eine Kategorie, …)
Eigentlich denke ich das das Ganze sehr einfach aufgebaut werden könnte, nachdem ich mir (u.a.) folgenden zwei Spring Guids angesehen habe:
https://spring.io/guides/gs/actuator-service/
https://spring.io/guides/gs/relational-data-access/
Sprich ich brauche eigentlich nur (mit Spring Boot):
Einen RestController (Class mit @Controller) der die Endpoints definiert.
Eine EntryJsonObj Klasse als Respone represenation (der dan auf JSON gemappt wird bei der Response)
Eine InfoJsonObj Klasse als Respone represenation (der dan auf JSON gemappt wird bei der Response) -> da muss ich noch überlegen, sollte aber auch einfach sein
Eine DBAccess Klasse die mit JDBCTemplate die Daten aus der Datenbank holt - die wird in den RestController Injected damit dieser die Daten abholen kann. Darin wird mit dem JDBC template einfach aus beiden Tabellen gejoined und fertig (eine Abfrage für das entries filtern/pagen + eine Abfrage für die anderen (da ggf mehr)).
Eine EntryDbObj Klasse als Transfer Object Zwischen DB und REST Controler dient für die Entries. (wird auf EntryJsonObj gemapped)
Eine InfoDbObj Klasse als Transfer Object Zwischen DB und REST Controler dient für die Info Response. (wird auf InfoJsonObj gemapped)
Dazu jetzt folgende Fragen:
1) Übersehe ich dabei etwas?
2) Mir kommt es recht einfach vor, eigentlich muss ich beim RestConroller nur alle Parameter an die DBAccess weitergeben, damit die auf der DB den Query absetzt und wieder zurück geben kann.
Eigentlich könnte man sich ja DBAccess und EntryDbObj sparen, aber von wegen Seperation of Concerns ...
Oder müsste/sollte ich da die Klassen weiter aufsplitten?
3) Wie sieht es mit dem Mapping von EntryDbObj auf EntryJsonObj aus, das könnte doch sicher auch irgendwie automatisiert oder vereinfacht werden?
4) Als ich begonnen habe und mir nch keine Überlegung gemacht habe wie ich die daten aus der DB holen kann, wollte ich im RestContoler mit Streams arbeiten ...
weil man damit sehr schön elegant und einfach alles erledigen kann:
Paging mit skip() und limit()
Filtering mit mit filter(e -> e.isCategory(X))
kann man das auch irgendwie auf die DBAccess anwenden - so das die einen Stream liefert?
(weil alles aus der DB holen geht ja wegen der Menge der Entries nicht (mehrere Millionen))
Sonst geht nur Paramter and DB durchschleifen ... oder gibt es alternativen
5) Zur Architektur - gibt es was was man verbessern ändern sollte?
Ich versuche mich gerade mit Architektur zu befassen, erkenne aber bei der Anwendung nicht die verschiedenen Schichten / Module
Also sowas wie MVC? Domain/Business Logic?
Oder ist die Anwendung nur einfach zu simpel damit man das nicht sehen/schöner machen kann. Die Entries (als Domain Objects) sind nun mal eigentlich dumme Value objects die nichts können (keine Logic) ....
Es ist eine REST Anwendung die eigentlich nur Daten aus einer Datenbank zur Verfügung stellt (Read only).
Das Problem ist, dass die Datenbank-Struktur schon vorgegeben ist (und das blöd – aber daran kann ich nichts ändern):
Entries
- ENTRY_ID
- USER
- IP
- DATETIME
- CATEGORY (ENUM)
- CATEGORY-SUB (ENUM)
- DESCRIPTION
In der Datenbank ist es so aufgeteilt (Unnötig aber nicht änderbar!):
SQL Table: ENTRIES_PART_1
- ENTRY_ID
- DATETIME
- CATEGORY (ENUM)
- IP
SQL Table: ENTRIES_PART_2
- ENTRY_ID
- USER
- CATEGORY-SUB (ENUM)
- DESCRIPTION
Folgende Rest-Endpoints solls geben:
/entries --> Einträge können abgerufen werden - mit Filterung (auf alles außer Description) & Paging.
/info -> so Sachen wie summen für diverse Kategorien heraus holen (wie oft in einem Zeitfenster eine Kategorie, …)
Eigentlich denke ich das das Ganze sehr einfach aufgebaut werden könnte, nachdem ich mir (u.a.) folgenden zwei Spring Guids angesehen habe:
https://spring.io/guides/gs/actuator-service/
https://spring.io/guides/gs/relational-data-access/
Sprich ich brauche eigentlich nur (mit Spring Boot):
Einen RestController (Class mit @Controller) der die Endpoints definiert.
Eine EntryJsonObj Klasse als Respone represenation (der dan auf JSON gemappt wird bei der Response)
Eine InfoJsonObj Klasse als Respone represenation (der dan auf JSON gemappt wird bei der Response) -> da muss ich noch überlegen, sollte aber auch einfach sein
Eine DBAccess Klasse die mit JDBCTemplate die Daten aus der Datenbank holt - die wird in den RestController Injected damit dieser die Daten abholen kann. Darin wird mit dem JDBC template einfach aus beiden Tabellen gejoined und fertig (eine Abfrage für das entries filtern/pagen + eine Abfrage für die anderen (da ggf mehr)).
Eine EntryDbObj Klasse als Transfer Object Zwischen DB und REST Controler dient für die Entries. (wird auf EntryJsonObj gemapped)
Eine InfoDbObj Klasse als Transfer Object Zwischen DB und REST Controler dient für die Info Response. (wird auf InfoJsonObj gemapped)
Dazu jetzt folgende Fragen:
1) Übersehe ich dabei etwas?
2) Mir kommt es recht einfach vor, eigentlich muss ich beim RestConroller nur alle Parameter an die DBAccess weitergeben, damit die auf der DB den Query absetzt und wieder zurück geben kann.
Eigentlich könnte man sich ja DBAccess und EntryDbObj sparen, aber von wegen Seperation of Concerns ...
Oder müsste/sollte ich da die Klassen weiter aufsplitten?
3) Wie sieht es mit dem Mapping von EntryDbObj auf EntryJsonObj aus, das könnte doch sicher auch irgendwie automatisiert oder vereinfacht werden?
4) Als ich begonnen habe und mir nch keine Überlegung gemacht habe wie ich die daten aus der DB holen kann, wollte ich im RestContoler mit Streams arbeiten ...
weil man damit sehr schön elegant und einfach alles erledigen kann:
Paging mit skip() und limit()
Filtering mit mit filter(e -> e.isCategory(X))
kann man das auch irgendwie auf die DBAccess anwenden - so das die einen Stream liefert?
(weil alles aus der DB holen geht ja wegen der Menge der Entries nicht (mehrere Millionen))
Sonst geht nur Paramter and DB durchschleifen ... oder gibt es alternativen
5) Zur Architektur - gibt es was was man verbessern ändern sollte?
Ich versuche mich gerade mit Architektur zu befassen, erkenne aber bei der Anwendung nicht die verschiedenen Schichten / Module
Also sowas wie MVC? Domain/Business Logic?
Oder ist die Anwendung nur einfach zu simpel damit man das nicht sehen/schöner machen kann. Die Entries (als Domain Objects) sind nun mal eigentlich dumme Value objects die nichts können (keine Logic) ....