# OpenAPI

## Vad det är

OpenAPI är ett standardformat för att skriva ner allt som en anropare behöver veta om ett HTTP-API —
adresser, operationer, indata, utdata, fel och säkerhetskrav — i ett enda JSON- eller YAML-dokument
som människor och program läser på samma sätt. Själva standarden heter OpenAPI Specification, ofta
förkortad OAS, och ett dokument skrivet enligt den kallas en OpenAPI-beskrivning. Formatet började
som Swagger Specification, och det äldre namnet lever kvar i verktyg som byggts kring det, till
exempel Swagger UI.

Specifikationen beskriver sig själv som en gränssnittsbeskrivning för HTTP-API:er som är oberoende
av programspråk. Målet den anger är att en människa eller ett program ska kunna förstå vad en tjänst
gör utan dess källkod, ytterligare dokumentation eller en inspelning av dess nätverkstrafik.
Rotdokumentet rekommenderas heta `openapi.json` eller `openapi.yaml`, och större beskrivningar delas
ofta upp i flera dokument som fogas samman med referenser.

Swagger 2.0 släpptes i september 2014 och skänktes till OpenAPI Initiative den 31 december 2015.
Version 3.0.0 kom i juli 2017 under det nya namnet, följd av 3.1.0 i februari 2021 och 3.2.0 i
september 2025.

En beskrivning har en handfull delar på toppnivå. `info` namnger API:et och dess version; `servers`
listar var det körs; `paths` innehåller varje adress och, under den, en operation per HTTP-metod,
med parametrar, anropets body och möjliga svar. `components` samlar det som återanvänds:
datascheman, parametrar, svar och de säkerhetsscheman som anger hur en anropare autentiserar sig.
Sedan 3.1 kan en sektion `webhooks` dessutom beskriva anrop som API:et skickar till sina
konsumenter. Ett minimalt utdrag:

```yaml
openapi: 3.1.0
info:
    title: Orders
    version: 1.4.0
paths:
    /orders/{id}:
        get:
            operationId: getOrder
            parameters:
                - name: id
                  in: path
                  required: true
                  schema:
                      type: string
            responses:
                "200":
                    description: One order
```

Datastrukturerna skrivs i ett schemaspråk. Från och med 3.1 är Schema Object en övermängd av JSON
Schema Draft 2020-12; 3.0 använde en utökad delmängd av ett äldre utkast med egna tillägg. JSON
Schema beskriver ett enskilt dataobjekt, medan OpenAPI beskriver ett helt HTTP-API och lånar JSON
Schema för delarna. Grannarna beskriver andra slags gränssnitt: AsyncAPI täcker meddelandedrivna
system, gRPC-tjänster deklareras med Protocol Buffers i `.proto`-definitioner, och en GraphQL-tjänst
publicerar sitt eget schema.

## Varför det spelar roll

En beskrivning i ett standardformat är ett enda dokument som många verktyg kan läsa, och vart och
ett sparar arbete som ett team annars hade fått göra för hand. Referensdokumentationen renderas från
den. Klientbibliotek i flera språk genereras från den, så att en frontend anropar en typad funktion
i stället för att sätta ihop en URL. Mockservrar svarar utifrån den, så att en frontend kan byggas
innan backend finns. API-gateways importerar rutter från den, testsviter validerar trafik mot den,
och AI-agenter som anropar API:er läser den för att se vad som erbjuds.

Den räckvidden är också risken. Vart och ett av verktygen litar på dokumentet. En beskrivning som är
fel är värre än ingen alls, eftersom den genererade klienten kompilerar, dokumentationen ser
auktoritativ ut och misstaget visar sig vid körning i någon annans produkt.

Det viktigaste beslutet gäller därför var beskrivningen kommer ifrån. Vid design-first skriver
människor beskrivningen, granskar den som kontraktet och bygger sedan servern så att den stämmer.
API:ets form diskuteras innan det finns någon kod, vilket passar publika API:er och team som arbetar
parallellt. Priset är att beskrivningen och servern är två saker som kan säga emot varandra. Vid
code-first genereras beskrivningen från serverns egna typer och annoteringar. Den kan inte beskriva
en rutt som servern saknar, men den är bara så exakt som typerna, och designdiskussionen sker i
kodgranskningen i stället för i ett dokument. Hur man än gör förblir beskrivningen sann bara om ett
bygge kontrollerar den.

Steget från 3.0 till 3.1 ändrade hur schemadelen skrivs, eftersom 3.1 tog över JSON Schema 2020-12.
Generatorer, validerare och gateways stöder var och en sitt eget spann av versioner, så den version
ett team skriver begränsas av det äldsta verktyget i kedjan.

## Så ser det ut i praktiken

En OpenAPI-beskrivning kan vara dokumentation som följer koden eller en länk i en kedja som
genererar kod, och arbetet här har gett den båda uppgifterna.

På en plattform började API:et på Fiber med validering skriven för hand, slutpunkt för slutpunkt,
och utan något samlat dokument som beskrev dess form.
[HTTP-lagret flyttades till Huma v2](/sv/portfolio/migrated-the-http-api-from-fiber-to-huma-60/),
ovanpå Fiber, så varje slutpunkt deklareras med structar för indata och utdata och
OpenAPI-beskrivningen genereras från de typerna; dokumentationen följer koden i stället för att
åldras i en wiki. De två slutpunkterna för WebSocket ligger kvar på ren Fiber, utanför den modell
med anrop och svar som Huma bygger på. Sidan förklarar varför skalan spelar roll: med 760
operationer fördelade på 649 sökvägar är beskrivningen i praktiken det enda sätt som någon kan läsa
API:et på, så vetskapen om att den är komplett väger tyngre än vid femtio. En kontroll i CI håller
pariteten mellan rutter och beskrivning på 100 %.

På en annan plattform är beskrivningen mittlänken i en kedja som går från databasen och utåt.
Schemat och dess funktioner formar Go-typerna,
[Huma genererar beskrivningen, och det som frontenden använder genereras från den](/sv/portfolio/built-a-request-schema-validation-contract-with-automated-61/):
en typad TypeScript-klient på 44 076 rader, 61 mock-hanterare för frontendens tester och de gränser
som varje formulär upprätthåller. Den löser isärglidning mellan frontend och backend, som oftast
visar sig som en 422 i webbläsaren efter att avvikelsen redan har släppts. En kontraktskontroll i CI
fäller bygget vid avvikelse, med en sond riktad mot valfria fält i anropets body, där ”saknas” och
”null” blandas ihop, och mot enum-värden i query-parametrar. Sidan sätter namn på priset: ett
genereringssteg mitt i allt, och en kedja som bara är så pålitlig som sin sämst skyddade länk.

[Företagets sida om att vara redo för AI-agenter](/sv/ai-ready/) tillämpar samma resonemang på
agenter. En applikation som agenter kan använda erbjuder ett beskrivet API: ett OpenAPI-dokument, en
MCP-server där agenter ska anropa det direkt, och OAuth-metadata så att en agent kan agera för en
användare utan att få lösenordet. Sidan klassificerar varje rekommendation i stället för att lyda
den, och eftersom företagets egen webbplats saknar API är en API-katalog och OAuth-metadata två av
de fem som valdes bort där.

## Var det går fel

**Beskrivningen lovar något som servern inte gör.** En handskött beskrivning halkar efter: en ny
query-parameter, ett omdöpt fält eller en felkod som bara servern känner till. Genererade klienter
kompilerar då mot en fiktion. Generera beskrivningen från koden, eller håll den separat och validera
verkliga anrop och svar mot den i testsviten, och jämför de rutter som servern registrerar med de
sökvägar som beskrivningen listar.

**Varje omgenerering av klienten döper om hälften av metoderna.** Utan `operationId` hittar
generatorer på metodnamn utifrån sökvägen och HTTP-metoden, så att en flyttad rutt döper om den
funktion som varje anropare använder. Specifikationen kräver att varje `operationId` är unikt och
skiljer på stora och små bokstäver. Sätt ett på varje operation, välj det lika omsorgsfullt som
namnet på en publik funktion, och låt en linter fälla bygget när ett saknas.

**Fält som får vara null börjar avvisa null efter en uppgradering.** OpenAPI 3.0 markerade dem med
`nullable: true`. I 3.1 är det nyckelordet borta och typen blir en lista, och en validerare som
stöter på ett nyckelord den inte känner igen brukar ignorera det. Ett schema för 3.0 som bara märks
om till 3.1 avvisar därför null överallt där författaren menade att tillåta det. Konvertera med
uppgraderingsguiden från OpenAPI Initiative, som också tar upp att `exclusiveMinimum` blir ett tal:

```yaml
# OpenAPI 3.0
type: string
nullable: true
# OpenAPI 3.1
type: [string, "null"]
```

**Exemplen klarar inte sitt eget schema.** Specifikationen säger att ett exempel ska stämma med sitt
schema och lämnar kontrollen åt verktygen. En läsare kopierar exemplet ur dokumentationen och får en
422; en mockserver serverar det, och frontenden byggs mot data som det verkliga API:et kommer att
avvisa. Validera varje exempel i CI, lika strikt som skarp trafik.

**Den publika beskrivningen kartlägger admin-API:et.** En beskrivning som genereras från varje rutt
och serveras på en publik adress visar interna operationer och deras datastrukturer för vem som
helst som frågar. Publicera en beskrivning per målgrupp, genererad med de interna operationerna
bortfiltrerade. Specifikationen tillåter att objekt lämnas tomma eller tas bort för just den här
sortens åtkomstkontroll.

## Läs mer

- [OpenAPI Specification](https://spec.openapis.org/oas/latest.html) — den senaste versionen av
  standarden, med varje objekt och fält definierat och en historik över varje utgåva.
- [JSON Schema Draft 2020-12](https://json-schema.org/draft/2020-12) — schemaspråket som OpenAPI 3.1
  och senare använder för varje body i anrop och svar.
- [Upgrading from OpenAPI 3.0 to 3.1](https://learn.openapis.org/upgrading/v3.0-to-v3.1.html) —
  listan från OpenAPI Initiative över ändringar i schemadelen, `nullable` bland dem.
- [Huma: OpenAPI Generation](https://huma.rocks/features/openapi-generation/) — hur Go-ramverket som
  används i projekten ovan härleder en beskrivning ur typerna i hanterarna.

<https://engineer.company/sv/glossary/openapi/>
