<commit_before>[[Swagger]]
== Swagger / OpenAPI integration

_Swagger V2 Maven coordinates_:
[source, xml, subs="attributes+"]
----
<groupId>com.holon-platform.jaxrs</groupId>
<artifactId>holon-jaxrs-swagger-v2</artifactId>
<version>{revnumber}</version>
----

_Swagger/OpenAPI V3 Maven coordinates_:
[source, xml, subs="attributes+"]
----
<groupId>com.holon-platform.jaxrs</groupId>
<artifactId>holon-jaxrs-swagger-v3</artifactId>
<version>{revnumber}</version>
----

The `holon-jaxrs-swagger-v2` and `holon-jaxrs-swagger-v3` artifacts provide integration with the  link:http://swagger.io[Swagger^] _OpenAPI Specification_, for the *Swagger Version 2* and the *Swagger/OpenAPI Version 3* specifications respectively.

WARNING: The Holon Platform 5.1.x `holon-jaxrs-swagger` artifact is *deprecated* and should be replaced with the `holon-jaxrs-swagger-v2` artifact. The `holon-jaxrs-swagger` is still available in Holon Platform version 5.2.x, acting as an alias only for backward compatibility purposes.

The integration facilities concerns the following aspects:

* A complete integration with the Holon Platform *Property model* data types, specifically with the link:holon-core.html#PropertyBox[PropertyBox^] type, ensuring a consistent representation and serialization using the Swagger/OpenAPI definition models. See <<PropertyBoxModel>>.

* A convenient `ApiReader` API to obtain a Swagger/OpenAPI definition from a set of API resource classes.  See <<ApiReader>>.

* A complete and highly configurable *Spring Boot* integration, with auto-configuration facilities for both *Jersey* and *Resteasy* JAX-RS runtimes. See <<SwaggerSpringBoot>>.

TIP: The Swagger/OpenAPI integration architecture is designed to be highly consistent between the Swagger/OpenAPI versions 2 and 3, so in most cases it is enough to put the `holon-jaxrs-swagger-v2` or the `holon-jaxrs-swagger-v3` artifact in classpath to enable the integration features. Or even both: see <<V2andV3>>.

[[PropertyBoxModel]]
=== `PropertyBox` data type support

When the `holon-jaxrs-swagger-v2` or the `holon-jaxrs-swagger-v3` artifact is in classpath, the Swagger/OpenAPI reader engine is automatically configured to support the `PropertyBox` type as API operations parameter or return type.

IMPORTANT: If you programmatically use the Swagger/OpenAPI reader or context configuration classes to generate the API definition model, you have to include a proper `ReaderListener` class in the API resource classes to ensure a consistent `PropertyBox` type handling. This class is available from the `CONTEXT_READER_LISTENER` static attribute of the  
link:{apidir}/com/holonplatform/jaxrs/swagger/v2/SwaggerV2.html[SwaggerV2^] interface for the Swagger V2 integration and of the link:{apidir}/com/holonplatform/jaxrs/swagger/v3/SwaggerV3.html[SwaggerV3^] interface for the Swagger/OpenAPI V3 integration.

TIP: When the <<SwaggerSpringBoot,Spring Boot integration>> is enabled or an <<ApiReader,ApiReader>> is used, the Swagger/OpenAPI engine is automatically configured for a consistent `PropertyBox` type support.

[[PropertySetRef]]
==== `PropertyBox` property set declaration

A `PropertyBox` type API parameter or return type is translated in a regular Swagger/OpenAPI _object_ type Model/Schema definition, listing all the properties of the `PropertyBox` *property set* as object attributes.

NOTE: By default, only the `Path` type properties are included in the API definition _models_/_schemas_, using the `Path` *name* as model/schema attribute name and the property *type* as model/schema attribute type.

Since a `PropertyBox` type class does not provide a fixed link:holon-core.html#PropertySet[PropertySet] decalration, the link:{coreapidir}/com/holonplatform/core/property/PropertySetRef.html[PropertySetRef^] *annotation has to be used* to declare the `PropertySet` to use to translate the `PropertyBox` type into an API model/schema definition. The annotation has to be placed on the `PropertyBox` type method parameters and/or method return types.

The `PropertySetRef` annotation *value* can be either:
* A class which contains the `PropertySet` instance as a `public static` field.
* A `PropertySet` type class: in this case, a new instance of such class will be used.

When the first option is used and more than one `PropertySet` type static field is available in the provided class, the *field* annotation attribute can be used to specify the field name to use.

[[Subjects]]
For example, given the following `SubjectModel` interface, which contains a data model declaration for a simple subject entity:

[source, java]
----
include::{examplesdir}/com/holonplatform/jaxrs/examples/ExampleSwagger.java[tag=model,indent=0]
----
<1> `PropertySet` definition

The `SUBJECT` field can be used as `PropertyBox` property set definition in a JAX-RS API endpoint like this:

[source, java]
----
include::{examplesdir}/com/holonplatform/jaxrs/examples/ExampleSwagger.java[tag=propertyset,indent=0]
----
<1> Declare the `PropertySet` to use for the `getById` operation *return type*, using the `PropertySetRef` annotation
<2> Declare the `PropertySet` to use for the `create` operation *body parameter*, using the `PropertySetRef` annotation

Since the `SUBJECT` field is the unique `PropertySet` type static field of the `SubjectModel` interface, no additional *field* name specification is required in the `PropertySetRef` annotation.

In this example, the generated API definition will look like this (using the YAML format):

.Swagger 2 specification:
[source, yaml]
----
swagger: "2.0"
paths:
  /subjects/{id}:
    get:
      operationId: "getById"
      produces:
      - "application/json"
      parameters:
      - name: "id"
        in: "path"
        required: true
        type: "integer"
        format: "int32"
      responses:
        200:
          description: "successful operation"
          headers: {}
          schema:
            type: "object"
            properties:
              id:
                type: "integer"
                format: "int32"
              name:
                type: "string"
            title: "PropertyBox"
  /subjects:
    put:
      operationId: "create"
      consumes:
      - "application/json"
      parameters:
      - in: "body"
        name: "body"
        required: false
        schema:
          type: "object"
          properties:
            id:
              type: "integer"
              format: "int32"
            name:
              type: "string"
          title: "PropertyBox"
      responses:
        default:
          description: "successful operation"
definitions: {}
----

.Swagger/OpenAPI 3 specification:
[source, yaml]
----
openapi: 3.0.1
paths:
  /subjects/{id}:
    get:
      operationId: getById
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: integer
          format: int32
      responses:
        default:
          description: default response
          content:
            application/json:
              schema:
                title: PropertyBox
                type: object
                properties:
                  id:
                    type: integer
                    format: int32
                  name:
                    type: string
  /subjects:
    put:
      operationId: create
      requestBody:
        content:
          application/json:
            schema:
              title: PropertyBox
              type: object
              properties:
                id:
                  type: integer
                  format: int32
                name:
                  type: string
      responses:
        default:
          description: default response
          content:
            '*/*': {}
components:
  schemas: {}
----

See the next section to learn how to include a `PropertyBox` type model/schema in the Swagger API definition `definitions` (for Swagger V2) or `components/schemas` (for Swagger V3).

[[PropertyBoxModelDefinition]]
==== Creating a Swagger Model/Schema definition for a `PropertyBox` type

When the `PropertySetRef` annotation is used, a generic Swagger _object_ type model/schema definition is generated for each API response or API operation parameter, using the property set definition to generate the schema properties.

To include a `PropertyBox` type as a _named_ model/schema in the Swagger API definition (i.e. to create a type declaration in the `definitions` section for Swagger V2 or in the `components/schemas` section for Swagger V3), the link:{apidir}/com/holonplatform/jaxrs/swagger/annotations/ApiPropertySetModel.html[ApiPropertySetModel^] annotation can be used.

The `ApiPropertySetModel` *value* attribute is used to specify the model/schema _name_. When a `PropertyBox` type model is declared this way, its name will be used as a _reference_ in the API operation components which use it.

The `ApiPropertySetModel` annotation should be always used in conjunction with the `PropertySetRef` annotation, which provides the property set declaration.

TIP: To make the API enpoints code more readable and to ensure a consistent property set and model name definition, the `PropertySetRef` and `ApiPropertySetModel` annotations can be used as meta-annotations to create specific annotations to be used in the API endpoints code. See below for an example.

Taking the <<Subjects,Subjects>> example endpoint declaration, we can create a `Subject` annotation to declare the `PropertySet` to use and a model/schema definition named `Subject` this way:

[source, java]
----
include::{examplesdir}/com/holonplatform/jaxrs/examples/ExampleSwagger.java[tag=apimodel1,indent=0]
----
<1> `PropertySet` reference declaration
<2> Model/Schema *name* definition

Next, the `Subject` annotation is used in the JAX-RS endpoint instead of the simple `PropertySetRef` annotation:

[source, java]
----
include::{examplesdir}/com/holonplatform/jaxrs/examples/ExampleSwagger.java[tag=apimodel2,indent=0]
----
<1> Declare the `Subject` model definition for the `getById` operation *return type*
<2> Declare the `Subject` model definition for the `create` operation *body parameter*

The generated API definition will include a `Subject` model/schema definition and will look like this:

.Swagger 2 specification:
[source, yaml]
----
swagger: "2.0"
paths:
  /subjects/{id}:
    get:
      operationId: "getById"
      produces:
      - "application/json"
      parameters:
      - name: "id"
        in: "path"
        required: true
        type: "integer"
        format: "int32"
      responses:
        200:
          description: "successful operation"
          headers: {}
          schema:
            $ref: "#/definitions/Subject"
  /subjects:
    put:
      operationId: "create"
      consumes:
      - "application/json"
      parameters:
      - in: "body"
        name: "body"
        required: false
        schema:
          $ref: "#/definitions/Subject"
      responses:
        default:
          description: "successful operation"
definitions:
  Subject:
    type: "object"
    properties:
      id:
        type: "integer"
        format: "int32"
      name:
        type: "string"
    title: "Subject"
----

.Swagger/OpenAPI 3 specification:
[source, yaml]
----
openapi: 3.0.1
paths:
  /subjects/{id}:
    get:
      operationId: getById
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: integer
          format: int32
      responses:
        default:
          description: default response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Subject'
  /subjects:
    put:
      operationId: create
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Subject'
      responses:
        default:
          description: default response
          content:
            '*/*': {}
components:
  schemas:
    Subject:
      title: Subject
      type: object
      properties:
        id:
          type: integer
          format: int32
        name:
          type: string
----

In the API definition, the API operation return types or body parameters annotated with the `Subject` annotation declarations provide a *reference* to the `Subject` model/schema definition.

[[ApiReader]]
=== Using the `ApiReader` to generate the API definition model

The link:{apidir}/com/holonplatform/jaxrs/swagger/ApiReader.html[ApiReader^] service can be used to directly generate a Swagger API definition model from a set of JAX-RS API resource classes, ensuring a consistent Swagger engine configuration with the Holon Platform property model support.

The `read(Set<Class<?>> classes)` method reads and generates a Swagger API definition model which includes the given API resource classes operations.

==== Swagger version 2 `ApiReader`

The link:{apidir}/com/holonplatform/jaxrs/swagger/v2/SwaggerV2.html[SwaggerV2^] entrypoint interface can be used to obtain an `ApiReader`, using a `SwaggerConfig` type configuration definition and providing a `io.swagger.models.Swagger` type API definition model.

Furthermore, the `SwaggerV2` interface provides a set of convenience methods to serialize the Swagger model using *JSON* (through the `asJson(...)` methods) or *YAML* (through the `asYaml(...)` methods).

[source, java]
----
include::{examplesdir}/com/holonplatform/jaxrs/examples/ExampleSwagger.java[tag=apireaderv2,indent=0]
----
<1> Obtain a `ApiReader` using the provided configuration
<2> Generate the Swagger API model from given API resource classes
<3> Serialize the API model using JSON
<4> Serialize the API model using YAML

==== Swagger/OpenAPI version 3 `ApiReader`

The link:{apidir}/com/holonplatform/jaxrs/swagger/v3/SwaggerV3.html[SwaggerV3^] entrypoint interface can be used to obtain an `ApiReader`, using a `OpenAPIConfiguration` type configuration definition and providing a `io.swagger.v3.oas.models.OpenAPI` type API definition model.

Furthermore, the `SwaggerV3` interface provides a set of convenience methods to serialize the Swagger/OpenAPI model using *JSON* (through the `asJson(...)` methods) or *YAML* (through the `asYaml(...)` methods).

[source, java]
----
include::{examplesdir}/com/holonplatform/jaxrs/examples/ExampleSwagger.java[tag=apireaderv3,indent=0]
----
<1> Obtain a `ApiReader` using the provided configuration
<2> Generate the OpenAPI model from given API resource classes
<3> Serialize the API model using JSON
<4> Serialize the API model using YAML

[[SwaggerSpringBoot]]
=== Swagger Spring Boot integration and auto configuration

The `holon-jaxrs-swagger-v2` and `holon-jaxrs-swagger-v3` artifacts provide a set of *Spring Boot* auto-configuration classes to automatically configure *Swagger API definition JAX-RS endpoints* for Swagger/OpenAPI version 2 and version 3 respectively, using the Spring Boot application JAX-RS API endpoints classes as API definition sources.

Both *Jersey* and *Resteasy* JAX-RS runtimes are supported.

==== Prerequisites

To enable the Swagger Spring Boot auto-configuration facilities, just include in classpath the `holon-jaxrs-swagger-v2` artifact for Swagger version 2 integration and `holon-jaxrs-swagger-v3` artifact for Swagger/OpenAPI version 3 integration.

NOTE: It is perfectly safe to include *both* `holon-jaxrs-swagger-v2` and `holon-jaxrs-swagger-v3` artifacts in order to enable the Swagger version 2 and version 3 integration simultaneously. See <<V2andV3>> for JAX-RS API definition endpoints _path_ naming considerations.

The Swagger API definition endpoints auto-configuration is triggered when the following conditions are satisfied:

* When the *Jersey* JAX-RS runtime is used, a `org.glassfish.jersey.server.ResourceConfig` type bean must be available in context.

* When the *Resteasy* JAX-RS runtime is used, a `com.holonplatform.jaxrs.spring.boot.resteasy.ResteasyConfig` type bean must be available in context.

TIP: When the Holon Platform JAX-RS Spring Boot integration is available, a `ResourceConfig` or `ResteasyConfig` type bean can be automatically configured, including the automatic registration of the `@Path` annotated JAX-RS endpoint classes declared as Spring beans. See the link:holon-jaxrs.html#JaxrsSpringBoot[JAX-RS Spring Boot integration documentation^] section.
<commit_msg>Swagger V2/V3 integration documentation (wip)<commit_after>[[Swagger]]
== Swagger / OpenAPI integration

_Swagger V2 Maven coordinates_:
[source, xml, subs="attributes+"]
----
<groupId>com.holon-platform.jaxrs</groupId>
<artifactId>holon-jaxrs-swagger-v2</artifactId>
<version>{revnumber}</version>
----

_Swagger/OpenAPI V3 Maven coordinates_:
[source, xml, subs="attributes+"]
----
<groupId>com.holon-platform.jaxrs</groupId>
<artifactId>holon-jaxrs-swagger-v3</artifactId>
<version>{revnumber}</version>
----

The `holon-jaxrs-swagger-v2` and `holon-jaxrs-swagger-v3` artifacts provide integration with the  link:http://swagger.io[Swagger^] _OpenAPI Specification_, for the *Swagger Version 2* and the *Swagger/OpenAPI Version 3* specifications respectively.

WARNING: The Holon Platform 5.1.x `holon-jaxrs-swagger` artifact is *deprecated* and should be replaced with the `holon-jaxrs-swagger-v2` artifact. The `holon-jaxrs-swagger` is still available in Holon Platform version 5.2.x, acting as an alias only for backward compatibility purposes.

The integration facilities concerns the following aspects:

* A complete integration with the Holon Platform *Property model* data types, specifically with the link:holon-core.html#PropertyBox[PropertyBox^] type, ensuring a consistent representation and serialization using the Swagger/OpenAPI definition models. See <<PropertyBoxModel>>.

* A convenient `ApiReader` API to obtain a Swagger/OpenAPI definition from a set of API resource classes.  See <<ApiReader>>.

* A complete and highly configurable *Spring Boot* integration, with auto-configuration facilities for both *Jersey* and *Resteasy* JAX-RS runtimes. See <<SwaggerSpringBoot>>.

TIP: The Swagger/OpenAPI integration architecture is designed to be highly consistent between the Swagger/OpenAPI versions 2 and 3, so in most cases it is enough to put the `holon-jaxrs-swagger-v2` or the `holon-jaxrs-swagger-v3` artifact in classpath to enable the integration features. Or even both: see <<V2andV3>>.

[[PropertyBoxModel]]
=== `PropertyBox` data type support

When the `holon-jaxrs-swagger-v2` or the `holon-jaxrs-swagger-v3` artifact is in classpath, the Swagger/OpenAPI reader engine is automatically configured to support the `PropertyBox` type as API operations parameter or return type.

IMPORTANT: If you programmatically use the Swagger/OpenAPI reader or context configuration classes to generate the API definition model, you have to include a proper `ReaderListener` class in the API resource classes to ensure a consistent `PropertyBox` type handling. This class is available from the `CONTEXT_READER_LISTENER` static attribute of the  
link:{apidir}/com/holonplatform/jaxrs/swagger/v2/SwaggerV2.html[SwaggerV2^] interface for the Swagger V2 integration and of the link:{apidir}/com/holonplatform/jaxrs/swagger/v3/SwaggerV3.html[SwaggerV3^] interface for the Swagger/OpenAPI V3 integration.

TIP: When the <<SwaggerSpringBoot,Spring Boot integration>> is enabled or an <<ApiReader,ApiReader>> is used, the Swagger/OpenAPI engine is automatically configured for a consistent `PropertyBox` type support.

[[PropertySetRef]]
==== `PropertyBox` property set declaration

A `PropertyBox` type API parameter or return type is translated in a regular Swagger/OpenAPI _object_ type Model/Schema definition, listing all the properties of the `PropertyBox` *property set* as object attributes.

NOTE: By default, only the `Path` type properties are included in the API definition _models_/_schemas_, using the `Path` *name* as model/schema attribute name and the property *type* as model/schema attribute type.

Since a `PropertyBox` type class does not provide a fixed link:holon-core.html#PropertySet[PropertySet] decalration, the link:{coreapidir}/com/holonplatform/core/property/PropertySetRef.html[PropertySetRef^] *annotation has to be used* to declare the `PropertySet` to use to translate the `PropertyBox` type into an API model/schema definition. The annotation has to be placed on the `PropertyBox` type method parameters and/or method return types.

The `PropertySetRef` annotation *value* can be either:
* A class which contains the `PropertySet` instance as a `public static` field.
* A `PropertySet` type class: in this case, a new instance of such class will be used.

When the first option is used and more than one `PropertySet` type static field is available in the provided class, the *field* annotation attribute can be used to specify the field name to use.

[[Subjects]]
For example, given the following `SubjectModel` interface, which contains a data model declaration for a simple subject entity:

[source, java]
----
include::{examplesdir}/com/holonplatform/jaxrs/examples/ExampleSwagger.java[tag=model,indent=0]
----
<1> `PropertySet` definition

The `SUBJECT` field can be used as `PropertyBox` property set definition in a JAX-RS API endpoint like this:

[source, java]
----
include::{examplesdir}/com/holonplatform/jaxrs/examples/ExampleSwagger.java[tag=propertyset,indent=0]
----
<1> Declare the `PropertySet` to use for the `getById` operation *return type*, using the `PropertySetRef` annotation
<2> Declare the `PropertySet` to use for the `create` operation *body parameter*, using the `PropertySetRef` annotation

Since the `SUBJECT` field is the unique `PropertySet` type static field of the `SubjectModel` interface, no additional *field* name specification is required in the `PropertySetRef` annotation.

In this example, the generated API definition will look like this (using the YAML format):

.Swagger 2 specification:
[source, yaml]
----
swagger: "2.0"
paths:
  /subjects/{id}:
    get:
      operationId: "getById"
      produces:
      - "application/json"
      parameters:
      - name: "id"
        in: "path"
        required: true
        type: "integer"
        format: "int32"
      responses:
        200:
          description: "successful operation"
          headers: {}
          schema:
            type: "object"
            properties:
              id:
                type: "integer"
                format: "int32"
              name:
                type: "string"
            title: "PropertyBox"
  /subjects:
    put:
      operationId: "create"
      consumes:
      - "application/json"
      parameters:
      - in: "body"
        name: "body"
        required: false
        schema:
          type: "object"
          properties:
            id:
              type: "integer"
              format: "int32"
            name:
              type: "string"
          title: "PropertyBox"
      responses:
        default:
          description: "successful operation"
definitions: {}
----

.Swagger/OpenAPI 3 specification:
[source, yaml]
----
openapi: 3.0.1
paths:
  /subjects/{id}:
    get:
      operationId: getById
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: integer
          format: int32
      responses:
        default:
          description: default response
          content:
            application/json:
              schema:
                title: PropertyBox
                type: object
                properties:
                  id:
                    type: integer
                    format: int32
                  name:
                    type: string
  /subjects:
    put:
      operationId: create
      requestBody:
        content:
          application/json:
            schema:
              title: PropertyBox
              type: object
              properties:
                id:
                  type: integer
                  format: int32
                name:
                  type: string
      responses:
        default:
          description: default response
          content:
            '*/*': {}
components:
  schemas: {}
----

See the next section to learn how to include a `PropertyBox` type model/schema in the Swagger API definition `definitions` (for Swagger V2) or `components/schemas` (for Swagger V3).

[[PropertyBoxModelDefinition]]
==== Creating a Swagger Model/Schema definition for a `PropertyBox` type

When the `PropertySetRef` annotation is used, a generic Swagger _object_ type model/schema definition is generated for each API response or API operation parameter, using the property set definition to generate the schema properties.

To include a `PropertyBox` type as a _named_ model/schema in the Swagger API definition (i.e. to create a type declaration in the `definitions` section for Swagger V2 or in the `components/schemas` section for Swagger V3), the link:{apidir}/com/holonplatform/jaxrs/swagger/annotations/ApiPropertySetModel.html[ApiPropertySetModel^] annotation can be used.

The `ApiPropertySetModel` *value* attribute is used to specify the model/schema _name_. When a `PropertyBox` type model is declared this way, its name will be used as a _reference_ in the API operation components which use it.

The `ApiPropertySetModel` annotation should be always used in conjunction with the `PropertySetRef` annotation, which provides the property set declaration.

TIP: To make the API enpoints code more readable and to ensure a consistent property set and model name definition, the `PropertySetRef` and `ApiPropertySetModel` annotations can be used as meta-annotations to create specific annotations to be used in the API endpoints code. See below for an example.

Taking the <<Subjects,Subjects>> example endpoint declaration, we can create a `Subject` annotation to declare the `PropertySet` to use and a model/schema definition named `Subject` this way:

[source, java]
----
include::{examplesdir}/com/holonplatform/jaxrs/examples/ExampleSwagger.java[tag=apimodel1,indent=0]
----
<1> `PropertySet` reference declaration
<2> Model/Schema *name* definition

Next, the `Subject` annotation is used in the JAX-RS endpoint instead of the simple `PropertySetRef` annotation:

[source, java]
----
include::{examplesdir}/com/holonplatform/jaxrs/examples/ExampleSwagger.java[tag=apimodel2,indent=0]
----
<1> Declare the `Subject` model definition for the `getById` operation *return type*
<2> Declare the `Subject` model definition for the `create` operation *body parameter*

The generated API definition will include a `Subject` model/schema definition and will look like this:

.Swagger 2 specification:
[source, yaml]
----
swagger: "2.0"
paths:
  /subjects/{id}:
    get:
      operationId: "getById"
      produces:
      - "application/json"
      parameters:
      - name: "id"
        in: "path"
        required: true
        type: "integer"
        format: "int32"
      responses:
        200:
          description: "successful operation"
          headers: {}
          schema:
            $ref: "#/definitions/Subject"
  /subjects:
    put:
      operationId: "create"
      consumes:
      - "application/json"
      parameters:
      - in: "body"
        name: "body"
        required: false
        schema:
          $ref: "#/definitions/Subject"
      responses:
        default:
          description: "successful operation"
definitions:
  Subject:
    type: "object"
    properties:
      id:
        type: "integer"
        format: "int32"
      name:
        type: "string"
    title: "Subject"
----

.Swagger/OpenAPI 3 specification:
[source, yaml]
----
openapi: 3.0.1
paths:
  /subjects/{id}:
    get:
      operationId: getById
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: integer
          format: int32
      responses:
        default:
          description: default response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Subject'
  /subjects:
    put:
      operationId: create
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Subject'
      responses:
        default:
          description: default response
          content:
            '*/*': {}
components:
  schemas:
    Subject:
      title: Subject
      type: object
      properties:
        id:
          type: integer
          format: int32
        name:
          type: string
----

In the API definition, the API operation return types or body parameters annotated with the `Subject` annotation declarations provide a *reference* to the `Subject` model/schema definition.

[[ApiReader]]
=== Using the `ApiReader` to generate the API definition model

The link:{apidir}/com/holonplatform/jaxrs/swagger/ApiReader.html[ApiReader^] service can be used to directly generate a Swagger API definition model from a set of JAX-RS API resource classes, ensuring a consistent Swagger engine configuration with the Holon Platform property model support.

The `read(Set<Class<?>> classes)` method reads and generates a Swagger API definition model which includes the given API resource classes operations.

==== Swagger version 2 `ApiReader`

The link:{apidir}/com/holonplatform/jaxrs/swagger/v2/SwaggerV2.html[SwaggerV2^] entrypoint interface can be used to obtain an `ApiReader`, using a `SwaggerConfig` type configuration definition and providing a `io.swagger.models.Swagger` type API definition model.

Furthermore, the `SwaggerV2` interface provides a set of convenience methods to serialize the Swagger model using *JSON* (through the `asJson(...)` methods) or *YAML* (through the `asYaml(...)` methods).

[source, java]
----
include::{examplesdir}/com/holonplatform/jaxrs/examples/ExampleSwagger.java[tag=apireaderv2,indent=0]
----
<1> Obtain a `ApiReader` using the provided configuration
<2> Generate the Swagger API model from given API resource classes
<3> Serialize the API model using JSON
<4> Serialize the API model using YAML

==== Swagger/OpenAPI version 3 `ApiReader`

The link:{apidir}/com/holonplatform/jaxrs/swagger/v3/SwaggerV3.html[SwaggerV3^] entrypoint interface can be used to obtain an `ApiReader`, using a `OpenAPIConfiguration` type configuration definition and providing a `io.swagger.v3.oas.models.OpenAPI` type API definition model.

Furthermore, the `SwaggerV3` interface provides a set of convenience methods to serialize the Swagger/OpenAPI model using *JSON* (through the `asJson(...)` methods) or *YAML* (through the `asYaml(...)` methods).

[source, java]
----
include::{examplesdir}/com/holonplatform/jaxrs/examples/ExampleSwagger.java[tag=apireaderv3,indent=0]
----
<1> Obtain a `ApiReader` using the provided configuration
<2> Generate the OpenAPI model from given API resource classes
<3> Serialize the API model using JSON
<4> Serialize the API model using YAML

[[SwaggerSpringBoot]]
=== Swagger Spring Boot integration and auto configuration

The `holon-jaxrs-swagger-v2` and `holon-jaxrs-swagger-v3` artifacts provide a set of *Spring Boot* auto-configuration classes to automatically configure *Swagger API definition JAX-RS endpoints* for Swagger/OpenAPI version 2 and version 3 respectively, using the Spring Boot application JAX-RS API endpoints classes as API definition sources.

Both *Jersey* and *Resteasy* JAX-RS runtimes are supported.

==== Prerequisites

To enable the Swagger Spring Boot auto-configuration facilities, just include in classpath the `holon-jaxrs-swagger-v2` artifact for Swagger version 2 integration and `holon-jaxrs-swagger-v3` artifact for Swagger/OpenAPI version 3 integration.

NOTE: It is perfectly safe to include *both* `holon-jaxrs-swagger-v2` and `holon-jaxrs-swagger-v3` artifacts in order to enable the Swagger version 2 and version 3 integration simultaneously. See <<V2andV3>> for JAX-RS API definition endpoints _path_ naming considerations.

The Swagger API definition endpoints auto-configuration is triggered when the following conditions are satisfied:

* When the *Jersey* JAX-RS runtime is used, a `org.glassfish.jersey.server.ResourceConfig` type bean must be available in context.

* When the *Resteasy* JAX-RS runtime is used, a `com.holonplatform.jaxrs.spring.boot.resteasy.ResteasyConfig` type bean must be available in context.

TIP: When the Holon Platform JAX-RS Spring Boot integration is available, a `ResourceConfig` or `ResteasyConfig` type bean can be automatically configured, including the automatic registration of the `@Path` annotated JAX-RS endpoint classes declared as Spring beans. See the link:holon-jaxrs.html#JaxrsSpringBoot[JAX-RS Spring Boot integration documentation^] section.

==== Default API endpoints configuration strategy

By default, any `@Path` annotated JAX-RS endpoint class registered in the JAX-RS `javax.ws.rs.core.Application` is included in the Swagger API definition.

A JAX-RS *Swagger API definition* endpoint class in generated and registered in the current JAX-RS runtime to provide the Swagger API definition either in *JSON* or *YAML* format.

By default, the Swagger API definition endpoint will be available at the `/api-docs` path and a `type` named URL *query parameter* can be used to declare the API output format, which can be either `json` or `yaml`.

Depending on the `holon-jaxrs-swagger-v2` or `holon-jaxrs-swagger-v3` artifact presence in classpath, the Swagger API definition output will be provided either in version 2 or version 3 specification format.

For example, given a Maven project whith the following dependencies in the `pom.xml` file:

[source, xml, subs="attributes+"]
----
<dependencies>
  <!-- Optional Holon JAX-RS starter using Jersey -->
  <dependency>
    <groupId>com.holon-platform.jaxrs</groupId>
    <artifactId>holon-starter-jersey</artifactId>
    <version>{revnumber}</version>
  </dependency>
  <!-- Swagger V3 integration -->
    <dependency>
      <groupId>com.holon-platform.jaxrs</groupId>
      <artifactId>holon-jaxrs-swagger-v3</artifactId>
      <version>{revnumber}</version>
    </dependency>
</dependencies>
----

A Swagger API definition endpoint will be automatically configured and mapped to the `/api-docs` path. Supposing the application is available from `localhost`, the API definition can be obtained from the following URL:

.JSON format:
[source, text]
----
http://localhost/api-docs?type=json
----

.YAML format:
[source, text]
----
http://localhost/api-docs?type=yaml
----

The Swagger Spring Boot integration can be widely configured, either using explicit configuration beans or the `holon.swagger.*` configuration property set. See the next sections for the available configuration options.

==== API definition endpoint types

The following Swagger API definition JAX-RS endpoint types are available:



==== API resources scan strategy

TBD

==== API configuration using beans

TBD

==== API configuration using application properties

TBD

{'fraction_non_alphanumeric': 0.08783841611274355, 'fraction_numerical': 0.0072461700852994035, 'mean_word_length': 3.397139989964877, 'pattern_counts': {'":': 0, '<': 113, '<?xml version=': 0, '>': 113, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 6}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4888738', 'n_tokens_mistral': 9671, 'n_tokens_neox': 9353, 'n_words': 3690}