# servant-openapi-hs
[](https://hackage.haskell.org/package/servant-openapi-hs)
[](/LICENSE)
Generate an [OpenAPI 3.1](https://spec.openapis.org/oas/v3.1.0) specification for
your [Servant](https://github.com/haskell-servant/servant) API, and partially
test that the API conforms to its specification.
> **Fork notice.** `servant-openapi-hs` is a fork of
> [`biocad/servant-openapi3`](https://github.com/biocad/servant-openapi3), which
> targets OpenAPI 3.0. This fork retargets it at OpenAPI 3.1 by building on
> [`openapi-hs`](https://github.com/shinzui/openapi-hs) (a fork of
> [`biocad/openapi3`](https://github.com/biocad/openapi3)) instead of `openapi3`.
> The Haskell module namespace is unchanged (`Servant.OpenApi.*`), and because
> `openapi-hs` keeps the `Data.OpenApi.*` namespace, migrating is usually just a
> dependency-name swap: `servant-openapi3` → `servant-openapi-hs` and `openapi3` →
> `openapi-hs`. The fork keeps the upstream [BSD-3-Clause license](#license) and
> copyright.
---
## Motivation
OpenAPI is a language-agnostic format for describing and documenting HTTP APIs.
This package derives an OpenAPI 3.1 specification directly from a Servant API
type, so the description stays in sync with the server, and provides combinators
to test that handlers conform to the generated schema.
A generated specification can then be used to
- display interactive documentation in any OpenAPI 3.1 viewer;
- generate clients and servers in many languages with [OpenAPI Generator](https://openapi-generator.tech/);
- and many other things across the OpenAPI tooling ecosystem.
## Installation
`servant-openapi-hs` is available on
[Hackage](https://hackage.haskell.org/package/servant-openapi-hs). The `5.0`
series builds against `openapi-hs` 5; see the [changelog](CHANGELOG.md) for the
OpenAPI 3.1 port, `MultiVerb` support, and the `openapi-hs` 5 upgrade.
Add `servant-openapi-hs` to your package's `build-depends`:
```cabal
build-depends: servant-openapi-hs >= 5.0 && < 6
```
Its OpenAPI 3.1 data model comes from
[`openapi-hs`](https://hackage.haskell.org/package/openapi-hs), which is pulled
in automatically as a transitive dependency.
Import the umbrella module:
```haskell
import Servant.OpenApi
```
Requires GHC **9.12.4** or **9.14.1**.
<a id="building-from-source"></a>
> **Building from source.** To test unreleased changes, depend on this
> repository directly by adding a `source-repository-package` stanza for
> `servant-openapi-hs` to your `cabal.project`:
>
> ```cabal
> source-repository-package
> type: git
> location: https://github.com/shinzui/servant-openapi-hs.git
> tag: <commit-sha>
> ```
>
> Its `openapi-hs` dependency resolves from Hackage automatically.
## Usage
Derive an OpenAPI 3.1 document from a Servant API type with `toOpenApi`:
```haskell
import Data.Aeson (encode)
import Data.OpenApi (OpenApi)
import Data.Proxy (Proxy (..))
import Servant.OpenApi (toOpenApi)
spec :: OpenApi
spec = toOpenApi (Proxy :: Proxy MyApi)
-- encode spec ==> {"openapi":"3.1.0", ...}
```
A runnable example lives in [`app/GenOpenApi.hs`](app/GenOpenApi.hs), built as
the `gen-openapi` executable, which prints a complete Todo-CRUD document:
```bash
cabal run gen-openapi > openapi.json
```
The full API surface is unchanged from upstream; see the
[Haddock documentation](https://hackage.haskell.org/package/servant-openapi-hs).
Generated specifications can be explored interactively in any OpenAPI 3.1
viewer or editor.
## Validation
Generated documents are checked at three levels:
1. **Round-trip** — the test suite decodes each generated document back through
`openapi-hs`'s `FromJSON OpenApi`, which rejects any `openapi` version outside
`3.1.0 … 3.1.1`, then compares the result for semantic equality.
2. **Example-conformance** — `Servant.OpenApi.Test.validateEveryToJSON` checks
that random values of each response type validate against the generated
schema.
3. **Authoritative conformance** — the `gen-openapi` output lints cleanly under
[`vacuum`](https://quobix.com/vacuum/) (0 errors). On servant ≥ 0.20.3 the
API includes a `MultiVerb` endpoint, so this check also validates MultiVerb
rendering against the OpenAPI 3.1 spec:
```bash
cabal run gen-openapi > openapi.json
nix run nixpkgs#vacuum-go -- lint -d openapi.json
```
## Versioning
This package follows the Haskell
[Package Versioning Policy (PVP)](https://pvp.haskell.org/). Versions have the
form `A.B.C`, optionally followed by further components, where **`A.B` together
is the major version**: it changes only when the public API breaks. A release
that only adds to the API bumps `C`, and one that does not touch the API bumps a
fourth component `D`. The PVP-recommended bound is therefore:
```cabal
build-depends: servant-openapi-hs >=5.0 && <5.1
```
Releases up to and including `5.0.0` numbered themselves like SemVer; `4.1.0` in
particular was additive-only and would be `4.0.1` under the policy above. From
`5.0.0` onward the policy holds.
## License
`servant-openapi-hs` retains the original **BSD-3-Clause** license of the upstream
[`servant-openapi3`](https://github.com/biocad/servant-openapi3) project,
including its copyright. See the [`LICENSE`](/LICENSE) file for the full text;
this fork's changes are released under the same terms.
---
*Originally derived from work by the Servant contributors (David Johnson,
Nickolay Kudasov, Maxim Koltsov, and others).*