Spring REST Application (Data Retrive) API und Architectur hilfe

LokiA

Mitglied
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) ....
 

mihe7

Top Contributor
Eigentlich denke ich das das Ganze sehr einfach aufgebaut werden könnte
Richtig. Hier geht es um eine simple Query. Das Ergebnis sind keine Objekte (weder Value Objects noch Domain Objects), sondern schlicht Daten. Diese sollen zu JSON transformiert werden und das war es auch schon. Dafür muss man keine zig Klassen schreiben.

aber von wegen Seperation of Concerns ...
Welche Concerns siehst Du denn?
 

LokiA

Mitglied
Danke, für die Antwort.

Richtig. Hier geht es um eine simple Query. Das Ergebnis sind keine Objekte (weder Value Objects noch Domain Objects), sondern schlicht Daten. Diese sollen zu JSON transformiert werden und das war es auch schon. Dafür muss man keine zig Klassen schreiben.
Meinst du damit, dass die von mir erwähnten Klassen schion zu viel wären?
Oder wie macht man den das eben erwähnte mapping am elegantesten?


Welche Concerns siehst Du denn?
Naja zumindest:
- das handlen der der REST requests
- Zugriff auf die DB
- das mapping dazwischen
- ggf Brechung für den INFO endpoint (ob das wirklich was eigenes wäre muss ich mir noch ansehen)
BZW wie würdest du sonst den Durchgriff auf die Daten in der DB machen?
 

Thallius

Top Contributor
Im Prinzip brauchst du ja gar keine Klassen. Du weist ja auch gar nicht welche Klassen der Benutzer des Services erwartet. Also wirst Du die Daten aus der DB einfach in ein JSON Object packen und zurück geben. Um alles andere muss sich die Software kümmern die den REST Service benutzt.
 

mihe7

Top Contributor
@Thallius hat es sehr schön auf den Punkt gebracht.

Es geht doch einfach darum, eine SQL-Abfrage zu stellen und das Ergebnis als JSON formatiert auszugeben. Da gibt es weder ein Domain Model, noch gibt es Entity-Klassen. Im Extremfall (das ist keine Empfehlung) könntest Du alles in Deiner Service-Klasse erledigen.

Prinzipien/Patterns sind nicht dazu da, sie blind einzusetzen. Ein "Hello World" teilst Du doch auch nicht so auf: HelloWorldView, HelloWorldModel und natürlich HelloWorldController. Dann natürlich einen Greeter für die Business Logic und eine Domain-Klasse für den Namen, lass mal überlegen, ach ja ein Value Object. Noch ein paar Interfaces (design by contract) und ein DI-Framework und schon ist das System.out.println("Hello " + name); fertig.
 

mrBrown

Super-Moderator
Mitarbeiter
Prinzipien/Patterns sind nicht dazu da, sie blind einzusetzen. Ein "Hello World" teilst Du doch auch nicht so auf: HelloWorldView, HelloWorldModel und natürlich HelloWorldController. Dann natürlich einen Greeter für die Business Logic und eine Domain-Klasse für den Namen, lass mal überlegen, ach ja ein Value Object. Noch ein paar Interfaces (design by contract) und ein DI-Framework und schon ist das System.out.println("Hello " + name); fertig.
https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpriseEdition :cool:
 

LokiA

Mitglied
Also auf Klassen zu verzichten halte ich wohl für ziemlich übertrieben - Seperation of Concerns / SRP gilt ja wohl auch hier. Daher finde ich eure aussagen wohl wissend, dass es klare Übertreibungen sind nicht richtig.
Da ich aber dennoch euren Rat als immer wieder le[h/e]rreich empfinde wollte ich nochmal nach-harken - wir würdet ihr sonst das mapping DB-Object JSON-Response-Object machen?
Manuell oder anders?
 

Thallius

Top Contributor
Also auf Klassen zu verzichten halte ich wohl für ziemlich übertrieben - Seperation of Concerns / SRP gilt ja wohl auch hier. Daher finde ich eure aussagen wohl wissend, dass es klare Übertreibungen sind nicht richtig.
Da ich aber dennoch euren Rat als immer wieder le[h/e]rreich empfinde wollte ich nochmal nach-harken - wir würdet ihr sonst das mapping DB-Object JSON-Response-Object machen?
Manuell oder anders?

Immer noch:

Gar nicht! Was für ein Java Objekt willst du denn erstellen wenn du es eh wieder in ein JSON object zerlegst? Das ist einfach nur sinnlos.
 

mihe7

Top Contributor
Also auf Klassen zu verzichten halte ich wohl für ziemlich übertrieben
Er meinte vermutlich Dinge wie Entity-Klassen.
Daher finde ich eure aussagen wohl wissend, dass es klare Übertreibungen sind nicht richtig.
Das sind keine Übertreibungen - das passiert, wenn man Prinzipien und Patterns als die über allem stehenden Gesetze versteht.

Vielleicht hilft es, wenn Du Dir mal für einen Moment vorstellst, Du hättest in der DB eine View, die den benötigten JSON-String liefert. Würdest Du dann auch hergehen den JSON-String erstmal in ein JSON-Object einlesen, dieses auf eine EntityDbObj-Instanz abbilden, dann mit einem Mapper auf eine EntityJsonObj-Instanz, dann zurück auf JSONObject und am Ende wieder auf den String, den Du am Anfang aus der DB erhalten hast?

Nein? Genau das versuchst Du aber, nur mit dem Unterschied, dass Du am Anfang eben keinen String sondern mehrere Werte erhältst.

Es geht hier nicht um Objekte, sondern um Daten und die Aufgabe besteht einfach darin, Daten zu formatieren (z. B. jede Zeile in JSONObject einlesen, das Ergebnis als JSONArray zurückgeben und dann als String ausgeben lassen).
 

LokiA

Mitglied
Ach herrje - jetzt bin ich aber ganz schön lange auf dem Schlauch gestanden ...
Mein EntryDbObj ist das selbe wie EntryJsonObj daher brauch ich das nicht doppelt moppeln ... klar!!

Noch eine vielleicht letzte frage - wie würdet ihr die Daten aus der DB auslesen?
Bei so einer einfachen und schon vorgegebenen Struktur - JDBCTemplate oder JPA?
 

mihe7

Top Contributor
Mein EntryDbObj ist das selbe wie EntryJsonObj daher brauch ich das nicht doppelt moppeln ... klar!!
Und EntryDbObj/EntryJsonObj machen das gleiche wie JsonObject, daher brauchst Du "keine" Klassen.

JdbcTemplate kenn ich zwar nicht (mach kein Spring), sieht aber gut aus. Je nachdem, was Du vorhast, kann ein RowMapper<JsonObject> oder RowCallbackHandler (beides funktionale Interfaces) verwendet werden, um eine List<JsonObject> oder direkt ein JsonArray zu füllen.

Java:
public JsonArray find(...) {
    JsonArrayBuilder rows = Json.createArrayBuilder();
    RowCallbackHandler callback = rs -> {
        rows.add(Json.createObjectBuilder()
            .add("id", rs.getLong(1))
            .add("user", rs.getString(2))
            ...
        );
    };
    template.query(..., callback);
    return rows.build();
}
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
D Fehler wegen Rest-Schnittstelle Allgemeines EE 4
J rest-schnittstelle Allgemeines EE 3
LimDul Rest-Client/DTOs aus JSON Ergebnis generieren Allgemeines EE 3
M einfacher REST Webservice Allgemeines EE 4
M Rest mit Java 11 Allgemeines EE 6
OnDemand REST Json Response Mapping ist null Allgemeines EE 2
L Tcp-IP Server an Rest Schnittstelle Allgemeines EE 20
K Unterschied zwischen JSP & Servlet gegenüber REST mittels JAX-RS Allgemeines EE 1
C Servlet Tomcat/Jersey findet REST-Service nicht Allgemeines EE 3
N Authentication/UserPrincipal mit Rest Webservice? Allgemeines EE 6
T Servlet REST-Full Object per QueryParam Allgemeines EE 2
P ArrayIndexOutOfBoundsException: 48188 bei REST-WebServices Allgemeines EE 1
S Jersey, REST: Vererbung Allgemeines EE 0
G RMI vs REST Allgemeines EE 12
F REST-Service: GET erkennt Veränderungen an der DB nicht. Allgemeines EE 2
G REST Webservice Allgemeines EE 11
S Tomcat Application Path bestimmen Allgemeines EE 0
B Logging (log4j) in JAVA EE application - WildFly Allgemeines EE 15
S FAIL - Deployed application at context path /Address but context failed to start Allgemeines EE 1
T Fertiges html javascrip css template in java EE application Allgemeines EE 0
Y Caching Application Allgemeines EE 20
P Subprozess auf Application Server ausführen Allgemeines EE 6
S Rich Client Application mit Eclipse/WebLogic/EclipseLink/EJB3 Allgemeines EE 2
G Login into Web Application Allgemeines EE 9
P Nur ein User für Web Application Allgemeines EE 11
J Wicket-Projekt: "Unable to create application..." Allgemeines EE 2
MQue Java Web- Application -> MVC Allgemeines EE 4
D Wohin mit Resourcen (Bilder, txt Dateien) im Application Client Allgemeines EE 3
S Unterschied zwischen Tomcat und Application Server? Allgemeines EE 3
MQue Application Server Allgemeines EE 61
K Glassfish Application Client Allgemeines EE 4
N Objekte zwischen zwei Application Contexts austauschen Allgemeines EE 19
K Java Application Server + ganttproject *.jar Anwendung Allgemeines EE 6
J prozesse aus der application-bean threadfähig? Allgemeines EE 4
flashfactor Gibt es ein Case Management für Java Application Server? Allgemeines EE 6
M Java Application Server in einem ungesunden Zustand Allgemeines EE 4
F Application in HttpServlet abfragen? Allgemeines EE 5
X Sun Application Server 9 - EJB3 Zugriffsproblem Allgemeines EE 2
H Test Application für Tomcat Allgemeines EE 3
L xpetstore ejb sample application läuft nicht :-((( Allgemeines EE 7
T statische Methoden versus Application-Bean Allgemeines EE 2
K Datei schreiben in einer Web-Application Allgemeines EE 3
G Application Server! Gibt es eine grundsätzliche Architektur? Allgemeines EE 9
M Übersicht über Application Server Allgemeines EE 3
B Sun Application Server 8 --- Nichtsaussagende Fehlermeldung Allgemeines EE 2
M Debugging mit Eclipse / Web-Application Allgemeines EE 2
B Was kostet ein Application Server Allgemeines EE 18
K Sun Application Server - Servlets laufen nicht Allgemeines EE 2
E Web-, EJB-Container - Application Server Allgemeines EE 6
R Problem beim hochladen einer Web Application Allgemeines EE 16
M Initial data ohne SQL imports? Allgemeines EE 6
C "Data-holding" Klasse für JSP und ear Allgemeines EE 9

Ähnliche Java Themen

Neue Themen


Oben