OpenAPI

API documentation

This family of interpreters produces static documentation for endpoint definitions, in the form of an OpenAPI document.

Endpoints

The Endpoints interpreter provides an openApi method that takes as parameter a sequence of endpoints for which to generate an OpenAPI document.

Given the following endpoint definition:

sourceimport endpoints4s.algebra

trait DocumentedEndpoints extends algebra.Endpoints {

  val someDocumentedResource: Endpoint[Int, String] =
    endpoint(
      get(path / "some-resource" / segment[Int]("id")),
      ok(textResponse, docs = Some("The content of the resource"))
    )

}

It can be documented as follows:

sourceimport endpoints4s.openapi
import endpoints4s.openapi.model.{Info, OpenApi}

object EndpointsDocs extends DocumentedEndpoints with openapi.Endpoints {

  val api: OpenApi =
    openApi(Info(title = "API to get some resource", version = "1.0"))(
      someDocumentedResource
    )

}

The value returned by the openApi method has type endpoints4s.openapi.models.OpenApi, which is an abstract model for OpenAPI documents. You can encode it into JSON by using the OpenApi.stringEncoder encoder.

sourceval apiJson: String = OpenApi.stringEncoder.encode(api)

In case the endpoint that serves the documentation is itself defined using endpoints, you can use the JsonEntitiesFromEncoderAndDecoder interpreter to define an endpoint returning the OpenApi document as a JSON entity. Here is an example using Pekko HTTP:

sourceimport endpoints4s.openapi.model.OpenApi
import endpoints4s.pekkohttp.server

object DocumentationServer
    extends server.Endpoints
    with server.JsonEntitiesFromEncodersAndDecoders {

  val routes =
    endpoint(get(path / "documentation.json"), ok(jsonResponse[OpenApi]))
      .implementedBy(_ => CounterDocumentation.api)

}

Finally, the apiJson value contains the following JSON document:

{
  "openapi" : "3.0.0",
  "info" : {
    "title" : "API to get some resource",
    "version" : "1.0"
  },
  "paths" : {
    "/some-resource/{id}" : {
      "get" : {
        "parameters" : [
          {
            "name" : "id",
            "in" : "path",
            "schema" : {
              "type" : "integer"
            },
            "required" : true
          }
        ],
        "responses" : {
          "200" : {
            "description" : "The content of the resource",
            "content" : {
              "text/plain" : {
                "schema" : {
                  "type" : "string"
                }
              }
            }
          }
        }
      }
    }
  }
}

JSON entities

To properly document the underlying JSON schema of your JSON entities, you have to define these schemas by using the JsonEntitiesFromSchemas algebra (and its corresponding interpreter).