diff --git a/doc/SUMMARY.md b/doc/SUMMARY.md index d70d65e4..f0f2cce9 100644 --- a/doc/SUMMARY.md +++ b/doc/SUMMARY.md @@ -41,6 +41,7 @@ * [Route Data Validation](ring/route_data_validation.md) * [Compiling Middleware](ring/compiling_middleware.md) * [Swagger Support](ring/swagger.md) +* [OpenAPI Support](ring/openapi.md) * [RESTful form methods](ring/RESTful_form_methods.md) ## HTTP diff --git a/doc/cljdoc.edn b/doc/cljdoc.edn index 3ec69060..b03b0bd3 100644 --- a/doc/cljdoc.edn +++ b/doc/cljdoc.edn @@ -47,6 +47,7 @@ ["Route Data Validation" {:file "doc/ring/route_data_validation.md"}] ["Compiling Middleware" {:file "doc/ring/compiling_middleware.md"}] ["Swagger Support" {:file "doc/ring/swagger.md"}] + ["OpenAPI Support" {:file "doc/ring/openapi.md"}] ["RESTful form methods" {:file "doc/ring/RESTful_form_methods.md"}]] ["HTTP" {} ["Interceptors" {:file "doc/http/interceptors.md"}] diff --git a/doc/ring/coercion.md b/doc/ring/coercion.md index faed3a8b..930c10df 100644 --- a/doc/ring/coercion.md +++ b/doc/ring/coercion.md @@ -4,13 +4,14 @@ Basic coercion is explained in detail [in the Coercion Guide](../coercion/coerci The following request parameters are currently supported: -| type | request source | -|-----------|------------------| -| `:query` | `:query-params` | -| `:body` | `:body-params` | -| `:form` | `:form-params` | -| `:header` | `:header-params` | -| `:path` | `:path-params` | +| type | request source | +|------------|--------------------------------------------------| +| `:query` | `:query-params` | +| `:body` | `:body-params` | +| `:request` | `:body-params`, allows per-content-type coercion | +| `:form` | `:form-params` | +| `:header` | `:header-params` | +| `:path` | `:path-params` | To enable coercion, the following things need to be done: @@ -148,6 +149,30 @@ Invalid response: ; :in [:response :body]}} ``` +## Per-content-type coercion + +You can also specify request and response body schemas per content-type. The syntax for this is: + +```clj +(def app + (ring/ring-handler + (ring/router + ["/api" + ["/example" {:post {:coercion reitit.coercion.schema/coercion + :parameters {:request {:content {"application/json" {:y s/Int} + "application/edn" {:z s/Int}} + ;; default if no content-type matches: + :body {:yy s/Int}}} + :responses {200 {:content {"application/json" {:w s/Int} + "application/edn" {:x s/Int}} + ;; default if no content-type matches: + :body {:ww s/Int}} + :handler ...}}]] + {:data {:middleware [rrc/coerce-exceptions-middleware + rrc/coerce-request-middleware + rrc/coerce-response-middleware]}}))) +``` + ## Pretty printing spec errors Spec problems are exposed as is in request & response coercion errors. Pretty-printers like [expound](https://github.com/bhb/expound) can be enabled like this: diff --git a/doc/ring/content_negotiation.md b/doc/ring/content_negotiation.md index fb696c10..990e642d 100644 --- a/doc/ring/content_negotiation.md +++ b/doc/ring/content_negotiation.md @@ -84,6 +84,8 @@ Server: Jetty(9.2.21.v20170120) kukka ``` +You can also specify request and response schemas per content-type. See [Coercion](coercion.md) and [OpenAPI Support](openapi.md). + ## Changing default parameters diff --git a/doc/ring/openapi.md b/doc/ring/openapi.md new file mode 100644 index 00000000..ee6ffd72 --- /dev/null +++ b/doc/ring/openapi.md @@ -0,0 +1,51 @@ +# OpenAPI Support + +Reitit can generate [OpenAPI 3.1.0](https://spec.openapis.org/oas/v3.1.0) +documentation. The feature works similarly to [Swagger documentation](swagger.md). + +The [http-swagger example](../../examples/http-swagger) also has OpenAPI documentation. + +## OpenAPI data + +The following route data keys contribute to the generated swagger specification: + +| key | description | +| ---------------|-------------| +| :openapi | map of any openapi data. Can contain keys like `:deprecated`. +| :content-types | vector of supported content types. Defaults to `["application/json"]` +| :no-doc | optional boolean to exclude endpoint from api docs +| :tags | optional set of string or keyword tags for an endpoint api docs +| :summary | optional short string summary of an endpoint +| :description | optional long description of an endpoint. Supports http://spec.commonmark.org/ + +Coercion keys also contribute to the docs: + +| key | description | +| --------------|-------------| +| :parameters | optional input parameters for a route, in a format defined by the coercion +| :responses | optional descriptions of responses, in a format defined by coercion + +Use `:request` parameter coercion (instead of `:body`) to unlock per-content-type coercions. See [Coercion](coercion.md). + +## Swagger spec + +Serving the OpenAPI specification is handled by `reitit.openapi/create-openapi-handler`. It takes no arguments and returns a ring handler which collects at request-time data from all routes and returns an OpenAPI specification as Clojure data, to be encoded by a response formatter. + +You can use the `:openapi` route data key of the `create-openapi-handler` route to populate the top level of the OpenAPI spec. + +Example: + +``` +["/openapi.json" + {:get {:handler (openapi/create-openapi-handler) + :openapi {:info {:title "my nice api" :version "0.0.1"}} + :no-doc true}}] +``` + +If you need to post-process the generated spec, just wrap the handler with a custom `Middleware` or an `Interceptor`. + +## Swagger-ui + +[Swagger-ui](https://github.com/swagger-api/swagger-ui) is a user interface to visualize and interact with the Swagger specification. To make things easy, there is a pre-integrated version of the swagger-ui as a separate module. + +- TIP: downgrade to 3.0.0 if needed diff --git a/doc/ring/swagger.md b/doc/ring/swagger.md index 5ad40b80..d576512b 100644 --- a/doc/ring/swagger.md +++ b/doc/ring/swagger.md @@ -6,6 +6,8 @@ Reitit supports [Swagger2](https://swagger.io/) documentation, thanks to [schema-tools](https://github.com/metosin/schema-tools) and [spec-tools](https://github.com/metosin/spec-tools). Documentation is extracted from route definitions, coercion `:parameters` and `:responses` and from a set of new documentation keys. +See also: [OpenAPI support](openapi.md). + To enable swagger-documentation for a Ring router: 1. annotate your routes with swagger-data