---
title: "Apache Avro: kontrakten mellem moduler"
url: "https://hurukan.com/da/blog/apache-avro-kontrakten-mellem-moduler"
description: "Hver hændelse mellem moduler er en kontrakt. Avro skriver den ind i data, og en skemaændring bliver et forslag, et menneske godkender og systemet registrerer."
---

# Apache Avro: kontrakten mellem moduler

2\. september 2026·4 min. læsning·Redaktionen

To ingeniører set bagfra ved et fælles bord i et stille kontor, en stor vægskærm mellem dem viser et abstrakt blågråt diagram af en formular og dens versioner, et udskrevet ark under den ene hånd, et enkelt blåt statuslys i skærmens ramme

Salgsteamet tilføjer en rabatprocent til ordren. Det er en lille ændring, aftalt på et møde, og modulet, der opretter ordrer, begynder at sende den samme eftermiddag. Økonomimodulet, som har læst ordrer i to år, kender ikke feltet og holder op med at acceptere beskeden. Ingen havde til hensigt at ændre en kontrakt. Der var en kontrakt, den var bare aldrig skrevet ned andre steder end i to stykker kode, som plejede at være enige.

I et system bygget af moduler, der udveksler hændelser, er hver hændelse en aftale. Apache Avro er et af de formater, der skriver den aftale ind i selve data, og grunden til, at det indgår i designet af Hurukans [datalag](https://hurukan.com/da/system/data), som er under opbygning, handler mindre om bytes end om, hvad der sker, når aftalen skal ændres.

## Skemaet rejser med data

En Avro-post er en kompakt binær række. Alene kan den ikke læses: feltnavne, typer og rækkefølge står ikke i bytes. De står i skemaet, skrevet i JSON, og [specifikationen](https://avro.apache.org/docs/1.12.0/specification/) definerer et lille sæt typer at skrive det med: null, boolean, int, long, float, double, bytes, string og de sammensatte record, enum, array, map, union og fixed. Et felt kan have en standardværdi, og netop den standardværdi gør senere ændringer til at overleve. Den aktuelle udgivelse er 1.12.2 ([projektets blog](https://avro.apache.org/blog/), kontrolleret den 21. oktober 2026).

Skemaet når læseren ad en af to veje. I en fil lægger Object Container File-formatet skemaet i headeren, efterfulgt af blokke af poster adskilt af en synkroniseringsmarkør, så en fil, der findes år senere, stadig forklarer sig selv. På en meddelelsesbus, hvor det ville være spild at sende skemaet med hver hændelse, sætter specifikationens enkeltobjektkodning (single-object encoding) en markør på to bytes og et fingeraftryk af skemaet på otte bytes foran hver post; et register opbevarer skemaet under det fingeraftryk. Det udbredte Confluent-register gør det samme med sin egen indramning, en magisk byte og en skema-id på fire bytes før Avro-bytes ([Confluent-dokumentation](https://docs.confluent.io/platform/current/schema-registry/fundamentals/serdes-develop/index.html)).

Uanset vejen gætter læseren aldrig. Den har skribentens skema og sit eget, og resten er regler.

## Opløsning: hvordan en læser møder en skribent, den aldrig har set

Specifikationen fastlægger, hvad der sker, når skribentens skema og læserens skema er forskellige. Felter matches på navn. Et felt, som skribenten sendte, og som læseren ikke har, ignoreres. Et felt, som læseren forventer, og som skribenten ikke sendte, udfyldes fra læserens standardværdi, og findes der ingen standardværdi, fejler læsningen med en klar begrundelse. Nogle typer kan forfremmes undervejs: en int kan læses som long, en long som float eller double, en float som double, og string og bytes kan læses som hinanden. En union matches med den første kompatible gren på læserens side.

Skrevet ud er de regler hele disciplinen omkring rabatfeltet. Tilføj det med en standardværdi, og økonomimodulet læser videre og ignorerer feltet, indtil det lærer at bruge det. Tilføj det uden standardværdi og fjern et gammelt felt i samme ændring, og den ældste læser i virksomheden stopper. Reglerne er ikke råd; de afgør, hvilken udgave af morgenen du får.

## En skemaændring som et forslag

I Hurukan er designet, at et hændelsesskema er et objekt i ontologien som alle andre: det har en ejer, versioner og en plads i registret. Det gør rabatfeltet fra en eftermiddags kodeændring til en kort, registreret vej.

**En agent foreslår.** Salgsmodulet har brug for et nyt felt; en agent udarbejder skemaændringen med standardværdi, type og begrundelse og navngiver de moduler, der læser denne hændelse.

**Registret kontrollerer.** Den foreslåede version testes mod læsernes skemaer efter opløsningsreglerne ovenfor. En ændring, der ville stoppe en eksisterende læser, afvises, før nogen ser den, med læseren navngivet.

**Ejeren godkender.** En kompatibel ændring er stadig en ændring af en aftale mellem moduler. Hændelsens ejer, et menneske, godkender den, og først derefter begynder producenterne at skrive den nye version.

**Registret gemmer det.** Godkendelsen, versionen og tidspunktet skrives i registret, så spørgsmålet “hvornår dukkede rabatter op på ordrer, og hvem tillod det” har et svar et år senere. Det er den samme vej, hver ændring i systemet tager: en agent foreslår, et menneske beslutter, systemet registrerer. Den bredere idé står i [den levende tilstand og registret](https://hurukan.com/da/blog/den-levende-tilstand-og-registret-to-hukommelser).

## Hvad Avro ikke er til

Avro bærer hændelser godt og læser hele poster godt. Det er et dårligt layout til det spørgsmål, superintelligensen oftest stiller, nogle få felter på tværs af en million rækker, fordi hvert felt står i vejen for alle de andre. Derfor bliver hændelser i Avro i designet samlet i kolonner, når de er accepteret. Hvilken form der hører hvor, er beskrevet i [Parquet og Avro: hændelsen og registret](https://hurukan.com/da/blog/parquet-og-avro-haendelsen-og-registret).

Avro optræder også et sted, få kigger: tabelformatet Apache Iceberg skriver sine manifester, listerne over de datafiler, en tabel består af, som Avro-filer ([Iceberg-specifikationen](https://iceberg.apache.org/spec/)). Det rækkeformat, der bærer hændelser mellem moduler, bærer også registrets bogføring.

## Hvad der bliver hos mennesker

En agent kan udarbejde et skema, køre kompatibilitetskontrollen og navngive læserne. Den kan ikke beslutte, at et felt, som økonomimodulet var afhængig af, må forsvinde, at en standardværdi på nul er et sandt udsagn om gamle ordrer, eller at en læser må få lov at fejle. Det er beslutninger om forretningens betydning, og i Hurukan træffes de af hændelsens ejer og skrives ned.

## En test, du kan lave i dag

Vælg én besked, der bevæger sig mellem to af dine systemer. Find, hvor dens felter er defineret. Hvis svaret er “i den afsendende kode” og “i den modtagende kode”, har du to definitioner og ingen kontrakt. Spørg derefter, hvem der ville godkende at tilføje et felt til den, med navn. Er der intet navn, bliver det næste felt tilføjet af den, der har brug for det først, og opdaget af den, det ødelægger for. Siden om [datalaget](https://hurukan.com/da/system/data) beskriver, hvor den kontrakt skal bo i Hurukan; [oversigten](https://hurukan.com/da) viser modulerne omkring den.

-   Apache Avro
-   skemaregister
-   hændelseskontrakter
-   skemaudvikling
-   datalaget

## Læs videre

-   [Én identitet for mennesker og agenter: hvem må hvad](https://hurukan.com/da/blog/en-identitet-for-mennesker-og-agenter)
-   [Den levende tilstand og registret: to hukommelser i et operativsystem for virksomheden](https://hurukan.com/da/blog/den-levende-tilstand-og-registret-to-hukommelser)