Backends
TL;DR
- Ein backend ist die Kompositions-Schicht der Plattform: ein typisierter Graph aus component-Releases mit ihren gebundenen Parametern und Dateien, bereit zum Deploy. components definieren, was Code tut; backends definieren, was ein konkreter Produkt-Workflow mit diesem Code tut.
- Ein backend ist ein Objekt, kein Skript: es kann inspiziert, bearbeitet, rueckgaengig gemacht, redeployt und nach dem exakten component-Release in der Produktion abgefragt werden. Die Plattform besitzt die Mutationsflaeche; siehe Backend-Operationen, wie jede Aenderung aufgezeichnet und rueckgaengig gemacht wird.
- Die Plattform typprueft den Graphen zur Edit-Zeit, nicht erst beim Deploy. Einen
Image-Output in einen[BoundingBox]-Input zu verbinden wird sofort abgelehnt, mit einem praezisen Fehler, der die edge benennt, statt spaeter als Laufzeitfehler in einem Container aufzutauchen. - backends pinnen spezifische component-Release-Versionen, keine floatenden Tags. Das promote eines neuen component-Release aendert kein backend stillschweigend, das bereits gegen ein aelteres Release verdrahtet war.
- Ein backend ist kein laufender Code. Es ist die geprüfte Definition eines Produkt-Workflows. Es auszufuehren ist die Aufgabe eines deployment; das backend selbst bleibt die inspizierbare, rueckgaengigmachbare, redeploybare Graph-Definition.
Was ein backend tatsaechlich ist
Ein backend ist, wie Pipelogic den Workflow eines Produkts darstellt: eine typisierte, geprüfte, reproduzierbare Komposition von component-Faehigkeiten. components definieren, was Code tut; ein backend definiert, was ein konkretes Produkt mit diesem Code tut, und zwar als explizites, inspizierbares Objekt statt als Orchestrierungscode, der um die components gewickelt ist.
Komposition als erstklassiges Objekt zu modellieren ist es, was den Workflow selbst operierbar macht. Weil das backend ein Objekt und kein Skript ist, kann es von einem Teamkollegen inspiziert, von einem Tool bearbeitet, nach einer schlechten Aenderung rueckgaengig gemacht, ohne Neubau redeployt und danach abgefragt werden, welche component-Release-Version tatsaechlich in der Produktion laeuft. Die Form des Systems ist der Graph, nicht Glue-Code, der ueber Dateien und das Gedaechtnis des Autors verstreut ist, und die Typgarantien, die die components deklarieren, werden durch die Verdrahtung getragen statt verloren zu gehen, wenn Ports von Hand verbunden werden.
Ein backend ist ein Graph: vertices sind gepinnte component-Release-Versionen plus die an jede gebundenen Parameter und Dateien; edges verbinden typisierte Output-Streams mit kompatiblen typisierten Input-Streams; die gesamte Struktur ist reproduzierbar, weil jede Aenderung daran eine aufgezeichnete Operation im Log des backend ist. Das backend kann inspiziert, bearbeitet, rueckgaengig gemacht, kompaktiert, typgeprueft, deployt, redeployt, geforkt und durchdacht werden, weil es ein erstklassiges Objekt ist und kein Nebeneffekt von Code.
Die Trennung ist bewusst: Komposition lebt im backend, nicht in der component. Eine component ist die Faehigkeit; das backend ist die Nutzung dieser Faehigkeit in einem konkreten Workflow. Eine einzelne component kann als vertex in vielen backends sitzen, jedes verdrahtet sie mit anderen Vorgaengern, parametrisiert sie anders, bindet andere Dateien. Deshalb kann ein einmal gut gebauter Detektor vielen Produkten dienen, statt pro Produkt geforkt zu werden. Das ist die uebliche Modularitaetsrendite von Microservices — unabhaengig versionierte, wiederverwendbare Faehigkeiten — ohne die uebliche Steuer: kein Glue-Code pro Service, keine zu betreibende Orchestrierungsschicht, keine Vertragsdrift, weil die Verdrahtung ein typisierter Graph ist, den die Plattform prueft, statt Code, den jedes Team von Hand pflegt.
Mentales Modell
┌──────────────────────────────────────┐
│ input_image_http │
│ () → (Image, String) │
└──────────────────────────────────────┘
vertex 1
│ out 0 → Image
▼
┌──────────────────────────────────────┐
│ convert_image_format │
│ Image → Image │
│ color_model=RGB │
└──────────────────────────────────────┘
vertex 2
│ out 0 → Image
▼
┌──────────────────────────────────────┐
│ detect_objects_ultralytics_yolo │
│ Image → [BoundingBox] │
│ threshold=0.4 · model=<file> │
└──────────────────────────────────────┘
vertex 3
Jeder vertex ist eine gepinnte Release-Version plus ihre Bindungen — zwei vertices auf demselben Release mit unterschiedlichen Parametern oder unterschiedlichen Datei-Bindungen sind unterschiedliche vertices. Jede edge ist (from-vertex, from-output) → (to-vertex, to-input): Inputs akzeptieren hoechstens eine vorgelagerte edge, Outputs koennen auf mehrere Konsumenten ausfaechern. Die gesamte Struktur ist es, was deployt wird; nichts an einem deployment ist implizit.
Siehe Components fuer die Einheit, die ein vertex pinnt, und Types fuer den Vertrag, den die edges erfuellen.
Der Graph wird nicht als Datei gespeichert, die du oeffnest und bearbeitest; die Plattform besitzt die Mutationsflaeche, jede Aenderung ist eine aufgezeichnete Operation, und der aktuelle Graph wird durch das Replay dieses Logs abgeleitet. Siehe Backend-Operationen fuer das Operationsvokabular, wie jede Aenderung rueckgaengig gemacht wird, und die compact-Semantik.
Das Typsystem faengt Verdrahtung zur Edit-Zeit ab
Nutze diesen Rahmen, um zu verstehen, warum eine connect-Operation abgelehnt wird.
Jede component deklariert den Typ jedes ihrer Streams in ihrer component.yml. Wenn ein backend zwei vertices verdrahtet, laeuft die Typinferenz der Plattform ueber die vorgeschlagene edge und ueber den gesamten Graphen und bestimmt, ob die Verbindung schluessig ist. Ein Image-Output in einen [BoundingBox]-Input wird abgelehnt, mit einem Fehler, der die edge und den Konflikt benennt. Ein Maybe<String> in ein String wird abgelehnt (das Wrapping ist signifikant). Ein generisches [t] in [Image] wird nur akzeptiert, wenn t anderswo im Graphen konsistent als Image instanziiert.
Der Check laeuft zur Edit-Zeit, nicht erst beim Deploy. Das ist das tragende Detail. Im Moment des Edits zu validieren bedeutet, dass ein Typkonflikt bei der Operation gemeldet wird, die ihn verursacht hat, nicht als Laufzeitabsturz in einem deployten Container. Wenn eine Verbindung unschluessig ist, wird die Operation nicht aufgezeichnet, der Graph bleibt gueltig, und du korrigierst den Edit und faehrst fort.
Derselbe Check laeuft zur Deploy-Zeit erneut, und es ist bewusst dieselbe Maschine — der Deploy-Zeit-Check ist nicht strenger als der Edit-Zeit-Check. Ein Edit, den die Plattform akzeptiert, wird beim Deploy erneut akzeptiert. Diese Symmetrie ist es, die backend-Autoren sich auf das Edit-Zeit-Feedback verlassen laesst.
Siehe Types fuer das Typsystem, gegen das der Check laeuft.
Mutable Bindungen versus Topologie-Aenderungen
Nutze diesen Rahmen, wann immer du dich fragst, ob ein backend-Edit einen redeploy braucht.
Die meisten Edits an einem backend-Graphen erfordern einen redeploy: einen vertex hinzufuegen, einen vertex entfernen, die gepinnte Release-Version eines vertex aendern, edges verbinden oder trennen, eine andere Datei binden oder einen Parameter aendern, der nicht als mutable: true deklariert ist. Das sind Topologie-Aenderungen — die laufenden Container entsprechen dem neuen Graphen nicht mehr, also werden sie ersetzt.
Eine kleine Menge von Edits erfordert keinen redeploy. Parameter, die als mutable: true im config_schema der component deklariert sind, aktualisieren sich gegen das laufende deployment: die Plattform schiebt den neuen Wert in den laufenden Container, und die component liest ihn beim naechsten Aufruf ueber ihren subscribe-config-Pfad. Das gilt fuer Schwellenwerte, Laufzeit-Knoepfe und jeden Parameter, den der component-Autor als sicher markiert hat, um ihn live ohne redeploy zu tunen.
Topologie-Aenderungen haben kein mutable-Aequivalent. Es gibt kein Live-Hinzufuegen eines vertex und kein Live-Umverdrahten einer edge; diese Aenderungen definieren den Graphen neu, und die Laufzeit wird passend redeployt. Dasselbe gilt fuer Datei-Bindungen — die Laufzeit mountet Dateien beim Container-Start, also erfordert ein Neubinden einen frischen Container.
Das Design erzwingt, dass mutable-Parameter von der component deklariert werden, nicht vom backend. Der component-Autor entscheidet, welche Parameter laufzeitsicher sind; der backend-Operator bekommt genau diese Flaeche fuer Live-Tuning und nichts darueber hinaus. Diese Trennung haelt Parameter, die live unsicher zu aendern sind, davon ab, als live-editierbar behandelt zu werden.
Was das Forken eines backend bedeutet
Nutze das, wann immer du zwei parallele Umgebungen brauchst — Staging vs. Produktion, A vs. B, Blue vs. Green.
Die Verbindung zwischen einem backend und seinem deployment ist 1:1. Ein einzelnes backend kann nicht zwei gleichzeitige deployments hosten. Um zwei parallele Umgebungen zu betreiben, forke zuerst das backend: kopiere den Graphen (mit beliebigen Aenderungen), dann deploye jeden Fork unabhaengig. Die beiden backends teilen sich die zugrunde liegenden component-Releases und unterscheiden sich in vertex-Parametern, vertex-Datei-Bindungen oder Graph-Topologie — je nachdem, was die parallele Umgebung erfordert.
Die 1:1-Verbindung haelt den Produktionszustand eindeutig: was auf einem deployment laeuft, ist genau der Graph, auf den dieses backend gerade zeigt. Zwei parallele Umgebungen sind zwei separate Objekte statt zwei Sichten auf ein Objekt, sodass die Operation-Historie pro backend, die aufgezeichnete Aenderungshistorie pro Umgebung und das Live-Tuning pro deployment jeweils unabhaengig sind.
Siehe Deployments fuer die 1:1-Verbindung im Detail.
Was ein backend besitzt und was nicht
Ein backend besitzt seine vertices (gepinnte Release-Versionen plus Parameter-, Datei- und Constraint-Bindungen), seine edges, seine endpoint-Aliase (die Namen, die Aufrufer verwenden, um bestimmte Output-Ports zu erreichen) und sein Operation-Log (die aufgezeichnete Historie jeder Aenderung). Es besitzt auch seine Anzeigeidentitaet und seinen Workspace-Besitz.
Es besitzt nicht die component-Implementierung (die lebt im component-Release), die laufenden Container (die leben im deployment), die oeffentliche URL (die lebt im deployment, abgeleitet aus den endpoint-Aliasen des backend), die Team-Mitgliedschaft (die lebt im Workspace) oder irgendeinen per-Umgebung-Laufzeitzustand. Das backend ist die geprüfte Komposition; die Laufzeit, der beobachtbare Zustand und die extern erreichbare Flaeche gehoeren zum deployment und zum Workspace.
drivers richten sich gegen endpoint-Aliase aus
Ein backend fuehrt keine driver_id. Die Ausrichtung ist implizit: ein backend erfuellt einen driver, wenn fuer jeden RequiredEndpoint, den der driver deklariert, die endpoint-alias-Map eines vertex diesen endpoint an der passenden Rolle benennt, mit einem Transport, den der driver akzeptiert, und der korrekten Richtung. Die alias-Map ist die Entkopplungsnaht — der driver beschreibt, was das backend exponiert, das gepinnte component-Release des vertex entscheidet, wie, und der Operator kann die Implementierung hinter einem alias austauschen, ohne den Vertrag zu brechen.
Dieselbe Ausrichtung wird von zwei Flaechen konsumiert, die eine application pinnt: der Live-Wire-Vertrag (needs_driver, Transport pro UX-Bedarf) und der Capture-und-replay-Vertrag (taps_driver, immer HTTP, beide Richtungen). Wenn eine Aufzeichnung gegen dasselbe backend startet, loest die Plattform die erforderlichen endpoints des taps_driver durch dieselbe alias-Map auf und legt HTTP-Tap-URLs auf die gematchten vertices beim Deploy-Resolve — der backend-Graph wird nie mutiert.
Siehe Drivers fuer die Vertragsschicht und Replays fuer die Capture-Flaeche, die taps_driver ueber die alias-Map konsumiert.
Wo das hineinpasst
backends sind dort, wo die Trennung der Belange der Plattform zusammenkommt. components sind wiederverwendbar, Releases sind unveraenderlich, Typen werden end-to-end geprueft, das Operation-Log ist reproduzierbar, und deployments sind von den Definitionen entkoppelt. Das backend ist das Primitiv, das diese Garantien in einen einzigen Workflow komponiert. Jedes Produkt auf Pipelogic ist ein oder mehrere backends — gepinnt, typisiert, event-sourced, redeploybar — und diese Einheitlichkeit ist es, die die Komposition eines Produkts inspizierbar und reproduzierbar haelt, waehrend es waechst.
Verwandt
- Components — die freigegebenen Faehigkeiten, die ein backend pinnt.
- Types — der Vertrag, gegen den die Plattform den Graphen validiert.
- Backend-Operationen — das Operation-Log im Detail.
- Deployments — die Laufzeitseite der 1:1-Verbindung.
- Leases — ephemere Huellen um Test-backends.
- Solutions — backend-endpoints und die Konsumenten, die sie bedienen.
- Quickstart — Routen-Auswahl fuer deine erste Aufgabe.