CodeGym /Kurse /Java Server /Unter der Haube des Backends 🔧

Unter der Haube des Backends 🔧

Java Server
Level 1, Lektion 2
Verfügbar

1. Nach dem schönen Pfeil beginnt die Arbeit 🚀

Wenn jemand zum ersten Mal von Backend hört, greift er meistens nach dem glänzendsten Teil des Bildes – der Request-Verarbeitung. Es scheint, als würde alles Wesentliche in einer einzigen Methode leben: Daten empfangen, Aufgabe erledigen, Antwort zurückgeben. Aber sobald man versucht, diese Methode in ein Projekt zu verwandeln, wächst sofort eine Infrastruktur-Realität darum herum.

Man muss verstehen, wie das Projekt überhaupt startet. Wo liegt sein Code, wie wird er gebaut, welche Abhängigkeiten hat er, wie wird er ohne den grünen Knopf in der IDE gestartet. Man muss entscheiden, in welcher Form das System mit der Außenwelt kommuniziert. Die Grenze zwischen internen Objekten der Anwendung und dem, was über das Netz kommt oder geht, muss gehalten werden. Einstellungen müssen änderbar sein, ohne Quellcode anzufassen. Es muss einen vernünftigen Weg geben, Probleme zu analysieren, wenn eine Anfrage nicht so gelaufen ist wie gewünscht.

Deshalb liest sich Backend schlecht als „eine Klasse mit Logik". Echtes Backend-Verhalten hat eine Bühne, auf der es sich abspielt. Und diese Bühne besteht nicht nur aus Methoden-Code, sondern auch aus Build, Verträgen, Konfiguration, Logs und Systemgrenzen.

Je früher du das siehst, desto leichter werden die nächsten Themen des Kurses. Wenn man es nicht sieht, erscheint Gradle als seltsame Formalität, HTTP als „einfach Netz", JSON als „einfach String" und Logging als „überflüssige Nachrichten". In Wirklichkeit sind das alles Teile eines Bildes.

2. Zuerst muss das Projekt überhaupt starten

Eine sehr bodenständige Frage: Wie startet man eine Anwendung nicht nur beim Autor in der IDE, sondern auch bei einer anderen Person? Das ist keine organisatorische Kleinigkeit, sondern das Fundament eines Backend-Projekts.

Solange man in der Welt kleiner Konsolenaufgaben lebt, kann man diesen Schmerz lange nicht bemerken. Auf Run gedrückt – und los. Aber ein Backend-Projekt hängt fast sofort von der Verzeichnisstruktur, Abhängigkeiten, Ressourcen, Konfiguration und der Version des Build-Tools ab. Wenn all das nur in IDE-Einstellungen lebt, wird das Projekt fragil. Es „funktioniert" scheinbar, aber nur in einem sehr spezifischen lokalen Universum 😬.

Deshalb beginnt der Kurs sein erstes technisches Modul nicht mit HTTP, sondern mit Gradle Wrapper. Das wirkt unspektakulär, ist aber eine sehr Backend-Entscheidung. Die Anwendung muss bei allen gleich gebaut und gestartet werden – nicht nur bei einer Person mit einer gut eingerichteten Maschine. Von diesem Moment an ist das Projekt keine Ordner mit Code, sondern ein reproduzierbares Artefakt.

Wir müssen die Details von build.gradle.kts noch nicht durcharbeiten, aber es ist nützlich, das Prinzip selbst zu verstehen: Regeln für Start und Build liegen neben dem Code, nicht in deinem Gedächtnis. Das ist genau die Reife, die Spring später nicht ersetzt, sondern voraussetzt. Selbst in der Welt von Spring Boot lebst du trotzdem in einem Projekt mit Build-Tool, Abhängigkeiten und reproduzierbarem Start.

3. Das Kommunikationsformat: Request, Response, HTTP und JSON 📡

Sobald das Projekt gelernt hat zu starten, taucht sofort die nächste Frage auf: In welcher Form kommuniziert es mit der Außenwelt? Hier bekommt Backend das Wort „Vertrag" 🧾.

Ein Vertrag ist keine Bürokratie und keine schöne Dokumentation um der Dokumentation willen. Das ist eine ehrliche Vereinbarung zwischen zwei Parteien: was als Eingabe gilt, was als Ausgabe gilt, in welcher Form Daten ankommen, welche Antworten möglich sind, wo ein Fehler ist, wo Erfolg, was das Fehlen von Daten bedeutet und was eine falsche Eingabe. Ohne eine solche Vereinbarung wird jede Interaktion schnell zu „ich dachte, du meintest etwas anderes" 😅.

Später werden wir über HTTP-Methoden, Status-Codes, Headers, Path und Query Params sprechen. Aber schon jetzt reicht es, das Wesentliche zu sehen: Backend kann nicht nur mit internen Java-Objekten leben. Es hat eine Grenze. Und an dieser Grenze gehen Daten normalerweise als JSON, und der Sinn der Vereinbarung wird mit Tools wie Postman überprüft.

Hier ist ein sehr kleines Transport-Fragment des zukünftigen ReadLater:

{
  // Buchtitel – so, wie er gemäß dem externen Vertrag übertragen wird (Transport-Layer)
  "title": "Clean Code",

  // Autor – ebenfalls Teil des externen Formats; intern kann es anders heißen
  "author": "Robert C. Martin",

  // Status – Feld, um das herum sofort Fragen zu Validierung und erlaubten Werten entstehen
  "status": "PLANNED"
}

Eine naive Sichtweise sagt: „Na ja, JSON ist JSON." Eine erfahrene Sichtweise stellt andere Fragen 👀. Wer garantiert, dass das Feld status überhaupt angekommen ist? Was bedeutet null? Darf ein leerer String gesendet werden? Ist das eine Response oder ein Request? Ist das das interne Modell der Anwendung oder nur das externe Format? Aus genau solchen Fragen entstehen später DTOs, Validierung, Fehlerverträge und normales API-Denken.

Genau hier wird die Rolle von Postman klar. Es wird nicht als Knopf Send gebraucht, sondern als Mikroskop für den Vertrag 🔬. Es hilft zu sehen, was wirklich über das Netz geht, welche Status-Codes zurückkommen, wie Happy-Path und Negative-Path aussehen. Das ist kein „zusätzliches Tool im Kurs", sondern ein Weg, mit der Grenze eines Backend-Systems als Ingenieur zu arbeiten – nicht als Zuschauer.

4. Transport-Daten dürfen sich nicht durch die Anwendung verteilen

Die nächste Schmerzschicht erscheint sofort nach dem Vertrag. Selbst wenn JSON ehrlich angekommen ist, muss es noch in Objekte umgewandelt werden, mit denen die Anwendung normal leben kann. Und hier macht ein Anfänger oft eine gefährliche Vereinfachung: Er beginnt, das externe Datenformat quer durch den Code so wie es ist mitzuschleppen.

Das Problem ist, dass Transport-Modell und internes Anwendungsmodell selten eins zu eins übereinstimmen. Eine externe API kann ein Feld so benennen, deine Domain anders. Eine externe Antwort kann jede Menge Überflüssiges enthalten. Intern brauchst du vielleicht ein saubereres und stabileres Objekt. Genau deshalb entstehen im Backend DTOs und Mapping.

Wir brauchen noch keine vollständige Analyse von Jackson 3, aber es ist nützlich, die Form der Trennung zu sehen:

// DTO – Transportform der Daten, die dem externen Vertrag entspricht
record CatalogBookDto(
    String title,      // Feld aus dem externen JSON (wie an der Grenze benannt)
    String author,     // Feld aus dem externen JSON (kann nullable/leer sein – hängt vom Vertrag ab)
    String externalId  // Externer Bezeichner (z. B. aus einem Katalog/Partner-Service)
) {}

// Domain/internes Modell – das, womit es sich bequem intern arbeiten lässt
record ReadingListItem(
    String title,   // Intern brauchen wir vielleicht nur das...
    String author   // ...und das, ohne externalId und andere Transport-Details
) {}

CatalogBookDto – das ist die Transportform, in der Daten von außen angekommen sind. ReadingListItem – das ist bereits das Objekt, mit dem es sich bequem innerhalb von ReadLater arbeiten lässt. Der Unterschied zwischen ihnen kann klein oder groß sein. Der Sinn ist derselbe: Der externe Vertrag darf sich nicht unkontrolliert durch die Anwendung verteilen.

Deshalb erscheinen im Kurs-Programm nach HTTP und JSON folgerichtig HttpClient, Jackson 3 und DTO-Denken. Das sind nicht drei neue Spielzeuge hintereinander. Das ist ein Paket rund um eine sehr praktische Aufgabe: externes JSON empfangen, das Projekt nicht in eine Suppe aus Strings verwandeln und eine klare Grenze zwischen Transport-Layer und internem Sinn erhalten.

5. Konfiguration und Logs sind keine Dekorationen, sondern Betrieb

Stell dir jetzt vor, unser ReadLater kann bereits zum externen Buchkatalog gehen und ein Ergebnis liefern. Plötzlich stellt sich heraus, dass die Anwendung Werte hat, die man nicht ewig hardcoden kann: baseUrl des externen Services, Modus real oder mock, Port des lokalen Servers, möglicherweise Timeouts ⏱️. Das ist keine Business-Logik mehr. Das sind die Bedingungen, unter denen die Anwendung arbeitet.

Genau hier taucht die Idee der externalized configuration auf. Selbst vor Spring ist das ein separates Thema, weil eine reife Anwendung nicht verlangen sollte, dass Quellcode geändert wird, jedes Mal wenn sich eine Service-Adresse oder ein Startmodus ändert 🔧. Später macht Spring Boot diese Schicht viel bequemer, aber das Prinzip selbst entsteht nicht aus Spring. Es wird bereits jetzt gebraucht.

Neben der Konfiguration taucht fast sofort Logging auf 📝. Sobald externe Aufrufe, verschiedene Betriebsmodi und mehrere Verarbeitungsschritte vorhanden sind, hört println auf, harmlos zu sein. Man braucht Log-Level, verständliche Nachrichten, Unterschiede zwischen debug, info, warn und error, sorgfältigen Umgang mit Exceptions. Wiederum: Später macht der Stack SLF4J + Logback das zur normalen Praxis. Aber der Schmerz selbst ist schon vor dem Tool spürbar.

Deshalb ist das Modul über Konfiguration und Logging in diesem Kurs nicht zur Zierde hinzugefügt. Es ist ein früher Unterricht in der Betriebskultur einer Backend-Anwendung. Wenn eine Anwendung nicht normal konfiguriert und ihr Verhalten nicht normal gelesen werden kann, bleibt sie eine Demonstration, kein System.

6. Der Schmerz, den Spring nimmt

Jetzt kann man die wichtigste Erkenntnis sehr direkt formulieren. Spring wird nicht gebraucht, weil „das so in der Industrie gemacht wird" und nicht weil Backend ohne es verboten ist. Es wird gebraucht, weil es im Backend zu viel wiederholende Handarbeit gibt 🔧.

Aber hier ist Ingenieur-Ehrlichkeit wichtig. Spring schreibt keine Business-Logik für dich. Spring erfindet keinen guten API-Vertrag. Spring lässt das Transport-Modell nicht automatisch zu einem guten Domain-Modell werden. Es tut etwas anderes: Es nimmt eine große Schicht Infrastruktur-Routine weg, vereinfacht das Verdrahten von Abhängigkeiten, die Konfiguration, Boilerplate-Code rund um den Web-Layer, die Arbeit mit Komponenten und den Anwendungslebenszyklus.

Das lässt sich gut in einer kompakten Karte sehen:

Handarbeit im Backend-Projekt Wozu sie gebraucht wird Wo du sie in diesem Kurs siehst Was später mit Spring einfacher wird
Reproduzierbarer Build und Start Damit das Projekt nicht nur in der IDE lebt Gradle Wrapper und grundlegende Build-Konfiguration Boot und das Ökosystem lesen sich ohne Magie, aber das Verständnis des Builds bleibt deine Aufgabe
HTTP-Vertrag Damit Client und Server Eingabe und Ausgabe gleich verstehen HTTP, Status-Codes, Headers, Postman Spring MVC nimmt viel Boilerplate-Arbeit rund um die Web-Grenze weg
JSON und Transport-Formen Damit Daten an der Grenze explizit sind JSON, DTO, Jackson 3 Binding und Mapping werden bequemer, aber den Vertrag entwirfst du trotzdem selbst
Externer HTTP-Client Damit die Anwendung in andere Systeme gehen kann HttpClient, real/mock, Netzwerkfehler In der Spring-Welt erscheinen bequemere Integrations-Layer
Konfiguration außerhalb des Codes Damit derselbe Code in verschiedenen Modi lebt application.properties, Env-Variablen, Args Spring Boot macht externalized configuration viel komfortabler
Logging und Diagnostik Um Verhalten und Ausfälle zu analysieren SLF4J + Logback Ein normaler grundlegender Ansatz fürs Logging entsteht schneller und sauberer
Lokales HTTP-API Um den Web-Layer mit eigenen Händen zu sehen JDK HttpServer, Routing, Response Writing Spring MVC nimmt einen riesigen Anteil an Handarbeit im Web-Layer weg

Spring bringt keine neue Physik ins Backend. Es übernimmt den wiederholbaren Teil der Mechanik. Deshalb konkurriert dieser Kurs nicht mit Spring, sondern gibt ihm eine verständliche Grundlage.

7. Wie daraus das Kurs-Programm entsteht

Nach dieser Karte wirkt die Kursstruktur nicht mehr zufällig. Zuerst machst du das Projekt reproduzierbar mit Gradle Wrapper, weil du ohne das keinen zuverlässigen Einstiegspunkt ins Projekt hast. Dann tauchst du in HTTP, JSON und Postman ein, weil das die Sprache der Systemgrenze ist 📡. Dann lernst du, ein HTTP-Client zu einer externen API zu sein und JSON in DTOs zu mappen, weil Backend sehr oft selbst von anderen Services abhängt. Danach bringst du das Projekt durch Konfiguration, Logging und Struktur in Ordnung. Und erst dann hebst du ein eigenes lokales HTTP-API.

Genau deshalb fühlt sich unser Kurs vollständig an. Er geht nicht von einer Liste von Tools aus, sondern von echten Ingenieursfragen. Was braucht es, damit ein Backend-Projekt überhaupt lebt? Wie kommuniziert es mit der Außenwelt? Wie geht es in andere Systeme? Wie verhindert man, dass der externe Vertrag durch den Code fließt? Wie hebt man dann selbst ein HTTP-API?

Wenn du in diesem Moment etwas ruhiger geworden bist, funktioniert alles wie es soll 🙀. Du musst dem Kurs-Programm nicht blind vertrauen. Seine Logik ergibt sich aus der Natur der Backend-Arbeit selbst. Der nächste Schritt von hier entsteht ebenfalls natürlich: Gut, wenn der Kurs um eine Route und eine Handarbeit im Backend-Projekt herum aufgebaut ist, welches Projekt verbindet das alles? Hier kommt der ReadLater Starter auf die Bühne 🚀.

8. Typische Fehler 🙉

Fehler Nr. 1: Build-Tool, HTTP, JSON, DTO, Konfiguration und Logs als unverbundene Themen wahrnehmen.
Auf dem Papier sieht das wie eine Sammlung von Technologien aus. In einem echten System sind das Teile einer Route: Das Projekt muss starten, eine Grenze haben, Daten transportieren, konfigurierbar sein und sein Verhalten erklären. Wenn man dieses Paket im Kopf behält, liest sich der Kurs viel natürlicher.

Fehler Nr. 2: Zu denken, dass Spring „Backend von selbst löst".
Spring hilft sehr, aber es ersetzt kein Ingenieurdenken. Vertrag, Datenmodell, Code-Struktur, Verantwortungsgrenzen und die Qualität diagnostischer Nachrichten bleiben deine Arbeit. Das Framework erleichtert den Weg, geht ihn aber nicht für dich.

Fehler Nr. 3: Externes JSON direkt in alle Schichten der Anwendung zu ziehen.
Das scheint schnell, solange das Projekt klein ist. Später beginnt jede Änderung des externen Vertrags, die Hälfte des Codes kaputt zu machen. DTOs und Mapping werden nicht für Zeremonien gebraucht, sondern für die Isolierung der externen Grenze.

Fehler Nr. 4: Konfiguration und Logs als zweitrangig zu betrachten.
Solange eine Anwendung eine einzige Demo auf deiner Maschine macht, kann man so denken. Aber sobald Start-Modi, ein externer Service und eine wiederholbare Verarbeitung erscheinen, werden Konfiguration und Beobachtbarkeit Teil der grundlegenden Projektreife.

1
Aufgabe
Java Server, Level 1, Lektion 2
Gesperrt
Startprotokoll und Ergebnisprotokoll
Startprotokoll und Ergebnisprotokoll
1
Aufgabe
Java Server, Level 1, Lektion 2
Gesperrt
Anfragenroute durch Katalog und Speicher
Anfragenroute durch Katalog und Speicher
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION