# /core/publish-openapi

Deze regel schrijft voor dat elke api een `/openapi.json` file moet publiceren
zodat tooling hier gebruik van kan maken. Hiermee kunnen tools zoals
[Swagger UI](https://swagger.io/tools/swagger-ui/) automatisch documentatie
websites bouwen en kunnen er [TypeScript types](https://openapi-ts.dev/) worden
gegenereerd. Dit alles zorgt ervoor dat een API inzichtelijk is, maar ook
makkelijk te gebruiken voor eindgebruikers

- Regel:
  https://gitdocumentatie.logius.nl/publicatie/api/adr/2.0.2/#/core/publish-openapi

## Waarom moet dit bestandje publiekelijk beschikbaar zijn?

API's zijn niet per definitie open, vanwege gevoelige data die zij exposen of
vanwege het enforceren van rate limits. Hierdoor zijn API's niet altijd
bereikbaar voor eenieder. Toch stelt deze regel dat het `/openapi.json` bestand
wel altijd bereikbaar moet zijn, zonder authenticatie en autorisatie.

De bovengenoemde tooling is de grootste reden hiervoor: als de specificatie
altijd beschikbaar is, kunnen afnemers hier gebruik van maken. Denk bijvoorbeeld
aan CI systemen die geen productie toegang moeten hebben tot een API, maar wel
de TypeScript types willen genereren. Of dat developers eerst de documentatie
willen doorlezen, voordat ze beslissen of ze een API key willen aanvragen.

Het beschikbaar maken van de `/openapi.json` voor iedereen en op een standaard
locatie zorgt ervoor dat afnemers hier tooling omheen kunnen bouwen, zonder dit
voor elke API anders af te handelen. Vanwege deze vraag naar uniformiteit is dit
dus gestandaardiseerd.

## Implementeren in code

Afhankelijk van het framework van de server die de API host zijn er meerdere
oplossingen.


**Gin (Go):**

[Gin](https://gin-gonic.com/) heeft een [Fizz handler](https://github.com/wI2L/fizz) die automatisch de endpoints configureert [[source]](https://medium.com/@denispalnitsky/autogenerated-api-documentation-in-go-with-open-api-swagger-a0ed1edb084c):

```go
import (
  "fmt"

  "github.com/gin-gonic/gin"
  cors "github.com/rs/cors/wrapper/gin" // hiermee voldoe je aan /core/open-api

  "github.com/wI2L/fizz"
  "github.com/wI2L/fizz/openapi"
)

func NewRouter() (\*fizz.Fizz, error) {
  r := gin.Default()
  r.Use(func(c *gin.Context) {
      c.Header("API-Version", "1.0.0")
      c.Next()
  })
  f := fizz.NewFromEngine(r)

  infos := &openapi.Info{
      Title: "Example API",
      Description: "Voorbeeldproject",
      Version: "1.0.0",
      Contact: &openapi.Contact{
          Name: "API Team",
          URL: "https://example.com/support",
          Email: "support@example.com",
      },
  }
  f.Generator().SetServers([]*openapi.Server{
    {
      Description: "Production",
      URL:         "https://api.example.com/v1",
    },
  })
  f.GET("/v1/openapi.json", []fizz.OperationOption{
      fizz.WithoutSecurity(),
  }, cors.Default(), f.OpenAPI(infos, "json"))
}
```

---

**Quarkus (Java):**

[Quarkus](https://quarkus.io/) heeft een [openapi plugin](https://quarkus.io/guides/openapi-swaggerui) die automatisch een `openapi.json` kan genereren op basis van Java annotations. Voeg hiervoor de volgende plugin toe:

```xml
<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-smallrye-openapi</artifactId>
</dependency>
```

In de `application.properties` moet het volgende worden toegevoegd:

```properties
# Sta alle systemen toe om de `/openapi.json` resource op te vragen
quarkus.http.cors=true
quarkus.http.cors.origins=*
# De gestandaardiseerde locatie van het bestandje
quarkus.smallrye-openapi.path=/openapi.json
# Zodat authentication niet nodig is om de `/openapi.json` resource op te vragen
quarkus.smallrye-openapi.auto-add-security=false
```

Het is ook mogelijk om een statisch bestandje in `src/main/resources/META-INF/openapi.json` te zetten en deze automatisch te laten serven. De plugin zal het bestandje automatisch uitbreiden met de relevante resources op basis van de Java annotations.
