diff --git a/docs/about/additional_info.adoc b/docs/about/additional_info.adoc new file mode 100644 index 00000000000..e81d146e678 --- /dev/null +++ b/docs/about/additional_info.adoc @@ -0,0 +1,20 @@ +/////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2023 Oracle and/or its affiliates. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +/////////////////////////////////////////////////////////////////////////////// + += Learn More About Helidon + diff --git a/docs/about/benefits.adoc b/docs/about/benefits.adoc new file mode 100644 index 00000000000..fc6f01488a4 --- /dev/null +++ b/docs/about/benefits.adoc @@ -0,0 +1,19 @@ +/////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2023 Oracle and/or its affiliates. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +/////////////////////////////////////////////////////////////////////////////// + += Features and Benefits of Helidon \ No newline at end of file diff --git a/docs/about/doc_overview.adoc b/docs/about/doc_overview.adoc new file mode 100644 index 00000000000..5ce044d23fc --- /dev/null +++ b/docs/about/doc_overview.adoc @@ -0,0 +1,143 @@ +/////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2018, 2023 Oracle and/or its affiliates. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +/////////////////////////////////////////////////////////////////////////////// + += Documentation Overview +:description: Helidon +:keywords: helidon, java, microservices, microprofile +:rootdir: {docdir}/.. + +include::{rootdir}/includes/attributes.adoc[] + +This is test to see if this displays. Can we add some text about what's included in the docs? + +[PILLARS] +==== +//Introduction to Helidon +[CARD] +.Introduction to Helidon +[icon=lightbulb] +-- +New to Helidon? Start here to learn how Helidon's open-source set of Java libraries can help you write cloud-native Java microservices. + +xref:{rootdir}/about/introduction.adoc[What is Helidon?] + +xref:{rootdir}/about/benefits.adoc[Features and Benefits] + +xref:{rootdir}/about/archetype.adoc[Helidon Archetypes] + +xref:{rootdir}/about/additional_info.adoc[Reference and Community Resources] + +xref:{rootdir}/about/intro.adoc[What's New in Helidon 4] + + +-- +//Getting Started +[CARD] +.Getting Started +[icon=settings] +-- +There are several ways to generate your first Helidon project. In a hurry? The Helidon CLI and Project Starter provide a set of predefined archetypes to choose from. Or try the Quickstart guides for the standard Helidon Maven archetypes. + +xref:{rootdir}/about/prerequisites.adoc[Prerequisites and System Requirements] + +xref:{rootdir}/about/cli.adoc[Using the Helidon CLI] + +xref:{rootdir}/about/generating_project.adoc[Using Project Starter] + +xref:{rootdir}/mp/guides/quickstart.adoc[Using the MP Quickstart Guide] + +xref:{rootdir}/se/guides/quickstart.adoc[Using the SE Quick Start Guide] + + +-- + +//Migration Guides +[CARD] +.Upgrading Helidon +[icon=storage] +-- +Use the migration guides to help you upgrade your existing Helidon applications to the latest version of Helidon. + +xref:{rootdir}/mp/guides/migration_3x.adoc[Upgrade From Helidon MP 3.x] + +xref:{rootdir}/mp/guides/migration.adoc[Upgrade From Helidon MP 2.x] + +xref:{rootdir}/se/guides/migration_3x.adoc[Upgrade From Helidon SE 3.x] + +xref:{rootdir}/se/guides/migration.adoc[Upgrade From Helidon SE 2.x] + +-- + + + +//Developing Your First Application +[CARD] +.Developing Your First Application From Scratch +[icon=share] +-- +Use these hands-on development tutorials to learn how to generate a small "Hello World!" greeting service that demonstrates some of Helidon's core features. + +xref:{rootdir}/mp/guides/mp-tutorial.adoc[Helidon MP Tutorial] + +xref:{rootdir}/mp/guides/mp-tutorial.adoc[Helidon SE Tutorial] + +-- + +//How-To Guides +[CARD] +.How-To Guides +[icon=graphic_eq] +-- +Ready for more hands-on learning? Explore the features of Helidon with these quick step-by-step guides. + +Nima Guides + +xref:{rootdir}/se/guides/overview.adoc[SE Guides] + +xref:{rootdir}/mp/guides/overview.adoc[MP Guides] + +-- +//Helidon Nima +[CARD] +.Helidon Nima +[icon=swap_horiz] +-- + +-- + + +//Helidon MP +[CARD] +.Helidon MP +[icon=swap_horiz] +-- + +-- + +//Helidon SE +[CARD] +.Helidon SE +[icon=swap_horiz] +-- + +-- +==== + + + + diff --git a/docs/about/generating_project.adoc b/docs/about/generating_project.adoc new file mode 100644 index 00000000000..b96f478b34f --- /dev/null +++ b/docs/about/generating_project.adoc @@ -0,0 +1,86 @@ +/////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2023 Oracle and/or its affiliates. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +/////////////////////////////////////////////////////////////////////////////// + += Helidon Project Starter + + + +https://helidon.io/starter[Helidon Project Starter] allows you to choose from a set of archetypes with pre-defined feature sets and lets you customize it by providing a host of options. + +== Select a Flavor + + +=== Helidon SE + +=== Helidon MP + +=== Nima + + +== Choose an Application Type +Helidon provides the following set of archetypes to bootstrap your application development journey. + +=== QuickStart +This option creates a Helidon project that includes multiple REST operations along with default observability setup and a set of dependencies to enable ease of development e.g. in case of Helidon MP, it uses `helidon-microprofile` bundle instead of minimal `helidon-microprofile-core` bundle. + +=== Database +This option builds on `QuickStart` to demonstrate how to integrate with database (in-memory H2, by default). In case of, Helidon SE that uses the DbClient API while for Helidon MP that uses JPA. + +=== Custom +This option enables user to create Helidon project of their choice, suitable to start from scratch i.e. bare minimum, if default values are chosen Or choose from many options available. + +=== OCI (MP Only) +This option builds on `QuickStart` to demonstrate integration with Oracle Cloud Infrastructure (OCI) services using the OCI SDK. Generated project showcases OpenApi-driven development approach where the practice of designing and building APIs is done first, then creating the rest of an application around them is implemented next. This is available for Helidon MP only. + + +== Media Support Options + +=== Jackson JSON + +=== JSON-B +Default. + +=== JSON-P (SE Only) + +== Customize Project + +* groupId +* artifactId +* Project Version +* Java package name + +== Download the Project Files + +Click *Download* and Project Starter generates the files in a directory named after the `artifactId` value. It mainly contains the following: + +* Maven structure + +* skeletal application code + +* associated unit test code + +* example Dockerfile files + +* application configuration file(s) + +* Readme file with instructions to build and run application/test + + + + + diff --git a/docs/about/intro.adoc b/docs/about/intro.adoc new file mode 100644 index 00000000000..4bedae82961 --- /dev/null +++ b/docs/about/intro.adoc @@ -0,0 +1,26 @@ +/////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2023 Oracle and/or its affiliates. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +/////////////////////////////////////////////////////////////////////////////// + += Introducing Helidon 4 +:description: Helidon +:keywords: helidon, java, microservices +:rootdir: {docdir}/.. + + +== What's New in This Release + diff --git a/docs/about/introduction.adoc b/docs/about/introduction.adoc index 44255dcedd0..0fab74af258 100644 --- a/docs/about/introduction.adoc +++ b/docs/about/introduction.adoc @@ -1,6 +1,6 @@ /////////////////////////////////////////////////////////////////////////////// - Copyright (c) 2018, 2022 Oracle and/or its affiliates. + Copyright (c) 2018, 2023 Oracle and/or its affiliates. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -16,14 +16,14 @@ /////////////////////////////////////////////////////////////////////////////// -= Introduction += Introducing Helidon :description: Helidon :keywords: helidon, java, microservices, microprofile :rootdir: {docdir}/.. include::{rootdir}/includes/attributes.adoc[] -== Contents +== What is Helidon? * <> * <> diff --git a/docs/config/config_reference.adoc b/docs/config/config_reference.adoc index b9b454bd3ec..9b671140520 100644 --- a/docs/config/config_reference.adoc +++ b/docs/config/config_reference.adoc @@ -63,6 +63,7 @@ The following section lists all configurable types in Helidon. - xref:{rootdir}/config/io_helidon_security_providers_oidc_common_OidcConfig.adoc[OidcConfig (security.providers.oidc.common)] - xref:{rootdir}/config/io_helidon_security_providers_oidc_OidcProvider.adoc[OidcProvider (security.providers.oidc)] - xref:{rootdir}/config/io_helidon_openapi_OpenAPISupport.adoc[OpenAPISupport (openapi)] +- xref:{rootdir}/config/io_helidon_openapi_OpenApiUi.adoc[OpenApiUi (openapi)] - xref:{rootdir}/config/io_helidon_security_providers_common_OutboundConfig.adoc[OutboundConfig (security.providers.common)] - xref:{rootdir}/config/io_helidon_security_providers_common_OutboundTarget.adoc[OutboundTarget (security.providers.common)] - xref:{rootdir}/config/io_helidon_common_pki_KeyConfig_PemBuilder.adoc[PemBuilder (common.pki.KeyConfig)] diff --git a/docs/config/io_helidon_openapi_OpenAPISupport.adoc b/docs/config/io_helidon_openapi_OpenAPISupport.adoc index 0049886ba6a..9f45f4559b4 100644 --- a/docs/config/io_helidon_openapi_OpenAPISupport.adoc +++ b/docs/config/io_helidon_openapi_OpenAPISupport.adoc @@ -1,6 +1,6 @@ /////////////////////////////////////////////////////////////////////////////// - Copyright (c) 2022 Oracle and/or its affiliates. + Copyright (c) 2022, 2023 Oracle and/or its affiliates. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -46,6 +46,7 @@ Type: link:{javadoc-base-url}/io.helidon.openapi/io/helidon/openapi/OpenAPISuppo |`cors` |xref:{rootdir}/config/io_helidon_reactive_webserver_cors_CrossOriginConfig.adoc[CrossOriginConfig] |{nbsp} |Assigns the CORS settings for the OpenAPI endpoint. |`static-file` |string |`META-INF/openapi.*` |Sets the file system path of the static OpenAPI document file. Default types are `json`, `yaml`, and `yml`. +//|`ui` |xref:{rootdir}/config/io_helidon_openapi_OpenApiUi.adoc[OpenApiUi] |{nbsp} |Assigns the OpenAPI UI builder the `OpenAPISupport` service should use in preparing the U/I. |`web-context` |string |`/openapi` |Sets the web context path for the OpenAPI endpoint. |=== diff --git a/docs/config/io_helidon_openapi_OpenApiUi.adoc b/docs/config/io_helidon_openapi_OpenApiUi.adoc new file mode 100644 index 00000000000..e1319dbefaa --- /dev/null +++ b/docs/config/io_helidon_openapi_OpenApiUi.adoc @@ -0,0 +1,57 @@ +/////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2022, 2023 Oracle and/or its affiliates. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +/////////////////////////////////////////////////////////////////////////////// + +ifndef::rootdir[:rootdir: {docdir}/..] +:description: Configuration of io.helidon.openapi.OpenApiUi +:keywords: helidon, config, io.helidon.openapi.OpenApiUi +:basic-table-intro: The table below lists the configuration keys that configure io.helidon.openapi.OpenApiUi +include::{rootdir}/includes/attributes.adoc[] + += OpenApiUi (openapi) Configuration + +// tag::config[] + + +Type: link:{javadoc-base-url}/io.helidon.openapi/io/helidon/openapi/OpenApiUi.html[io.helidon.openapi.OpenApiUi] + + +[source,text] +.Config key +---- +ui +---- + + + +== Configuration options + + + +.Optional configuration options +[cols="3,3a,2,5a"] + +|=== +|key |type |default value |description + +|`enabled` |boolean |`true` |Sets whether the UI should be enabled. +|`options` |Map<string, string> |{nbsp} |Sets implementation-specific UI options. +|`web-context` |string |{nbsp} |web context (path) where the UI will respond + +|=== + +// end::config[] \ No newline at end of file diff --git a/docs/config/io_helidon_openapi_SEOpenAPISupport.adoc b/docs/config/io_helidon_openapi_SEOpenAPISupport.adoc index 30bd63dbb87..5e6a2eeff7e 100644 --- a/docs/config/io_helidon_openapi_SEOpenAPISupport.adoc +++ b/docs/config/io_helidon_openapi_SEOpenAPISupport.adoc @@ -1,6 +1,6 @@ /////////////////////////////////////////////////////////////////////////////// - Copyright (c) 2022 Oracle and/or its affiliates. + Copyright (c) 2022, 2023 Oracle and/or its affiliates. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -58,6 +58,7 @@ openapi |`servers.operation.*` |string[] |{nbsp} |Sets alternative servers to service the indicated operation (represented here by '*'). Repeat for multiple operations. |`servers.path.*` |string[] |{nbsp} |Sets alternative servers to service all operations at the indicated path (represented here by '*'). Repeat for multiple paths. |`static-file` |string |`META-INF/openapi.*` |Sets the file system path of the static OpenAPI document file. Default types are `json`, `yaml`, and `yml`. +|`ui` |xref:{rootdir}/config/io_helidon_openapi_OpenApiUi.adoc[OpenApiUi] |{nbsp} |Assigns the OpenAPI U/I builder the `OpenAPISupport` service should use in preparing the U/I. |`web-context` |string |`/openapi` |Sets the web context path for the OpenAPI endpoint. |=== diff --git a/docs/images/openapi-ui-screen-capture-greeting-mp-expanded.png b/docs/images/openapi-ui-screen-capture-greeting-mp-expanded.png new file mode 100644 index 00000000000..b5a310594c0 Binary files /dev/null and b/docs/images/openapi-ui-screen-capture-greeting-mp-expanded.png differ diff --git a/docs/images/openapi-ui-screen-capture-greeting-mp-start.png b/docs/images/openapi-ui-screen-capture-greeting-mp-start.png new file mode 100644 index 00000000000..707e59bd771 Binary files /dev/null and b/docs/images/openapi-ui-screen-capture-greeting-mp-start.png differ diff --git a/docs/images/openapi-ui-screen-capture-greeting-se-expanded.png b/docs/images/openapi-ui-screen-capture-greeting-se-expanded.png new file mode 100644 index 00000000000..372ca09df30 Binary files /dev/null and b/docs/images/openapi-ui-screen-capture-greeting-se-expanded.png differ diff --git a/docs/images/openapi-ui-screen-capture-greeting-se-start.png b/docs/images/openapi-ui-screen-capture-greeting-se-start.png new file mode 100644 index 00000000000..29f47a63b95 Binary files /dev/null and b/docs/images/openapi-ui-screen-capture-greeting-se-start.png differ diff --git a/docs/includes/attributes.adoc b/docs/includes/attributes.adoc index 3249a67be7a..48d03320815 100644 --- a/docs/includes/attributes.adoc +++ b/docs/includes/attributes.adoc @@ -1,6 +1,6 @@ /////////////////////////////////////////////////////////////////////////////// - Copyright (c) 2022 Oracle and/or its affiliates. + Copyright (c) 2022, 2023 Oracle and/or its affiliates. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -77,6 +77,7 @@ endif::[] :version-plugin-jib: 0.10.1 :version-plugin-jandex: 1.0.6 :version-lib-micrometer: 1.6.6 +:version-lib-smallrye-open-api: 2.1.16 :jdk-version: 17 @@ -204,6 +205,7 @@ endif::[] :mp-tyrus-javadoc-base-url: {javadoc-base-url}/io.helidon.microprofile.tyrus :mp-restclient-javadoc-base-url: {javadoc-base-url}/io.helidon.microprofile.restclient :openapi-javadoc-base-url: {javadoc-base-url}/io.helidon.openapi +:openapi-ui-javadoc-base-url: {javadoc-base-url}/io.helidon.integrations.openapi.ui :reactive-base-url: {javadoc-base-url}/io.helidon.common.reactive :scheduling-javadoc-base-url: {javadoc-base-url}/io.helidon.microprofile.scheduling :security-integration-jersey-base-url: {javadoc-base-url}/io.helidon.security.integration.jersey @@ -262,4 +264,16 @@ endif::[] :micrometer-javadoc-base-url: https://javadoc.io/doc/io.micrometer :micrometer-javadoc-registry-prometheus-base-url: {micrometer-javadoc-base-url}/micrometer-registry-prometheus/{version-lib-micrometer}/io/micrometer/prometheus +// OpenAPI generator +:openapi-generator-version: 6.2.1 +:openapi-generator-tool-base-url: https://github.com/OpenAPITools/openapi-generator +:openapi-generator-site-version: v{openapi-generator-version} + +:openapi-generator-tool-docs-url: {openapi-generator-tool-base-url}/blob/{openapi-generator-site-version}/docs +:openapi-generator-tool-generators-docs-url: {openapi-generator-tool-docs-url}/generators +:openapi-generator-tool-site-url: https://openapi-generator.tech + +// OpenAPI UI +:smallrye-openapi-ui-base-url: https://github.com/smallrye/smallrye-open-api/tree/{version-lib-smallrye-open-api}/ui/open-api-ui + endif::attributes-included[] diff --git a/docs/includes/cors.adoc b/docs/includes/cors.adoc index cacb02bad70..024a0f1c187 100644 --- a/docs/includes/cors.adoc +++ b/docs/includes/cors.adoc @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// - Copyright (c) 2020, 2022 Oracle and/or its affiliates. + Copyright (c) 2020, 2023 Oracle and/or its affiliates. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -251,7 +251,6 @@ matches an incoming request's path pattern and HTTP method. // tag::understanding-cors-support-in-services[] === Using CORS Support in Built-in Helidon Services -include::{rootdir}/includes/pages.adoc[] Several built-in Helidon services--xref:{health-page}[health], xref:{metrics-page}[metrics], and xref:{openapi-page}[OpenAPI]--have integrated CORS support. @@ -285,7 +284,6 @@ to your own endpoints. // tag::builtin-getting-started[] ==== Built-in Services with CORS -include::{rootdir}/includes/pages.adoc[] To use built-in services with CORS support and customize the CORS behavior: diff --git a/docs/includes/mp.adoc b/docs/includes/mp.adoc index 125b2d91668..7755902b10d 100644 --- a/docs/includes/mp.adoc +++ b/docs/includes/mp.adoc @@ -1,6 +1,6 @@ /////////////////////////////////////////////////////////////////////////////// - Copyright (c) 2022 Oracle and/or its affiliates. + Copyright (c) 2022, 2023 Oracle and/or its affiliates. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -28,4 +28,6 @@ include::{rootdir}/includes/attributes.adoc[] :flavor-lc: mp :mp-flavor: true +include::{rootdir}/includes/pages.adoc[] + endif::flavor-included[] diff --git a/docs/includes/nima.adoc b/docs/includes/nima.adoc new file mode 100644 index 00000000000..36441490d4b --- /dev/null +++ b/docs/includes/nima.adoc @@ -0,0 +1,31 @@ +/////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2023 Oracle and/or its affiliates. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +/////////////////////////////////////////////////////////////////////////////// + +ifndef::flavor-included[] + +:flavor-included: true + +ifndef::rootdir[:rootdir: {docdir}/..] +include::{rootdir}/includes/attributes.adoc[] + +:h1-prefix: Níma +:flavor-uc: Níma +:flavor-lc: nima + + +endif::flavor-included[] diff --git a/docs/includes/openapi/openapi-generator.adoc b/docs/includes/openapi/openapi-generator.adoc new file mode 100644 index 00000000000..029166081aa --- /dev/null +++ b/docs/includes/openapi/openapi-generator.adoc @@ -0,0 +1,540 @@ +/////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2023 Oracle and/or its affiliates. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +/////////////////////////////////////////////////////////////////////////////// +// tag::preamble[] +:description: Helidon {flavor-uc} OpenAPI Generator +:keywords: helidon, {flavor-lc}, openapi, generator +:feature-name: Helidon {flavor-uc} OpenAPI Generator +// DO NOT CHANGE THE FOLLOWING - it's used as a minimum release that will not normally change with new releases of the OpenAPI generator +:first-version-with-strong-helidon-support: 6.2.1 +// Update the following when it is convenient to keep pace with the latest releases of the OpenAPITools generator +// end::preamble[] + +// tag::intro[] +== Contents + +- <> +- <> +- <> +- <> +- <> + +== Overview +The link:{openapi-spec-url}[OpenAPI specification] provides a standard way to express RESTful APIs. + +Separately, the link:{openapi-generator-tool-site-url}[OpenAPI generator] project has created a powerful code generator tool which accepts an OpenAPI document and generates client and server code for many languages and frameworks. The Helidon team contributes to this tool to ensure that it provides strong support for Helidon {flavor-uc} clients and servers. +As a result, you can use the generator to create code that fits smoothly into your Helidon applications. +The OpenAPI generator release {first-version-with-strong-helidon-support} gained particularly strong support for Helidon. +This document applies to that release and later ones. + +In the vocabulary of the tool, there are two _generators_ for Helidon: + +* `java-helidon-client` (hereafter the Helidon client generator) +* `java-helidon-server` (hereafter the Helidon server generator). + +Each of these generators supports two _libraries_: + +* `mp` - for Helidon MP code generation +* `se` - for Helidon SE code generation + +Use the Helidon _client_ generator and its `{flavor-lc}` library to create a +ifdef::mp-flavor[] +xref:{helidon-client-xref}[Helidon MicroProfile REST client]. +endif::mp-flavor[] +ifdef::se-flavor[] +Helidon SE client based on xref:{helidon-client-xref}[Helidon WebClients]. +endif::se-flavor[] +The resulting client library works with any server that implements the API declared in the OpenAPI document you specified when you ran the generator. +The client library provides an abstraction similar to remote procedure calls (RPC). +To access a remote service that implements the endpoints declared in the OpenAPI document, your code uses the generated client library first to establish a connection to the remote service and then to call remote service endpoints by invoking local methods passing POJO business objects or Java types as arguments. + +Use the tool's Helidon _server_ generator and its `{flavor-lc}` library to create server endpoint stubs for a Helidon {flavor-uc} service. You build on these stubs by extending a generated class or implementing a generated interface, adding your specific business logic to finish the implementation of the endpoints. The combination of the generated server code plus Helidon {flavor-uc} underneath it allows you to focus on the business details instead of resource boilerplate. + +You can run the OpenAPI generators in three ways: + +// tag::three-ways-to-run[] +* using the OpenAPI generator CLI +* using the OpenAPI generator Maven plug-in +* using the online OpenAPI generator website +// end::three-ways-to-run[] + +The rest of this document walks you through <> each technique and how to <> the generators to produce the code you want. + +// end::intro[] + +// tag::coords[] + +== Maven Coordinates +Your project does not need any dependencies on the OpenAPI generator. + +To use the OpenAPI generator plug-in to generate or regenerate files during your project build, add the following to your project's `pom.xml` file to declare the plug-in. Choose whichever version of the generator plug-in meets your needs as long as it is at least {first-version-with-strong-helidon-support}. + +[source,xml,subs="+attributes,+macros"] +.Declaring the OpenAPI Generator Plug-in +---- + + {openapi-generator-version} + +... + + ... + + ... + + org.openapitools + openapi-generator-maven-plugin + ++${openapi-generator-version}++ + + ... + + ... + +---- + +A <> describes how to invoke the plug-in during your build. +// end::coords[] + +// tag::config[] + +== Configuration + +The OpenAPI generators support a substantial, powerful, and sometimes bewildering group of configuration settings. +For complete lists see these pages: + +[[links-to-settings]] + +* link:{openapi-generator-tool-docs-url}/usage.md#generate[generic options] +* link:{openapi-generator-tool-generators-docs-url}/java-helidon-client.md[Helidon client generator options] and +* link:{openapi-generator-tool-generators-docs-url}/java-helidon-server.md[Helidon server generator options] + +The OpenAPI generator divides its settings into two types: + +* _options_ ++ +These high-level settings generally govern the overall behavior of the tool. ++ +For the CLI, use the common option style: ++ +`-i petstore.yaml` ++ +`--input-spec petstore.yaml` ++ +For the Maven plug-in, use elements within the `` section of the plug-in: ++ +[source,xml] +---- + + petstore.yaml + +---- +* _additional properties_ ++ +These settings typically affect how a specific generator or library generates the code. ++ +For the CLI: ++ +`--additional-properties "useAbstractClasses=false,returnResponse=true"` ++ +or ++ +[source,bash] +---- +-p useAbstractClasses=false +-p returnResponse=true +---- ++ +For the Maven plug-in, use elements within the `` section: ++ +[source,xml] +---- + + .... + + false + true + + +---- + +Keep this distinction between options and additional properties in mind so you know how to express the configuration you want. +The <> to the lists of configuration options for the Helidon generators groups options and additional properties in separate tables. + +The next few sections describe, in turn, required settings, settings we recommend, and other common settings most developers will want to use. + +=== Required Settings + +You must specify the following options: + +.Required OpenAPI Generator Options +[cols="4,1,4,6,5"] +|=== +|Option | Short Option |Plug-in Setting | Description | Values + +|`--inputSpec` +|`-i` +|`` +|Path to the OpenAPI document defining the REST API +| + +|`--generatorName` +|`-g` +|`` +| Generator you want to use (`java-helidon-server` or `java-helidon-client`) +| `java-helidon-server` + +`java-helidon-client` + +|`--library` + +`` +| {nbsp} +|Library you want to use +|`mp` + +`se` +|=== + +=== Recommended Settings for the OpenAPI Generator +Your project might have different needs, but in general we advise developers to use the following settings when using the OpenAPI generator. + + +.Recommended OpenAPI Generator Additional Properties +[cols="3,6,5"] +|=== +| Property | Description | Default + +| `apiPackage` +| Name of the package for generated API interfaces/classes +| `org.openapitools.server.api` or + +`org.openapitools.client.api` + +| `modelPackage` +| Name of the package for generated model (POJO) classes +| `org.openapitools.server.model` or + +`org.openapitools.client.model` + +| `invokerPackage` +| Name of the package for generated driver classes +| `org.openapitools.server` or + +`org.openapitools.client` + +| `groupId` +| Group ID in the generated `pom.xml` +| `org.openapitools` + +| `artifactId` +| Artifact ID in the generated `pom.xml` +| `openapi-java-server` or + +`openapi-java-client` + +| `artifactVersion` +| Artifact version in the generated `pom.xml` +| `1.0.0` +|=== + +[NOTE] +The next table contains recommendations only for using the OpenAPI generator plug-in (not for using the CLI). + + +.Recommended OpenAPI Generator Plug-in Options +[cols="4,8,5"] +|=== +|Plug-in Option | Description |Default + +|`` +| Directory where the generator should place files. + ++ +We strongly recommend `target/generated-sources` or a subdirectory below there. +| `.` + +(current directory) + +| `` +| Whether Maven should include the output directory as a source root (that is, include it automatically in the build). + ++ +We advise `true`. +| `false` +|=== + + +=== Common Settings +Among the many configuration settings available to you, some you should particularly consider are summarized in the table below. Refer to the <> for complete lists. + +.Common OpenAPI Generator Additional Properties +[cols="4,5,3,3,7"] +|=== +|Property |Description |Values |Default |Notes + +| `helidonVersion` + +|Version of Helidon for which to generate the files +| {nbsp} +|`2.5.2` +a|Affects: + +* Helidon version for the `` +* Dependencies (`javax` vs. `jakarta`) +* `java import` statements in generated code (`javax` vs. `jakarta`) + +|`fullProject` +|Whether to generate all the normal files or only API files +|`true`/`false` +|`false` +| The "API files" include files developers do not normally modify after they are generated: the interfaces or classes for the declared API +and the model classes. + +|`serializationLibrary` +|which Java library to use for serializing JSON +|`jsonb`, `jackson` +|`jackson` +| +|=== + + +// end::config[] + +// tag::usage[] + +[[usage-section]] +== Usage + +This section covers two major topics: + +* <> +* <> + +[[usage-planning]] +=== Planning Your Use of the OpenAPI Generators + +Beyond the settings listed above, there are several important choices you need to make when planning your project and when running the OpenAPI generators. This section addresses those choices. + +==== Generating a New Project and Generating _Into_ an Existing Project + +You can use the OpenAPI generator to create a new project or to generate files into an existing project. +Some developers do both, using the generator to create the project at first and then to update the project as they evolve the OpenAPI document or change the generation options they select. +Others create the project in some other way--for example, using the xref:{cli-page}[Helidon CLI]. The OpenAPI generator CLI and plug-in both support each type of usage. + +If the OpenAPI generator finds a pre-existing API or model file, it overwrites it with the latest content. +It does _not_ overwrite a `pom.xml` file or test files. +This is important because certain generation settings can influence the generated dependencies in the `pom.xml` file. +For example, the `serializationLibrary` setting creates dependencies on either JSON-B or Jackson artifacts. +As a result, changing the generation options can change the dependencies your project should have. If you rerun the generator, the old `pom.xml` remains and does not reflect the revised depencencies. + +As a practical matter, many developers use the OpenAPI generators in one of the following ways: + +* Use the generator CLI once to create a new project. ++ +By default, the generator CLI creates files in the normal Maven project structure: `src/main/java`, etc. +Then you add your own files to that same project structure. +Because the generated files are in the standard places, the project build includes them by default. ++ +[NOTE] +==== +You _can_ run the generator CLI again to update the generated files. +Because this happens outside the project's build lifecycle, you need to remember to rerun the CLI yourself when you change the OpenAPI document. + +You also need to identify and manually remove any previously-generated files that become obsolete. +Similarly, you must understand how changes in the OpenAPI document or the generation options affect the project dependencies and update the project `pom.xml` accordingly. +==== +* Use the generator plug-in to (re)generate files during each build. ++ +Specify in the plug-in configuration that the generated files should reside in `target/generated-sources` directory (the conventional location for generated sources) or a subdirectory below there. +Each project build runs the OpenAPI generator which reads the then-current OpenAPI document file. +With the generated files under `target`, you can use `mvn clean` to remove any obsolete generated files left over from previous builds. ++ +[NOTE] +==== +In particular, with `mvn clean` each build regenerates the candidate `pom.xml` under `target/generated-sources`. You can inspect the generated `pom.xml` file for changes in dependencies and make any necessary changes in the actual project `pom.xml` file. +==== + +==== Generating Interfaces or Classes +As you generate a Helidon {flavor-uc} _server_, you can choose whether you want Java interfaces or classes to represent the RESTful API endpoints. + +By default, the Helidon OpenAPI server generator creates classes. +You write your own concrete subclasses which extend those generated classes, supplying the business logic for each REST endpoint. +_Do not_ modify the generated classes. + +If you set `useAbstractClasses=false` then the generator creates Java interfaces instead of classes. +You then write classes which implement those generated interfaces. + +Either way, you can safely regenerate the code later so long as you have not edited the generated code. +The generator replaces the generated classes or interfaces but does not touch other classes you wrote. + +The Helidon _client_ generator always creates concrete classes. Typically, you do not need to customize the behavior in the generated client API classes. If you choose to do so, write your own subclass of the generated client API class; _do not_ modify the generated files. + +==== Grouping Operations into "APIs" +Each operation in an OpenAPI document can have a `tags` attribute. +The generators group operations with the same `tags` value into the same API. + +When you generate a Helidon {flavor-uc} server, the generator creates a separate interface or class for each API your service _exposes_. +You implement each interface or extend each class to add your business logic for that API. + +When you generate a Helidon {flavor-uc} client, the generated code contains a separate API class for each distinct API your code might _invoke_. + +[[usage-running]] +=== Running the OpenAPI Generators + +Earlier we listed the ways you can run the OpenAPI generator: + +include::openapi-generator.adoc[tag=three-ways-to-run] + +The next sections describe each of these techniques in detail. + +==== Using the OpenAPI Generator CLI + +[NOTE] +.Downloading the OpenAPI Generator CLI +You need to download the CLI `.jar` file before you can run the CLI. +Follow these link:https://github.com/OpenAPITools/openapi-generator#13---download-jar[instructions] and remember where you save the `.jar` file. +The examples below use the placeholder `path-to-generator` to represent the directory where you store that downloaded file. + +The following example uses the Helidon server generator to create a project or regenerate files into an existing project. + +:example-project-type: server +.Creating or updating a server project using the OpenAPI generator CLI +// tag::example-cli-usage[] +[source,bash,subs="attributes+"] +---- +java -jar $\{path-to-generator}/openapi-generator-cli.jar \ + generate \ + -i src/main/resources/petstore.yaml \ + -g java-helidon-{example-project-type} \ + --library {flavor-lc} \ + -p groupId=io.helidon.examples \ + -p artifactId=helidon-openapigen-{flavor-lc}-{example-project-type} \ + -p artifactVersion=1.0.0-SNAPSHOT \ + -p apiPackage=io.helidon.examples.openapigen.{flavor-lc}.{example-project-type}.api \ + -p modelPackage=io.helidon.examples.openapigen.{flavor-lc}.{example-project-type}.model \ + -p invokerPackage=io.helidon.examples.openapigen.{flavor-lc}.{example-project-type} +---- +// end::example-cli-usage[] + +The next example runs the Helidon client generator using the same input file. + +:example-project-type: client +.Creating or updating a client project using the OpenAPI generator CLI +include::openapi-generator.adoc[tag=example-cli-usage] + +The key differences between the commands are: + +* the generator selected by the `-g` option (`client` vs. `server`), +* the artifact ID and package names (`client` vs. `server`). + +You could use these two commands together to generate a server submodule and a client submodule in a pre-existing multi-module Maven project. Remember that the resulting client project can access any server which implements the API described in the `petstore.yaml` OpenAPI document, whether it was generated using the OpenAPI generator tool or not. + +In both examples, the generator creates the entire project if it does not exist and recreates the generated API and model files if the project already exists. +The generator does not overwrite an existing `pom.xml` file, previously-generated test files, or files you create yourself. + +[[invoking-the-plugin]] +==== Invoking the OpenAPI Generator Maven Plug-in + +You can run the OpenAPI generator plug-in as part of your project build to generate or regenerate files. + +First, declare the plug-in as explained in the <>. + +Then, in the `` section of your `pom.xml` file, add an execution of the plug-in with the configuration you want. By default, the plug-in runs during the `generate-sources` phase of the Maven build. + + +The plug-in execution in the following example is equivalent to the CLI example above for generating server files: + +[source,xml,subs="+attributes,+macros"] +.Creating or updating a {example-project-type} project using the OpenAPI Maven plug-in +---- + + org.openapitools + openapi-generator-maven-plugin + + + + generate + + + ++${project.basedir}++/src/main/resources/petstore.yaml + java-helidon-{example-project-type} + {flavor-lc} + ++${project.build.directory}++/generated-sources/{example-project-type} + true + + io.helidon.examples + helidon-openapigen-{flavor-lc}-{example-project-type} + 1.0.0-SNAPSHOT + io.helidon.examples.openapigen.{flavor-lc}.{example-project-type}.api + io.helidon.examples.openapigen.{flavor-lc}.{example-project-type}.model + io.helidon.examples.openapigen.{flavor-lc}.{example-project-type} + + + + + +---- +<1> Specifies that the generated files should reside in the `target/generated-sources/{example-project-type}` directory. + +==== Using the Online Generator + +The OpenAPI tools project hosts and maintains the online OpenAPI generator at http://api.openapi-generator.tech. You can use the site's API browser to explore the available generators and the settings each supports, expressed as JSON. + +To generate your project, you supply the options and additional properties as JSON. The online generator provides you with a file ID, and you refer to the file ID in a subsequent HTTP request to retrieve your project. + +[NOTE] +The online generator stores your project on the server which you then retrieve using a separate HTTP request. +Before you use the online generator, consider whether any of the input you provide--the OpenAPI document, package or Maven coordinates--and therefore the generated project will reveal any sensitive information. + +This document does not explore further the use of the online generator. + +// end::usage[] + + +// tag::using-generated-code-intro[] +[[using-generated-code]] +== Using the Generated Code + +The Helidon generators go a long way in helping you write your client or server. Even so, there are important parts of your project only you can provide. This section describes your next steps _after_ you have run the generator. +// end::using-generated-code-intro[] + +// tag::using-generated-code-server[] +// tag::using-generated-code-server-intro[] + +=== Completing the Server +Recall from earlier how the OpenAPI generator gathers operations into one or more "APIs" and generates either a class or an interface--your choice--for each API. +You need to extend each generated API class or implement each generated API interface by writing your own classes. +Any input parameters to the endpoints are expressed as POJO model objects or Java types, as declared in the OpenAPI document. Your server code uses each of the input parameters to accomplish whatever business purpose that endpoint is responsible for, possibly returning a result as a POJO or Java type as indicated for that operation in the OpenAPI document. +// end::using-generated-code-server-intro[] + +In some cases, you might need more control over the response sent to the client. In that case, specify the additional property `returnResponse=true` when you run the Helidon server generator. The return type for the generated methods is +ifdef::mp-flavor[] +the Jakarta RESTful web services `Response` +endif::mp-flavor[] +ifdef::se-flavor[] +the Helidon SE `ServerResponse` +endif::se-flavor[] +and your code has complete control--and therefore responsibility--over setting the status, writing the response entity (if any), and assigning any returned headers. + +Your code plus the server code from the Helidon generator--all running on Helidon {flavor-uc}--combine to fully implement the server API declared in the original OpenAPI document. Build your project to get a tailored Helidon {flavor-uc} server `.jar` file or Docker image and your server is ready to run. + +// end::using-generated-code-server[] + +// tag::using-generated-code-client-intro[] +=== Using the Client Library + +The generated client code represents a true library. Typically, you do not need to customize the generated client code itself. You _do_ need to write code to invoke the code in that library. + +// using the SE and MP clients are so different there's not much common content. + +// end::using-generated-code-client-intro[] + +// tag::common-references[] +== References +* link:{openapi-generator-tool-site-url}[OpenAPI Generator Official Website] +* link:{openapi-generator-tool-base-url}[OpenAPI Generator GitHub Repository] +* link:{openapi-spec-url}[OpenAPI specification] +// end::common-references[] \ No newline at end of file diff --git a/docs/includes/openapi/openapi-ui.adoc b/docs/includes/openapi/openapi-ui.adoc new file mode 100644 index 00000000000..45e3ee8a705 --- /dev/null +++ b/docs/includes/openapi/openapi-ui.adoc @@ -0,0 +1,200 @@ +/////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2022, 2023 Oracle and/or its affiliates. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +/////////////////////////////////////////////////////////////////////////////// + +ifndef::rootdir[:rootdir: {docdir}/../..] +// Following make editing the included file a little easier +:flavor-lc: se +:flavor-uc: SE +:se-flavor: + +// tag::preamble[] +:feature-name: Helidon OpenAPI UI support +:screen-capture-start: openapi-ui-screen-capture-greeting-{flavor-lc}-start.png +:screen-capture-expanded: openapi-ui-screen-capture-greeting-{flavor-lc}-expanded.png +// end::preamble[] + +// tag::intro[] + +== Contents + +- <> +- <> +- <> +- <> +- <> +- <> + +// end::intro[] + +// tag::overview[] +== Overview + +SmallRye offers an link:{smallrye-openapi-ui-base-url}[OpenAPI user interface component] which displays a web page based on your application's OpenAPI document. +Through that UI, users can invoke the operations declared in the document. +While not generally suitable for end-users, the OpenAPI UI can be useful for demonstrating and "test driving" your service's endpoints. + +The Helidon OpenAPI component allows you to integrate the SmallRye UI into your application, adding the UI web page to your application very simply. + + +// end::overview[] + +// tag::dependencies[] +include::{rootdir}/includes/dependencies.adoc[] + +[source,xml,subs=+macros] +---- + + io.helidon.integrations.openapi-ui + helidon-integrations-openapi-ui +ifdef::mp-flavor[ runtime] + +---- + +// end::dependencies[] + +// tag::usage[] +// tag::usage-start[] +== Usage +ifdef::se-flavor[] +Make sure your application creates a Helidon `OpenAPISupport` instance and registers it for routing (described in detail in link:{openapi-page}[the Helidon OpenAPI documentation]). `OpenAPISupport` automatically prepares the OpenAPI UI with default settings if you also declare a dependency on the Helidon OpenAPI UI integration component as explained above. The <> section below illustrates adding OpenAPI to your application and customizing the UI behavior. +endif::se-flavor[] + +After you modify, build, and start your Helidon {flavor-uc} service, you can access the OpenAPI UI by default at `http://your-host:your-port/openapi/ui`. +Helidon also uses conventional content negotiation at `http://your-host:your-port/openapi` returning the UI to browsers (or any client that accepts HTML) and the OpenAPI document otherwise. + +You can customize the path using +ifdef::se-flavor[either the API or ] +xref:Configuration[configuration]. + +The example below shows the UI +ifdef::se-flavor[] +if you modify the Helidon SE QuickStart greeting application to contain a static OpenAPI file which describes the service endpoints. +endif::se-flavor[] +ifdef::mp-flavor[] +for the Helidon MP QuickStart greeting application. +endif::mp-flavor[] + +.OpenAPI UI Screen for Helidon {flavor-uc} QuickStart Greeting Application +image::{screen-capture-start}[align="center",title="Example OpenAPI UI Screen"] + +// end::usage-start[] + +// tag::usage-expanded-screen[] +With the OpenAPI UI displayed, follow these steps to access one of your service's operations. + +. Find the operation you want to run and click on its row in the list. +. The UI expands the operation, showing any input parameters and the possible responses. Click the "Try it out" button in the operation's row. +. The UI now allows you to type into the input parameter field(s) to the right of each parameter name. Enter any required parameter values (first highlighted rectangle) and any non-required values you wish, then click "Execute" (highlighted arrow). +. Just below the "Execute" button the UI shows several sections: + +* the equivalent `curl` command for submitting the request with your inputs, +* the URL used for the request, and +* a new "Server response" section (second highlighted rectangle) containing several items from the response: + +** HTTP status code +** body +** headers + +The next image shows the screen after you submit the "Returns a personalized greeting" operation. + +Note that the UI shows the actual response from invoking the operation in the "Server response" section. The "Responses" section farther below describes the possible responses from the operation as declared in the OpenAPI document for the application. + +.Example OpenAPI UI Screen +image::{screen-capture-expanded}[align="center",title="Example OpenAPI UI Screen"] + +// end::usage-expanded-screen[] +// end::usage[] + +// tag::config-intro[] +== Configuration +To use configuration to control how the Helidon OpenAPI UI service behaves, add an `openapi.ui` section to +ifdef::mp-flavor[your `META-INF/microprofile-config.properties` file.] +ifdef::se-flavor[your configuration file, such as `application.yaml`.] + +include::{rootdir}/config/io_helidon_openapi_OpenApiUi.adoc[tag=config,leveloffset=+1] +The default UI `web-context` value is the web context for your `OpenAPISupport` service with the added suffix `/ui`. If you use the default web context for both `OpenAPISupport` and the UI, the UI responds at `/openapi/ui`. + +// end::config-intro[] + +// tag::config-details[] + +You can use configuration to affect the UI path in two ways: + +* Configure the OpenAPI endpoint path (the `/openapi` part). ++ +Recall that you can xref:{openapi-page}#config[configure the Helidon OpenAPI component] to change where it serves the OpenAPI document. ++ +.Configuring the OpenAPI web context +ifdef::se-flavor[] +[source,yaml] +---- +openapi: + web-context: /my-openapi +---- +endif::se-flavor[] +ifdef::mp-flavor[] +[source,properties] +---- +openapi.web-context=/my-openapi +---- +endif::mp-flavor[] ++ +In this case, the path for the UI component is your customized OpenAPI path with `/ui` as a suffix. +With the example above, the UI responds at `/my-openapi/ui` and +Helidon uses standard content negotiation at `/my-openapi` to return either the OpenAPI document or the UI. +* Separately, configure the entire web context path for the UI independently from the web context for OpenAPI. ++ +.Configuring the OpenAPI UI web context +ifdef::se-flavor[] +[source,yaml] +---- +openapi: + ui: + web-context: /my-ui +---- +endif::se-flavor[] +ifdef::mp-flavor[] +[source,properties] +---- +openapi.ui.web-context=/my-ui +---- +endif::mp-flavor[] ++ +[NOTE] +==== +The `openapi.ui.web-context` setting assigns the _entire_ web-context for the UI, not the suffix appended to the `OpenAPISupport` endpoint. +==== +With this configuration, the UI responds at `/my-ui` regardless of the path for OpenAPI itself. + +The SmallRye OpenAPI UI component accepts several options, but they are of minimal use to application developers and they must be passed to the SmallRye UI code programmatically. +Helidon allows you to specify these values using configuration in the `openapi.ui.options` section. Helidon then passes the corresponding options to SmallRye for you. +To configure any of these settings, use the enum values--they are all lower case--declared in the SmallRye link:{smallrye-openapi-ui-base-url}/src/main/java/io/smallrye/openapi/ui/Option.java[`Option.java`] class as the keys in your Helidon configuration. + +[NOTE] +==== +Helidon prepares several of the SmallRye options automatically based on other settings. +Any options you configure override the values Helidon assigns, possibly interfering with the proper operation of the UI. +==== + +// end::config-details[] + +// tag::additional-info[] +== Additional Information + +xref:{openapi-page}[Helidon OpenAPI {flavor-uc} documentation] + +link:{smallrye-openapi-ui-base-url}[SmallRye OpenAPI UI GitHub site] +// end::additional-info[] \ No newline at end of file diff --git a/docs/includes/openapi/openapi.adoc b/docs/includes/openapi/openapi.adoc new file mode 100644 index 00000000000..12a29d9161b --- /dev/null +++ b/docs/includes/openapi/openapi.adoc @@ -0,0 +1,218 @@ +/////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2022, 2023 Oracle and/or its affiliates. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +/////////////////////////////////////////////////////////////////////////////// + +ifndef::rootdir[:rootdir: {docdir}/..] + +// tag::overview[] +The link:{openapi-spec-url}[OpenAPI specification] defines a standard way to express the interface exposed by a REST service. + +The link:{microprofile-open-api-spec-url}[MicroProfile OpenAPI spec] explains how MicroProfile embraces OpenAPI, adding annotations, configuration, and a service provider interface (SPI). + +ifdef::mp-flavor[Helidon {flavor-uc} implements the MicroProfile OpenAPI specification.] +ifdef::se-flavor[OpenAPI support in Helidon {flavor-uc} draws its inspiration from MicroProfile OpenAPI but does not implement the spec because Helidon {flavor-uc} does not support annotations.] + +The OpenAPI support in Helidon {flavor-uc} performs two main tasks: + +* Build an in-memory model of the REST API your service implements. +* Expose the model in text format (typically YAML) via the `/openapi` endpoint. + +To construct the model, Helidon gathers information about the service API from whichever of these sources are present in the application: + +* a _model reader_ ++ +The SPI defines an interface you can implement in your application for programmatically providing part or all of the model; +* a static OpenAPI document file packaged as part of your service; +ifdef::mp-flavor[] +* OpenAPI annotations; +endif::[] +* a _filter_ class ++ +The SPI defines an interface you can implement in your application which can mask parts of the model. + + +// end::overview[] + +// tag::mp-depc[] + + io.helidon.microprofile.openapi + helidon-microprofile-openapi + runtime + +// end::mp-depc[] + +// tag::furnish-openapi-info[] + +==== Furnish OpenAPI information about your endpoints +// It's a bit odd to intermix the SE and MP content in this common file this way. +// But I tried having a level 3 section in the SE file include a sequence of +// level 4 sections from here, and that led to errors with headers being out of sequence. +// With the entire level 3 section here and conditional text for SE and MP, AsciiDoctor is happy. +ifdef::se-flavor[] +OpenAPI support in Helidon SE largely follows the link:{microprofile-open-api-spec-url}[MicroProfile OpenAPI spec]. +But because Helidon SE does not process annotations, your application supplies data for the OpenAPI model in the other ways listed earlier. +endif::[] + +ifdef::mp-flavor[] +Helidon MP OpenAPI combines information from all of the following sources as it +builds its in-memory model of your application's API. It constructs the OpenAPI +document from this internal model. Your application can use one or more of these +techniques. + +===== Annotate the endpoints in your app +You can add MicroProfile OpenAPI annotations to the endpoints in your source code. +These annotations allow the Helidon MP OpenAPI runtime to discover the endpoints +and information about them via CDI at app start-up. + +Here is one of the endpoints, annotated for OpenAPI, from the example mentioned earlier: + +[source,java] +---- +@GET +@Operation(summary = "Returns a generic greeting", // <1> + description = "Greets the user generically") +@APIResponse(description = "Simple JSON containing the greeting", // <2> + content = @Content(mediaType = "application/json", + schema = @Schema(implementation = GreetingMessage.class))) +@Produces(MediaType.APPLICATION_JSON) +public JsonObject getDefaultMessage() {...} +---- +<1> `@Operation` gives information about this endpoint. +<2> `@APIResponse` describes the HTTP response and declares its media type and contents. + +You can also define any request parameters the endpoint expects, although this +endpoint uses none. + +This excerpt shows only a few annotations for illustration. The +link:{helidon-github-tree-url}/examples/microprofile/openapi-basic[Helidon MP OpenAPI example] illustrates more, +and the link:{microprofile-open-api-spec-url}[MicroProfile OpenAPI spec] describes them all. + +===== Provide a static OpenAPI file +Add a static file at `META-INF/openapi.yml`, `META-INF/openapi.yaml`, +or `META-INF/openapi.json`. Tools such as Swagger let you describe your app's API +and they then generate an OpenAPI document file which you can include in your application +so OpenAPI can use it. + +===== Write and configure a model reader class +Write a Java class that implements the OpenAPI +link:{microprofile-open-api-javadoc-url}/OASModelReader.html[`org.eclipse.microprofile.openapi.OASModelReader`] interface. Your +model reader code programmatically adds elements to the internal model that OpenAPI +builds. + +endif::[] + +===== Provide a static OpenAPI file +Add a static file at `META-INF/openapi.yml`, `META-INF/openapi.yaml`, +or `META-INF/openapi.json`. Tools such as Swagger let you describe your app's API +and they then generate an OpenAPI document file which you can include in your application +so OpenAPI can use it. + +===== Write and configure a model reader class +Write a Java class that implements the OpenAPI +link:{microprofile-open-api-javadoc-url}/OASModelReader.html[`org.eclipse.microprofile.openapi.OASModelReader`] interface. Your +model reader code programmatically adds elements to the internal model that OpenAPI +builds. + +Change your application's MP configuration to set `mp.openapi.model.reader` as the +fully-qualified class name of your class. + +===== Write and configure a filter class +Write a Java class that implements the OpenAPI +link:{microprofile-open-api-javadoc-url}/OASFilter.html[`org.eclipse.microprofile.openapi.OASFilter`] interface. +As OpenAPI composes its internal model, it invokes your filter with each +model element _before_ adding the element to the model. Your filter can +accept the element as-is, modify it, or suppress it. + +Change your application's configuration to set `mp.openapi.filter` as the full-qualified +class name of your class. + +// end::furnish-openapi-info[] + +// tag::usage-access-endpoint[] +=== Accessing the REST Endpoint +Once you add the {flavor-uc} OpenAPI dependency to your +ifdef::mp-flavor[project,] +ifdef::se-flavor[project and add code to create the `OpenAPISupport` object to your routing,] +your application automatically responds to the built-in endpoint -- +`/openapi` -- and it returns the OpenAPI document describing the endpoints +in your application. + +By default, per the MicroProfile OpenAPI spec, the default format of the OpenAPI document is YAML. +There is not yet an adopted IANA YAML media type, but a proposed one specifically +for OpenAPI documents that has some support is `application/vnd.oai.openapi`. +That is what Helidon returns, by default. + +In addition, a client can specify the HTTP header `Accept` as either `application/vnd.oai.openapi+json` or +`application/json` to request JSON. Alternatively, the client can pass the query parameter `format` as either `JSON` +or `YAML` to receive `application/json` or `application/vnd.oai.openapi` (YAML) output, respectively. +// end::usage-access-endpoint[] + +// tag::api[] +ifdef::mp-flavor[] +The link:{microprofile-open-api-spec-url}[MicroProfile OpenAPI specification] gives a listing and brief examples of the annotations you can add to your code to convey OpenAPI information. +endif::[] + +The link:{microprofile-open-api-javadoc-base-url}[MicroProfile OpenAPI JavaDocs] give full details of the +ifdef::mp-flavor[annotations and the other] +classes and interfaces you can use in your code. +ifdef::se-flavor[] +Remember that, although the JavaDocs describe annotations, Helidon {flavor-uc} does not support them. +endif::[] + +// end::api[] + + +// tag::additional-building-jandex[] + +=== Building the Jandex index + +A Jandex index stores information about the classes and methods in your app and +what annotations they have. It allows CDI to process annotations faster during your +application's start-up. + +Add the link:https://github.com/wildfly/jandex-maven-plugin[Jandex maven plug-in] to the `` +section of your `pom.xml`: + +[source,xml,subs="attributes+"] +---- + + org.jboss.jandex + jandex-maven-plugin + {jandex-plugin-version} + + + make-index + + jandex + + + + +---- +When you build your app `maven` should include the index `META-INF/jandex.idx` in +the JAR. + +[NOTE] +==== +If you _do not_ modify your build to create +the index then the Helidon MP OpenAPI runtime automatically creates one in memory during +app start-up. This slows down your app start-up and, depending on how CDI is +configured, might inadvertently miss information. + +We _strongly recommend_ using the Jandex plug-in to build the index into your app. +==== +// end::additional-building-jandex[] \ No newline at end of file diff --git a/docs/includes/pages.adoc b/docs/includes/pages.adoc index b31b6acb5b1..fc815ed783b 100644 --- a/docs/includes/pages.adoc +++ b/docs/includes/pages.adoc @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// - Copyright (c) 2022 Oracle and/or its affiliates. + Copyright (c) 2022, 2023 Oracle and/or its affiliates. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -18,10 +18,13 @@ ifdef::se-flavor[] :health-page: {rootdir}/se/health.adoc :metrics-page: {rootdir}/se/metrics/metrics.adoc -:openapi-page: {rootdir}/se/openapi.adoc +:openapi-page: {rootdir}/se/openapi/openapi.adoc endif::[] ifdef::mp-flavor[] :health-page: {rootdir}/mp/health.adoc :metrics-page: {rootdir}/mp/metrics/metrics.adoc -:openapi-page: {rootdir}/mp/openapi.adoc -endif::[] \ No newline at end of file +:openapi-page: {rootdir}/mp/openapi/openapi.adoc +endif::[] +:webclient-page: {rootdir}/se/webclient.adoc +:restclient-page: {rootdir}/mp/restclient.adoc +:cli-page: {rootdir}/about/cli.adoc \ No newline at end of file diff --git a/docs/includes/se.adoc b/docs/includes/se.adoc index 6d3b6144af7..07fef9b4052 100644 --- a/docs/includes/se.adoc +++ b/docs/includes/se.adoc @@ -1,6 +1,6 @@ /////////////////////////////////////////////////////////////////////////////// - Copyright (c) 2022 Oracle and/or its affiliates. + Copyright (c) 2022, 2023 Oracle and/or its affiliates. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -28,4 +28,6 @@ include::{rootdir}/includes/attributes.adoc[] :flavor-lc: se :se-flavor: true +include::{rootdir}/includes/pages.adoc[] + endif::flavor-included[] diff --git a/docs/mp/introduction.adoc b/docs/mp/introduction.adoc index 021e5275e4f..78f801265c1 100644 --- a/docs/mp/introduction.adoc +++ b/docs/mp/introduction.adoc @@ -1,6 +1,6 @@ /////////////////////////////////////////////////////////////////////////////// - Copyright (c) 2019, 2022 Oracle and/or its affiliates. + Copyright (c) 2019, 2023 Oracle and/or its affiliates. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -100,7 +100,7 @@ Helidon MP is an Eclipse MicroProfile {version-lib-microprofile-api} runtime tha | link:{microprofile-metrics-spec-url}[{version-lib-microprofile-metrics-api}] | Defining and exposing telemetry data in Prometheus and JSON formats -| xref:{rootdir}/mp/openapi.adoc[MicroProfile Open API] +| xref:{rootdir}/mp/openapi/openapi.adoc[MicroProfile Open API] | link:{microprofile-open-api-spec-url}[{version-lib-microprofile-openapi-api}] | Annotations for documenting your application endpoints diff --git a/docs/mp/openapi/openapi-generator.adoc b/docs/mp/openapi/openapi-generator.adoc new file mode 100644 index 00000000000..373a1a897c3 --- /dev/null +++ b/docs/mp/openapi/openapi-generator.adoc @@ -0,0 +1,68 @@ +/////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2022, 2023 Oracle and/or its affiliates. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +/////////////////////////////////////////////////////////////////////////////// + += OpenAPI-based Code Generation + +:description: Helidon MP OpenAPI Generator +:keywords: helidon, mp, microprofile, openapi, generator +:feature-name: MicroProfile OpenAPI Generator +:rootdir: {docdir}/../.. +:incdir: {rootdir}/includes/openapi +:gen-inc: {incdir}/openapi-generator.adoc + +include::{rootdir}/includes/mp.adoc[] +:helidon-client-xref: {restclient-page} + +include::{gen-inc}[tag=preamble] + +include::{gen-inc}[tags=intro;coords;config;usage;using-generated-code-intro;using-generated-code-server;using-generated-code-client-intro] + +The Helidon MP client generator creates a MicroProfile REST client interface for each API. +Each generated API interface is annotated so your code can `@Inject` the API into one of your own beans and then use the interface directly to invoke the remote service. Alternatively, you can also explicitly use the link:{microprofile-rest-client-javadoc-url}/org/eclipse/microprofile/rest/client/RestClientBuilder.html[`RestClientBuilder`] to create an instance programmatically and then invoke its methods to contact the remote service. +The xref:{restclient-page}[Helidon MP REST Client] documentation describes both approaches in more detail. + +In the following example, `ExampleResource` (itself running in a server) invokes a remote Pet service and shows one way to use the generated `PetApi` REST client interface. + + +[source,java] +.Using the generated `PetApi` from a separate service +---- +@Path("/exampleServiceCallingService") // <1> +public class ExampleResource { + + @Inject // <2> + @RestClient // <3> + private PetApi petApi; // <4> + + @GET + @Path("/getPet/{petId}") + public Response getPetUsingId(@PathParam("petId") Long petId) { + Pet pet = petApi.getPetById(petId); // <5> + //... + } +} +---- +<1> Uses a bean-defining annotation so CDI can inject into this class. +<2> Requests that CDI inject the following field. +<3> Identifies to Helidon MP that the following field is a REST client. +<4> Declares the field using the generated `PetApi` type. +<5> Invokes the remote service using the injected field and the parameter from the incoming request. + + +include::{gen-inc}[tag=common-references] +* link:https://github.com/eclipse/microprofile-rest-client[MicroProfile REST Client specification] diff --git a/docs/mp/openapi/openapi-ui.adoc b/docs/mp/openapi/openapi-ui.adoc new file mode 100644 index 00000000000..5c44a836bf7 --- /dev/null +++ b/docs/mp/openapi/openapi-ui.adoc @@ -0,0 +1,54 @@ +/////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2022, 2023 Oracle and/or its affiliates. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +/////////////////////////////////////////////////////////////////////////////// + += OpenAPI UI +:description: Helidon MP OpenAPI UI Support +:keywords: helidon, mp, openapi ui +:rootdir: {docdir}/../.. +:openapi-inc: {rootdir}/includes/openapi/openapi.adoc +:ui-inc: {rootdir}/includes/openapi/openapi-ui.adoc + +include::{rootdir}/includes/mp.adoc[] + +:javadoc-path: {openapi-ui-javadoc-base-url}/io/helidon/integrations/openapi/ui +:openapi-javadoc-path: {openapi-javadoc-base-url}/io/helidon/openapi + +include::{ui-inc}[tag=preamble] + +include::{ui-inc}[tags=intro;overview] + +include::{ui-inc}[tag=dependencies] + +Also make sure your project has the following dependency to include OpenAPI support in your Helidon MP application. +[source,xml] +---- +include::{openapi-inc}[tag=mp-depc] +---- + +include::{ui-inc}[tag=usage] + +== API + +Your Helidon MP application does not use any API to enable or control Helidon OpenAPI UI support. +Adding the dependency as described earlier is sufficient, and you can control the UI behavior using <>. + +include::{ui-inc}[tag=config-intro] + +include::{ui-inc}[tag=config-details] + +include::{ui-inc}[tag=additional-info] \ No newline at end of file diff --git a/docs/mp/openapi/openapi.adoc b/docs/mp/openapi/openapi.adoc new file mode 100644 index 00000000000..7d7d0de94fe --- /dev/null +++ b/docs/mp/openapi/openapi.adoc @@ -0,0 +1,267 @@ +/////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2019, 2023 Oracle and/or its affiliates. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +/////////////////////////////////////////////////////////////////////////////// + += OpenAPI in Helidon +:description: Helidon MP OpenAPI Support +:keywords: helidon, mp, microprofile, openapi +:feature-name: MicroProfile OpenAPI +:microprofile-bundle: true +:rootdir: {docdir}/../.. +:incdir: {rootdir}/includes/openapi + +include::{rootdir}/includes/mp.adoc[] + +== Contents + +- <> +- <> +- <> +- <> +- <> +- <> +- <> + +== Overview + +include::{incdir}/openapi.adoc[tag=overview] + +include::{rootdir}/includes/dependencies.adoc[] + +[source,xml,subs="attributes+"] +---- +include::{incdir}/openapi.adoc[tag=mp-depc] +---- +If you do not use the `helidon-microprofile-bundle` also add the following dependency which defines the MicroProfile OpenAPI annotations so you can use them in your code: +[source,xml] +---- + + org.eclipse.microprofile.openapi + microprofile-openapi-api + +---- + +== Usage + +=== OpenAPI support in Helidon MP + +You can very simply add support for OpenAPI to your Helidon MP application. This +document shows what changes you need to make to your application and how to access +the OpenAPI document for your application at runtime. + +=== Changing your application + +To use OpenAPI from your Helidon MP app, in addition to adding dependencies as described above: + +1. Furnish OpenAPI information about your application's endpoints. +2. Update your application's configuration (optional). + +include::{incdir}/openapi.adoc[tag=furnish-openapi-info] + +=== Update your application configuration +Beyond the two config properties that denote the model reader and filter, Helidon +MP OpenAPI supports a number of other mandated settings. These are described in the +link:{microprofile-open-api-spec-url}#configuration[configuration section] of the MicroProfile +OpenAPI spec. + +include::{incdir}/openapi.adoc[tag=usage-access-endpoint] + +== API + +include::{incdir}/openapi.adoc[tag=api] + +== Configuration + +Helidon OpenAPI configuration supports the following settings: + +include::{rootdir}/config/io_helidon_microprofile_openapi_MPOpenAPISupport.adoc[leveloffset=+1,tag=config] + +== Examples + +Helidon MP includes a link:{helidon-github-tree-url}/examples/microprofile/openapi-basic[complete OpenAPI example] +based on the MP quick-start sample app. The rest of this section shows, step-by-step, how one might change the original QuickStart service to adopt OpenAPI. + +=== Helidon MP Basic OpenAPI Example + +This example shows a simple greeting application, similar to the one from the +Helidon MP QuickStart, enhanced with OpenAPI support. + +[source,java] +---- +@Path("/greeting") +@PUT +@Operation(summary = "Set the greeting prefix", + description = "Permits the client to set the prefix part of the greeting (\"Hello\")") //<1> +@RequestBody( //<2> + name = "greeting", + description = "Conveys the new greeting prefix to use in building greetings", + content = @Content( + mediaType = "application/json", + schema = @Schema(implementation = GreetingMessage.class), + examples = @ExampleObject( + name = "greeting", + summary = "Example greeting message to update", + value = "New greeting message"))) +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +public Response updateGreeting(JsonObject jsonObject) { + ... +} +---- +<1> With `@Operation` annotation we document the current method. +<2> With `@RequestBody` annotation we document the content produced. Internal annotations `@Content`, `@Schema` and + `@ExampleObjects` are used to give more details about the returned data. + +If we want to hide a specific path an `OASFilter` is used. + +The OASFilter interface allows application developers to receive callbacks for various key OpenAPI elements. The + interface has a default implementation for every method, which allows application developers to only override the + methods they care about. To use it, simply create an implementation of this interface and register it using the + `mp.openapi.filter configuration` key, where the value is the fully qualified name of the filter class. + +The following example filter prevents information about a given path from appearing in the OpenAPI document. + +[source, java] +---- +import org.eclipse.microprofile.openapi.models.Operation; +import org.eclipse.microprofile.openapi.models.PathItem; + +public class SimpleAPIFilter implements OASFilter { + + @Override + public PathItem filterPathItem(PathItem pathItem) { + for (Map.Entry methodOp + : pathItem.getOperations().entrySet()) { + if (SimpleAPIModelReader.DOOMED_OPERATION_ID + .equals(methodOp.getValue().getOperationId())) { + return null; + } + } + return OASFilter.super.filterPathItem(pathItem); + } +} +---- + +You can implement a model reader to provide all or part of the in-memory `OpenAPI` model programmatically. Helidon + `OpenAPI` merges the model from the model reader with models from the other sources (a static file and annotations). + +The example model reader below creates an `OpenAPI` object describing two paths. It turns out that the filter described +earlier will suppress one of the paths, but the model reader does not know or care. + +[source,java] +---- +import org.eclipse.microprofile.openapi.OASFactory; +import org.eclipse.microprofile.openapi.OASModelReader; +import org.eclipse.microprofile.openapi.models.OpenAPI; +import org.eclipse.microprofile.openapi.models.PathItem; +import org.eclipse.microprofile.openapi.models.Paths; + +/** + * Defines two paths using the OpenAPI model reader mechanism, one that should + * be suppressed by the filter class and one that should appear in the published + * OpenAPI document. + */ +public class SimpleAPIModelReader implements OASModelReader { + + /** + * Path for the example endpoint added by this model reader that should be visible. + */ + public static final String MODEL_READER_PATH = "/test/newpath"; + + /** + * Path for an endpoint that the filter should hide. + */ + public static final String DOOMED_PATH = "/test/doomed"; + + /** + * ID for an endpoint that the filter should hide. + */ + public static final String DOOMED_OPERATION_ID = "doomedPath"; + + /** + * Summary text for the endpoint. + */ + public static final String SUMMARY = "A sample test endpoint from ModelReader"; + + @Override + public OpenAPI buildModel() { + /* + * Add two path items, one of which we expect to be removed by + * the filter and a very simple one that will appear in the + * published OpenAPI document. + */ + PathItem newPathItem = OASFactory.createPathItem() + .GET(OASFactory.createOperation() + .operationId("newPath") + .summary(SUMMARY)); + PathItem doomedPathItem = OASFactory.createPathItem() + .GET(OASFactory.createOperation() + .operationId(DOOMED_OPERATION_ID) + .summary("This should become invisible")); + OpenAPI openAPI = OASFactory.createOpenAPI(); + Paths paths = OASFactory.createPaths() + .addPathItem(MODEL_READER_PATH, newPathItem) + .addPathItem(DOOMED_PATH, doomedPathItem); + openAPI.paths(paths); + + return openAPI; + } +} +---- + +Having written the filter and model reader classes, identify them by adding configuration to + `META-INF/microprofile-config.properties` as the following example shows. + +[source,properties] +---- +mp.openapi.filter=io.helidon.microprofile.examples.openapi.basic.internal.SimpleAPIFilter +mp.openapi.model.reader=io.helidon.microprofile.examples.openapi.basic.internal.SimpleAPIModelReader +---- + + +Now just build and run: + +[source,bash] +---- +mvn package +java -jar target/helidon-examples-microprofile-openapi-basic.jar +---- + +Try the endpoints: + +[source,bash] +---- +curl -X GET http://localhost:8080/greet +{"message":"Hello World!"} + +curl -X GET http://localhost:8080/openapi +[lengthy OpenAPI document] +---- + +The output describes not only then endpoints from `GreetResource` but +also one contributed by the `SimpleAPIModelReader`. + +Full example is available link:{helidon-github-tree-url}}/examples/microprofile/openapi-basic[in our official repository] + + +== Additional Information +include::{incdir}/openapi.adoc[tag=additional-building-jandex] + +== Reference + +* link:https://github.com/eclipse/microprofile-open-api[MicroProfile OpenAPI GitHub Repository] +* link:{microprofile-open-api-spec-url}[MicroProfile OpenAPI Specification] diff --git a/docs/nima/guides/overview.adoc b/docs/nima/guides/overview.adoc new file mode 100644 index 00000000000..8016a99616c --- /dev/null +++ b/docs/nima/guides/overview.adoc @@ -0,0 +1,28 @@ +/////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2023 Oracle and/or its affiliates. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +/////////////////////////////////////////////////////////////////////////////// + += Helidon Níma Guides +:description: Helidon Níma Guides +:keywords: helidon, java, microservices, microprofile, guides +:rootdir: {docdir}/../.. + +include::{rootdir}/includes/nima.adoc[] + +== Getting Started + + diff --git a/docs/nima/introduction.adoc b/docs/nima/introduction.adoc new file mode 100644 index 00000000000..dce52141e0b --- /dev/null +++ b/docs/nima/introduction.adoc @@ -0,0 +1,26 @@ +/////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2023 Oracle and/or its affiliates. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +/////////////////////////////////////////////////////////////////////////////// + += Helidon Níma +:description: about Helidon Níma +:keywords: helidon, java, microservices, reactive, virtual threads +:rootdir: {docdir}/.. + +include::{rootdir}/includes/nima.adoc[] + +== Introduction \ No newline at end of file diff --git a/docs/se/introduction.adoc b/docs/se/introduction.adoc index 692478afb89..5532714c021 100644 --- a/docs/se/introduction.adoc +++ b/docs/se/introduction.adoc @@ -1,6 +1,6 @@ /////////////////////////////////////////////////////////////////////////////// - Copyright (c) 2019, 2022 Oracle and/or its affiliates. + Copyright (c) 2019, 2023 Oracle and/or its affiliates. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -97,7 +97,7 @@ Instrumentation to expose metrics of your applications. //Openapi [CARD] .OpenAPI -[icon=donut_large,link=openapi.adoc] +[icon=donut_large,link=openapi/openapi.adoc] -- Support OpenAPI from your application. -- diff --git a/docs/se/openapi/openapi-generator.adoc b/docs/se/openapi/openapi-generator.adoc new file mode 100644 index 00000000000..82c28f76e9a --- /dev/null +++ b/docs/se/openapi/openapi-generator.adoc @@ -0,0 +1,303 @@ +/////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2022, 2023 Oracle and/or its affiliates. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +/////////////////////////////////////////////////////////////////////////////// + += OpenAPI-based Code Generation +:rootdir: {docdir}/../.. +:incdir: {rootdir}/includes/openapi +:gen-inc: {incdir}/openapi-generator.adoc + +include::{rootdir}/includes/se.adoc[] + +:helidon-client-xref: {webclient-page} +include::{gen-inc}[tag=preamble] + +include::{gen-inc}[tags=intro;coords;config;usage;using-generated-code-intro;using-generated-code-server-intro] + + +The Helidon SE server generator also creates, for each API, a separate class containing handler methods for each endpoint. +Along with the `PetService` interface or abstract class which has methods such as `addPet` and `getPetById`, the tool generates `PetServiceImpl` with methods such as `handleAddPet` and `handleGetPetById`. + +[source,java] +.Generated `PetService` abstract class +---- +public abstract class PetService implements Service { + void addPet(ServerRequest request, ServerResponse response, Pet pet) { + // ... + } + abstract void handleAddPet(ServerRequest request, ServerResponse response, Pet pet); + + void getPetById(ServerRequest request, ServerResponse response) { + // ... + } + abstract void handleGetPetById(ServerRequest request, ServerResponse response, Long petId); +} +---- + +[source,java] +.Generated skeleton `PetServiceImpl` class (which you extend) +---- +public class PetServiceImpl extends PetService { + public void handleAddPet(ServerRequest request, ServerResponse response, Pet pet) { + response.status(HTTP_CODE_NOT_IMPLEMENTED.send()); + } + + public void handleGetPetById(ServerRequest request, ServerResponse response, Long petId) { + response.status(HTTP_CODE_NOT_IMPLEMENTED).send(); + } +} +---- +You write your own classes which extend `PetServiceImpl` and the other generated `xxxImpl` classes, overriding the `handle...` methods. + +You have control over--and therefore responsibility for--preparing the response to be sent to the client, including the status, any response headers, and any returned entity. +Your overriding implementation of `handleGetPetById` might look like the following example. + +[source,java] +.Example override of `handleGetPetById` +---- +public void handleGetPetById(ServerRequest request, ServerResponse response, Long petId) { + Pet pet = locatePetInDatabase(petId); + if (pet == null) { + response.status(404).send(); + } + response.send(pet); // Respnose status is 200 by default. + } +} +---- + +include::{gen-inc}[tag=using-generated-code-client-intro] + +The generated Helidon SE client includes the class `ApiClient`. This class corresponds to +the Helidon link:{webclient-javadoc-base-url}/io/helidon/webclient/WebClient.html[`WebClient`] and represents the connection between your code and the remote server. The generator also creates one or more `Api` interfaces and corresponding implementation classes. The examples below use the `PetApi` interface and the `PetApiImpl` class. + +To invoke the remote service your code must: + +. Create an instance of `ApiClient` using an `ApiClient.Builder`. +. Use that `ApiClient` instance to instantiate a `PetApi` object. +. Invoke the methods on the `PetApi` object to access the remote services and then retrieve the returned result value. + +The following sections explain these steps. + +==== Creating an `ApiClient` Instance +The Helidon SE client generator gives you as much flexibility as you need in connecting to the remote service. + +Internally, the `ApiClient` uses a Helidon `WebClient` object to contact the remote system. +The `ApiClient.Builder` automatically prepares a Helidon +link:{webclient-javadoc-base-url}/io/helidon/webclient/WebClient.Builder.html[`WebClient.Builder`] object using information from the OpenAPI document. + +The next sections describe, from simplest to most complicated, the ways your code can create an `ApiClient` instance, each involving increased involvement with the `WebClient.Builder` object. + +===== Accepting the Automatic `WebClient.Builder` +In the simplest case, your code can get an `ApiClient` instance directly. + +[source,java] +.Creating an `ApiClient` instance - simple case +---- +ApiClient apiClient = ApiClient.builder().build(); +---- + +Your code relies fully on the automatic `WebClient.Builder`. +In many cases, this approach works very well, especially if the OpenAPI document correctly declares the servers and their URIs. + +===== Influencing the Automatic `WebClient.Builder` +Your code can use the `ApiClient.Builder` to fine-tune the settings for the internal `WebClient.Builder`. +For instance, your code can set an object mapper to be used for Jackson processing or the `JsonbConfig` object to be used for JSON-B processing, depending on which serialization library you chose when you ran the generator. + +Your code does not need to know how the object mapper setting is conveyed to the internal `WebClient.Builder`. The `ApiClient.Builder` knows how to do that. + +[source,java] +.Creating an `ApiClient` instance - influencing the `ApiClient.Builder` +---- +ApiClient apiClient = apiClient.builder() + .objectMapper(yourCustomMapper) + .build(); +---- + +===== Adjusting the Automatic `WebClient.Builder` +In more complicated situations, your code can adjust the settings of the `WebClient.Builder` the `ApiClient.Builder` creates. + +[source,java] +.Creating an `ApiClient` instance - adjusting the `WebClient.Builder` +---- +ApiClient.Builder apiClientBuilder = ApiClient.builder(); + +apiClientBuilder.webClientBuilder() // <1> + .connectTimeout(4, TimeUnit.SECONDS); // <2> + +ApiClient apiClient = apiClientBuilder.build(); // <3> +---- +<1> Access the `ApiClient.Builder`'s automatic `WebClient.Builder` instance. +<2> Adjust a setting of the `WebClient.Builder` directly. +<3> Build the `ApiClient` which implicitly builds the `WebClient` from the now-adjusted internal `WebClient.Builder`. + +The automatic `WebClient.Builder` retains information derived from the OpenAPI document unless your code overrides those specific settings. + +===== Providing a Custom `WebClient.Builder` +Lastly, you can construct the `WebClient.Builder` entirely yourself and have the `ApiClient.Builder` use it instead of its own internal builder. + +[source,java] +.Creating an `ApiClient` instance - using a custom `WebClient.Builder` +---- +WebClient.Builder customWebClientBuilder = WebClient.builder() + .connectTimeout(3, TimeUnit.SECONDS) + .baseUri("https://myservice.mycompany.com"); + +ApiClient apiClient = ApiClient.builder() + .webClientBuilder(customWebClientBuilder) + .build(); +---- +Note that this approach entirely replaces the internal, automatically-prepared `WebClient.Builder` with yours; it _does not_ merge the new builder with the internal one. In particular, any information from the OpenAPI document the generator used to prepare the internal `WebClient.Builder` is lost. + + +==== Creating a `PetApi` Instance +The `ApiClient` represents the connection to the remote server but not the individual RESTful operations. +Each generated `xxxApi` interface exposes a method for each operation declared in the OpenAPI document associated with that API via its `tags` value. +By example, the `PetApi` interface exposes a method for each operation in the OpenAPI document that pertains to pets. + +To invoke an operation defined on the `PetApi` interface, your code instantiates a `PetApi` using an `ApiClient` object: + +[source,java] +.Preparing the PetStore Client API +---- +ApiClient apiClient = ApiClient.builder().build(); +PetApi petApi = PetApiImpl.create(apiClient); +---- + +==== Invoking Remote Endpoints +With the `petApi` object, your code can invoke any of the methods on the `PetApi` interface to contact the remote service. + +The Helidon WebClient follows a reactive programming model, and the Helidon SE client generator creates an `ApiResponse` interface, also reactive. +Each generated `PetApi` method returns an `ApiResponse` where the `returnType` is the return type declared in the OpenAPI document for the corresponding operation. + +The `ApiResponse` interface exposes two methods your code can use to work with the response from the remote service invocation: + +* `Single result()` ++ +Provides reactive access to the value returned by the remote service in the response. +This method lets your code fetch the return value directly. +* `Single webClientResponse()` ++ +Provides reactive access to the Helidon `WebClientResponse` object. +Your code can find out the HTTP return status, read headers in the response, and process the content (if any) in the response however it needs to. + +In the reactive Helidon WebClient model, the first part of the response message can arrive (the status and headers are available) before the entity in the body of the response is readable. +So there are two reactive events associated with an incoming HTTP response: + +. when the response _excluding_ the entity content has arrived, and +. when your code can begin consuming the entity content. + +You can adopt different styles of retrieving the results, depending on the specific needs of the code you are writing. + +===== Synchronous access to the result +This example shows the simplest way to invoke the remote service and work with the result. + +[source,java] +.Synchronous access to the return value +---- +// Assumes the petApi field is initialized as above. +List availablePets = petApi.findPetsByStatus(List.of(Pet.StatusEnum.AVAILABLE.value())) // <1> + .result() // <2> + .await(4, TimeUnit.SECONDS); // <3> +---- +<1> Start the remote service invocation. +<2> Access the reactive result. +<3> Wait for the result to arrive subject to a four-second timeout. + +This code blocks the current thread, waiting up to four seconds for the response to arrive. +This approach might be adequate if you are developing a command-line client where the thread has no other meaningful work to do until it has the result. +This is _not_ an appropriate style for server code that uses the generated client to invoke another service. + +Note that this approach offers no access to the HTTP status for the response or any headers that might have been returned. + +===== Synchronous access with status checking +The Helidon WebClient programming model includes a `WebClientResponse` interface which exposes all aspects of the HTTP response returned from the remote service. + +The next example shows how your code can use the `WebClientResponse`. + +[source,java] +.Synchronous access with status checking +---- +ApiResponse> apiResponse = petApi.findPetsByStatus(List.of(Pet.StatusEnum.AVAILABLE.value())); // <1> + +WebClientResponse webClientResponse = apiResponse.webClientResponse() + .await(4, TimeUnit.SECONDS); // <2> + +if (webClientResponse.status().code() != 200) { // <3> + // Handle a non-successful status. +} + +List> availablePets = apiResponse.result() + .await(4, TimeUnit.SECONDS); // <4> +---- +<1> Start the remote service invocation. +<2> Wait for the HTTP response status and headers to arrive. +<3> Check the status in the HTTP response. +<4> Wait for the content to arrive subject to a four-second timeout. + +This code also blocks the current thread, first to wait for the initial response and then to wait for the result content. + +===== Fully-reactive access +The following example shows how your code might invoke the remote service and process the response using the reactive programming model. + +.Fully-reactive access with status checking +[source,java] +---- +// Assumes the petApi field is initialized as above. +ApiResponse> availablePetsResponse = + petApi.findPetsByStatus(List.of(Pet.StatusEnum.AVAILABLE.value())); // <1> + +availablePetsResponse.webClientResponse() + .thenAccept(resp -> { // <2> + if (resp.status().code() == 200) { + try { + availablePetsResponse.result() // <3> + .thenAccept(availablePets -> { + // Process the List of available pets. // <4> + + }) + .exceptionally(throwable -> { + // Handle whatever problem occurred in retrieving the results. // <5> + return null; + }); + } catch (ExecutionException | InterruptedException e) { + // Handle errors while waiting for the response content to arrive. // <6> + } + } else { + // Handle non-200 HTTP status. // <7> + }) + .exceptionally(throwable -> { + // Handle whatever problem occurred in receiving the response. // <8> + return null; + }); +---- +<1> Starts the remote service invocation. +<2> Reactively processes the first portion of the HTTP response. +<3> Reactively processes a successfully-received HTTP response. +<4> Reactively processes the successfully-returned list of available pets. +<5> Reactively handles any errors in retrieving the list of available pets. +<6> Handle problems that occurred while waiting for the response content to arrive. +<7> Handle a non-200 response status. +<8> Reactively handles any errors in receiving the HTTP response. + +The fully-reactive approach brings with it some complexity, but it lets your code completely avoid blocking the thread that initiates the outbound remote service access. +Avoiding blocking is especially important if the code which uses the generated client runs in a server. + +Some of this complexity enters because there are several ways this processing can fail. +Your code should handle each of them in whatever ways make sense for your application, and that might mean dealing with each different error scenario in a different way. + +include::{gen-inc}[tag=common-references] +* xref:{helidon-client-xref}[Helidon WebClient documentation] \ No newline at end of file diff --git a/docs/se/openapi/openapi-ui.adoc b/docs/se/openapi/openapi-ui.adoc new file mode 100644 index 00000000000..029f6930e21 --- /dev/null +++ b/docs/se/openapi/openapi-ui.adoc @@ -0,0 +1,130 @@ +/////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2022, 2023 Oracle and/or its affiliates. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +/////////////////////////////////////////////////////////////////////////////// + += OpenAPI UI +:description: Helidon SE OpenAPI UI Support +:keywords: helidon, se, openapi ui +:rootdir: {docdir}/../.. +:ui-inc: {rootdir}/includes/openapi/openapi-ui.adoc + +include::{rootdir}/includes/se.adoc[] + +:javadoc-path: {openapi-ui-javadoc-base-url}/io/helidon/integrations/openapi/ui +:openapi-javadoc-path: {openapi-javadoc-base-url}/io/helidon/openapi + +include::{ui-inc}[tag=preamble] + +include::{ui-inc}[tags=intro;overview] + +include::{ui-inc}[tag=dependencies] + +Also, make sure your project has the following dependency. + +include::{docdir}/openapi.adoc[tag=depc] + +This dependency allows your application to create, configure, and register the `OpenAPISupport` service. + +include::{ui-inc}[tag=usage] + +== API +=== Creating `OpenAPISupport` with Automatic UI Behavior +With the Helidon OpenAPI UI dependency in your `pom.xml` file, any `OpenAPISupport` object your application builds prepares the default OpenAPI UI behavior, possibly modified by any UI settings you have in your configuration. + +[source,java] +.Create `OpenAPISupport` with automatic UI +---- +Config config = Config.create(); // <1> +Config openApiConfig = config.get(OpenAPISupport.Builder.CONFIG_KEY)); // <2> + +OpenAPISupport openApiSupport = + OpenAPISupport.builder() + .config(openApiConfig) // <3> + .build(); +---- +<1> Load the configuration. +<2> Extract the `OpenAPISupport` configuration. +<3> Build the `OpenAPISupport` instance using the configuration. + +If your code invokes the `OpenAPISupport.Builder` `config` method, Helidon automatically applies the `ui` section of the `openapi` configuration to the UI. + +=== Customizing the UI Behavior +You can control some of the behavior of the UI programmatically in two steps: + +. Create an link:{javadoc-path}/OpenApiUi.Builder.html[`OpenApiUi.Builder`] and invoke methods on it to set the UI behavior. +. Invoke the `ui` method on link:{openapi-javadoc-base-url}/io.helidon.openapi.OpenAPISupport.Builder.html[`OpenAPISupport.Builder`], passing the `OpenApiUi.Builder` you prepared above. + +The following example illustrates these steps, combining configuration with explicit programmatic settings. + +[source,java] +.Create `OpenApiUi` and `OpenAPISupport` instances +---- +Config config = Config.create(); // <1> +Config openApiConfig = config.get(OpenAPISupport.Builder.CONFIG_KEY)); // <2> + +OpenApiUi.Builder uiBuilder = + OpenApiUi.builder() // <3> + .webContext("/my-openapi-ui"); // <4> + +OpenAPISupport openApiSupport = + OpenAPISupport.builder() // <5> + .ui(uiBuilder) + .config(openApiConfig) // <6> + .build(); + + +---- +<1> Load the configuration. +<2> Extract the `OpenAPISupport` configuration. +<3> Create the `OpenApiUi.Builder` instance. +<4> Explicitly set the web context where the UI should respond. +<5> Create the `OpenAPISupport` instance using the `OpenApiUi.Builder` just created. +You can refine the behavior of the `OpenAPISupport` object by invoking additional methods on its builder before invoking its `build` method. +<6> Apply the `openapi` configuration to the `OpenAPISupport` builder. This also automatically applies any `openapi.ui` configuration to the UI. + +The order in which your code invokes the methods on `OpenApiUi.Builder` and `OpenAPISupport.Builder` determines the outcome. +For instance, the example above sets the UI on the `OpenAPISupport.Builder` _before_ applying configuration. +If the configuration contains a setting for the UI's `web-context` value then the UI uses the configured value, not the programmatic value, because your code applied the configuration later. +Your code should typically apply configuration _after_ setting any values programmatically. +Doing so allows users or deployers of your service to set the behavior using configuration according to their particular needs which your code might not be able to anticipate. + +[NOTE] +==== +The `webContext(String)` method on `OpenApiUi.Builder` sets the web context where the UI should respond instead of the default `/openapi/ui`. +Helidon uses the provided string to set the _entire_ web context for the UI, not as a suffix appended to the web context for the `OpenAPISupport` service. +==== + +=== Registering `OpenAPISupport` +Whether or not your code tailors the UI or `OpenAPISupport` behavior, it must register the resulting `OpenAPISupport` instance so that the OpenAPI and UI endpoints can respond correctly. + +[source,java] +.Register services for routing +---- +Routing.builder() + .register(openApiSupport) + // Add registrations of your service(s) and other Helidon services you need. + .build(); +---- + +The UI is implemented as part of the `OpenAPISupport` service which registers the UI automatically. +Your code does not register the UI explicitly. + +include::{ui-inc}[tag=config-intro] + +include::{ui-inc}[tag=config-details] + +include::{ui-inc}[tag=additional-info] \ No newline at end of file diff --git a/docs/se/openapi/openapi.adoc b/docs/se/openapi/openapi.adoc new file mode 100644 index 00000000000..218fec75043 --- /dev/null +++ b/docs/se/openapi/openapi.adoc @@ -0,0 +1,126 @@ +/////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2019, 2023 Oracle and/or its affiliates. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +/////////////////////////////////////////////////////////////////////////////// + += OpenAPI in Helidon +:description: Helidon SE OpenAPI Support +:keywords: helidon, se, openapi +:feature-name: OpenAPI +:rootdir: {docdir}/../.. +:incdir: {rootdir}/includes/openapi + +include::{rootdir}/includes/se.adoc[] +:javadoc-path: {openapi-javadoc-base-url}/io.helidon.openapi + +== Contents + +- <> +- <> +- <> +- <> +- <> +- <> +- <> + +== Overview + +include::{incdir}/openapi.adoc[tag=overview] + +include::{rootdir}/includes/dependencies.adoc[] + +// tag::depc[] +[source,xml] +---- + + io.helidon.openapi + helidon-openapi + +---- +// end::depc[] + +== Usage + +You can very simply add support for OpenAPI to your Helidon SE application. This +document shows what changes you need to make to your application and how to access +the OpenAPI document for your application at runtime. + +=== Changing your application + +==== Register `OpenAPISupport` in your application routing + +Helidon SE provides the link:{javadoc-path}/OpenAPISupport.html[`OpenAPISupport`] class which your application uses to assemble the in-memory model and expose the `/openapi` endpoint to clients. You can create an instance either using a static `create` method or by instantiating its link:{javadoc-path}/OpenAPISupport.Builder.html[`Builder`]. The xref:#register_openapisupport[example below] illustrates one way to do this. + +include::{incdir}/openapi.adoc[tag=furnish-openapi-info] + +==== Add OpenAPI dependency +If you implement either a model reader or a filter, add this dependency to your +`pom.xml`: + +[source,xml,subs="attributes+"] +---- + + org.eclipse.microprofile.openapi + microprofile-openapi-api + {microprofile-openapi-version} + +---- + +include::{incdir}/openapi.adoc[tag=usage-access-endpoint] + +== API + +include::{incdir}/openapi.adoc[tag=api] + +Helidon {flavor-uc} provides an API for creating and setting up the REST endpoint which serves OpenAPI documents to clients at the `/openapi` path. Use either static methods on link:{javadoc-path}/OpenAPISupport.html[`OpenAPISupport`] or use its link:{javadoc-base}/OpenAPISupport.Builder.html[`Builder`] to create an instance of `OpenAPISupport`. Then add that instance to your application's routing. The <<#register_openapisupport,example>> below shows how to do this. + +[[config]] +== Configuration + +Helidon SE OpenAPI configuration supports the following settings: + +include::{rootdir}/config/io_helidon_openapi_SEOpenAPISupport.adoc[leveloffset=+1,tag=config] + + + +== Examples + +Helidon SE provides a link:{helidon-github-tree-url}/examples/openapi[complete OpenAPI example] +based on the SE QuickStart sample app which includes a model reader and a filter. + +Most Helidon {flavor-uc} applications need only to create and register `OpenAPISupport`. + +[#register_openapisupport] +=== Register `OpenAPISupport` + +.Java Code to Register `OpenAPISupport` for Routing +[source,java] +---- +Config config = Config.create(); +return Routing.builder() + .register(JsonSupport.create()) + .register(OpenAPISupport.create(config)) // <1> + .register(health) // Health at "/health" + .register(metrics) // Metrics at "/metrics" + .register("/greet", greetService) + .build(); +---- +<1> Adds the `OpenAPISupport` service to your server. + +If you need more control over the `OpenAPISupport` instance, invoke `OpenAPISupport.builder()` to get an `OpenAPISupport.Builder` object and work with it. + +== Additional Information +include::{incdir}/openapi.adoc[tag=additional-building-jandex] \ No newline at end of file diff --git a/docs/sitegen.yaml b/docs/sitegen.yaml index 6eeba76b4da..f2ca0034da8 100644 --- a/docs/sitegen.yaml +++ b/docs/sitegen.yaml @@ -42,7 +42,7 @@ pages: - "includes/**" backend: name: "vuetify" - homePage: "about/introduction.adoc" + homePage: "about/doc_overview.adoc" releases: - "${project.version}" navigation: @@ -53,8 +53,8 @@ backend: value: "images/helidon_logo_dark.svg" items: - type: "PAGE" - title: "Introduction" - source: "about/introduction.adoc" + title: "Documentation Overview" + source: "about/doc_overview.adoc" glyph: type: "icon" value: "lightbulb" @@ -78,6 +78,24 @@ backend: value: "widgets" - type: "GROUPS" items: + - type: "GROUP" + title: "Helidon Nima" + dir: "nima" + items: + - type: "PAGE" + title: "Introduction" + source: "introduction.adoc" + glyph: + type: "icon" + value: "lightbulb" + - type: "MENU" + title: "Guides" + dir: "guides" + glyph: + type: "icon" + value: "explore" + sources: + - "overview.adoc" - type: "GROUP" title: "Helidon SE" dir: "se" @@ -138,6 +156,24 @@ backend: glyph: type: "icon" value: "storage" + - type: "PAGE" + title: "Fault Tolerance" + source: "fault-tolerance.adoc" + glyph: + type: "icon" + value: "warning" + - type: "PAGE" + title: "GraalVM Native Image" + source: "aot.adoc" + glyph: + type: "icon" + value: "save" + - type: "PAGE" + title: "GraphQL Server" + source: "graphql.adoc" + glyph: + type: "icon" + value: "graphic_eq" - type: "MENU" title: "gRPC" dir: "grpc" @@ -147,18 +183,22 @@ backend: sources: - "server.adoc" - "client.adoc" - - type: "PAGE" - title: "GraphQL server" - source: "graphql.adoc" - glyph: - type: "icon" - value: "graphic_eq" - type: "PAGE" title: "Health Checks" source: "health.adoc" glyph: type: "icon" value: "favorite_outline" + - type: "MENU" + title: "Integrations" + dir: "integrations" + glyph: + type: "icon" + value: "filter_drama" + sources: + - "oci.adoc" + - "hcv.adoc" + - "neo4j.adoc" - type: "MENU" title: "Metrics" dir: "metrics" @@ -170,22 +210,22 @@ backend: - "micrometer.adoc" - "prometheus-exemplar-support.adoc" - "metrics-capable-components.adoc" - - type: "PAGE" + - type: "MENU" title: "OpenAPI" - source: "openapi.adoc" + dir: "openapi" glyph: type: "icon" value: "donut_large" - - type: "MENU" - title: "Integrations" - dir: "integrations" + sources: + - "openapi.adoc" + - "openapi-generator.adoc" + - "openapi-ui.adoc" + - type: "PAGE" + title: "Reactive Messaging" + source: "reactive-messaging.adoc" glyph: type: "icon" - value: "filter_drama" - sources: - - "oci.adoc" - - "hcv.adoc" - - "neo4j.adoc" + value: "message" - type: "MENU" title: "Reactive Streams" dir: "reactivestreams" @@ -195,18 +235,18 @@ backend: sources: - "engine.adoc" - "rsoperators.adoc" - - type: "PAGE" - title: "Reactive Messaging" - source: "reactive-messaging.adoc" - glyph: - type: "icon" - value: "message" - type: "PAGE" title: "Reactive Webserver" source: "webserver.adoc" glyph: type: "icon" value: "settings_ethernet" + - type: "PAGE" + title: "Scheduling" + source: "scheduling.adoc" + glyph: + type: "icon" + value: "access_alarm" - type: "MENU" title: "Security" dir: "security" @@ -220,12 +260,6 @@ backend: - "tools.adoc" - "extensibility.adoc" - "jep-290.adoc" - - type: "PAGE" - title: "Scheduling" - source: "scheduling.adoc" - glyph: - type: "icon" - value: "access_alarm" - type: "PAGE" title: "Tracing" source: "tracing.adoc" @@ -244,18 +278,6 @@ backend: glyph: type: "icon" value: "timeline" - - type: "PAGE" - title: "AOT" - source: "aot.adoc" - glyph: - type: "icon" - value: "save" - - type: "PAGE" - title: "Fault Tolerance" - source: "fault-tolerance.adoc" - glyph: - type: "icon" - value: "warning" - type: "GROUP" title: "Helidon MP" dir: "mp" @@ -318,6 +340,18 @@ backend: glyph: type: "icon" value: "warning" + - type: "PAGE" + title: "GraalVM Native Image" + source: "aot.adoc" + glyph: + type: "icon" + value: "save" + - type: "PAGE" + title: "GraphQL Server" + source: "graphql.adoc" + glyph: + type: "icon" + value: "graphic_eq" - type: "MENU" title: "gRPC" dir: "grpc" @@ -327,18 +361,23 @@ backend: sources: - "server.adoc" - "client.adoc" - - type: "PAGE" - title: "GraphQL" - source: "graphql.adoc" - glyph: - type: "icon" - value: "graphic_eq" - type: "PAGE" title: "Health Checks" source: "health.adoc" glyph: type: "icon" value: "favorite_outline" + - type: "MENU" + title: "Integrations" + dir: "integrations" + glyph: + type: "icon" + value: "filter_drama" + sources: + - "oci.adoc" + - "hcv.adoc" + - "jedis.adoc" + - "neo4j.adoc" - type: "MENU" title: "JAX-RS/Jersey" dir: "jaxrs" @@ -349,24 +388,18 @@ backend: - "application-configuration.adoc" - "jaxrs-applications.adoc" - "jaxrs-client.adoc" - - type: "PAGE" - title: "Persistence" - source: "persistence.adoc" - glyph: - type: "icon" - value: "dns" - type: "PAGE" title: "JWT" source: "jwt.adoc" glyph: type: "icon" - value: "verified_user" + value: "verified_user" - type: "PAGE" title: "Long Running Actions (LRA)" source: "lra.adoc" glyph: type: "icon" - value: "pending_actions" + value: "pending_actions" - type: "MENU" title: "Metrics" dir: "metrics" @@ -378,32 +411,22 @@ backend: - "micrometer.adoc" - "prometheus-exemplar-support.adoc" - "metrics-capable-components.adoc" - - type: "PAGE" + - type: "MENU" title: "OpenAPI" - source: "openapi.adoc" + dir: "openapi" glyph: type: "icon" value: "donut_large" - - type: "MENU" - title: "Integrations" - dir: "integrations" - glyph: - type: "icon" - value: "filter_drama" sources: - - "oci.adoc" - - "hcv.adoc" - - "jedis.adoc" - - "neo4j.adoc" - - type: "MENU" - title: "Reactive Streams" - dir: "reactivestreams" + - "openapi.adoc" + - "openapi-generator.adoc" + - "openapi-ui.adoc" + - type: "PAGE" + title: "Persistence" + source: "persistence.adoc" glyph: type: "icon" - value: "waves" - sources: - - "engine.adoc" - - "rsoperators.adoc" + value: "dns" - type: "MENU" title: "Reactive Messaging" dir: "reactivemessaging" @@ -417,12 +440,27 @@ backend: - "aq.adoc" - "weblogic.adoc" - "mock.adoc" + - type: "MENU" + title: "Reactive Streams" + dir: "reactivestreams" + glyph: + type: "icon" + value: "waves" + sources: + - "engine.adoc" + - "rsoperators.adoc" - type: "PAGE" title: "REST Client" source: "restclient.adoc" glyph: type: "icon" value: "airplay" + - type: "PAGE" + title: "Scheduling" + source: "scheduling.adoc" + glyph: + type: "icon" + value: "access_alarm" - type: "MENU" title: "Security" dir: "security" @@ -435,11 +473,19 @@ backend: - "configuration-secrets.adoc" - "jep-290.adoc" - type: "PAGE" - title: "Scheduling" - source: "scheduling.adoc" + title: "Server" + source: "server.adoc" glyph: type: "icon" - value: "access_alarm" + value: "settings_ethernet" + - type: "MENU" + title: "Testing" + glyph: + type: "icon" + value: "thumbs_up_down" + sources: + - "testing.adoc" + - "testing-ng.adoc" - type: "PAGE" title: "Tracing" source: "tracing.adoc" @@ -452,26 +498,6 @@ backend: glyph: type: "icon" value: "sync_alt" - - type: "PAGE" - title: "Server" - source: "server.adoc" - glyph: - type: "icon" - value: "settings_ethernet" - - type: "PAGE" - title: "AOT" - source: "aot.adoc" - glyph: - type: "icon" - value: "save" - - type: "MENU" - title: "Testing" - glyph: - type: "icon" - value: "thumbs_up_down" - sources: - - "testing.adoc" - - "testing-ng.adoc" - type: "HEADER" title: "Additional resources" - type: "LINK"