Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add explanation/concept for extension maturity model #42446

Open
wants to merge 21 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/src/main/asciidoc/building-my-first-extension.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ The extension will expose a customizable HTTP endpoint which simply greets the v
[NOTE]
.Disclaimer
To be sure it's extra clear you don't need an extension to add a Servlet to your application.
This guide is a simplified example to explain the concepts of extensions development, see the xref:writing-extensions.adoc[full documentation] if you need more information.
This guide is a simplified example to explain the concepts of extensions development, see the :writing-extensions.adoc[full documentation] if you need more information.
Keep in mind it's not representative of the power of moving things to build time or simplifying the build of native images.

== Prerequisites
Expand Down
170 changes: 170 additions & 0 deletions docs/src/main/asciidoc/extension-maturity-matrix.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
////
This guide is maintained in the main Quarkus repository
and pull requests should be submitted there:
https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc
////
[id="extension-maturity-matrix"]
= A maturity model for Quarkus extensions
include::_attributes.adoc[]
:diataxis-type: concept
:categories: writing-extensions
:topics: extensions
:summary: Quarkus extensions can do a lot, or a little. This guide explains some of the capabilities extension authors might want to include.
////
The document header ends at the first blank line. Do not remove the blank line between the header and the abstract summary.
////

What makes a good Quarkus extension? What capabilities is a Quarkus extension expected to provide? Of course, it depends on the extension you are building. But, we found a set of attributes common to many extensions. This document explains what they are.

image::extension-maturity-matrix.png[A maturity matrix]

This isn't defining an exact order, even within a single row. Different extensions have different goals, and different developers will have different views on what capabilities are most important. You may wish to (for example) prioritise a fantastic programming model over enhancing your extension's Dev UI tile. That's fine!

Also, not every step will apply to every extension. For example, you don't need a Dev Service if your extension doesn't depend on external services.

It's completely OK to publish a first version of an extension that doesn't handle everything. In fact, it's OK if your extension _never_ gets to the more advanced features. This is a suggested pathway, not a minimum feature set.

Also note that this list only includes the technical features of your extension.
You might also want to think about how you share your extension, and how it presents itself to the world.
The link:https://hub.quarkiverse.io/checklistfornewprojects/[new extension checklist] on the Quarkiverse Hub has a useful list of ways extensions can participate in the ecosystem.
It's also a good idea to spend some time on the metadata in the xref:extension-metadata#quarkus-extension-yaml[`quarkus-extension.yaml` file], which is used by Quarkus tooling.

Here are some pointers on how to achieve those capabilities.

== Run modes

Quarkus applications can be run as a normal jar-based JVM application,
or live-coded in dev mode, or compiled to a native binary.
Each environment places different demands on framework extensions.

=== Works in JVM mode

For most extensions, this is the minimum expectation.
When wrapping an existing library, this is usually trivial to achieve; if an extension is providing net-new capability, it might be a bit more work. Quarkus provides tools for xref:writing-extensions.adoc#testing-extensions[unit testing and integration testing] extensions.

=== Works in dev mode

In some cases, extra work may be needed to ensure any wrapped libraries can tolerate
dev mode, since the classloading is different and hot reloading can break some assumptions. Extensions may also wish to add some
xref:writing-extensions.adoc#integrating-with-development-mode[special handling for dev mode].
To add automated tests which validate dev mode, you can xref:writing-extensions.adoc#testing-hot-reload[add tests which extend the `QuarkusDevModeTest`].

=== Works as a native application

For many libraries, native mode support is the primary motivation for creating an extension. See xref:writing-extensions.adoc#native-executable-support[the guide on native executable support] for more discussion about some of the adaptations that might be needed.

== Developer Joy

Developer Joy is an important Quarkus principle.
Here are some extension capabilities that contribute to joyful development.

=== Configuration support

Extensions should support Quarkus's unified configuration, by xref:writing-extensions.adoc#configuration[integrating with the Quarkus configuration model].
The Writing Extensions guide has more guidance on xref:writing-extensions.adoc#how-to-expose-configuration[the Quarkus configuration philosophy].

=== CDI Beans

Quarkus extensions should aim to xref:writing-extensions.adoc#expose-your-components-via-cdi[expose components via CDI], so that they can be consumed in a frictionless way by user applications.
Having everything injectable as CDI beans also helps testing, especially xref:getting-started-testing#mock-support[mocking].

=== Dev Service (if there is an external service)

Dev Services are generally relevant for extensions that "connect" to something, such as databases for datasources, a keycloak instance for security, an Apache Kafka instance for messaging, etc.

To provide a Dev Service, use the `DevServicesResultBuildItem` build item. See the xref:extension-writing-dev-service.adoc[Dev Services how-to] for more information.

=== Basic Dev UI

Every extension gets a tile in the Dev UI. The default tile pulls information from the xref:extension-metadata.adoc[extension metadata], which is another reason to spend a bit of time getting the metadata right.

Extensions also use Dev UI hooks to present extra information to users. For example, the tile could include a link to an external console, or an internal page which presents simple text metrics. See the xref:dev-ui.adoc[Dev UI for extension developers] guide.


=== Rich Dev UI

Some extensions provide extremely sophisticated Dev UIs.
For example, they might allow users to interact with the running application, xref:dev-ui.adoc#hot-reload[respond to reloads], visualise application metrics, or xref:dev-ui.adoc#add-a-log-to-the-footer[stream an application-specific log].
The xref:dev-ui.adoc[Dev UI for extension developers] guide also explains these more advanced options.

=== Joyful programming model

Quarkus's build-time philosophy means extensions can tidy up API boilerplate and make programming models more concise and expressive.
A good starting point is usually to use
xref:writing-extensions.adoc#scanning-deployments-using-jandex[Jandex] to scan user code for annotations and other markers.
Although providing new, joyful, ways to do things is good,
it's important to not break the normal patterns that users may be familiar with.

For some inspiration in this area, have a look at xref:logging#simplified-logging[simplified logging], xref:hibernate-orm-panache.adoc[simplified Hibernate ORM with Panache], the xref:rest-client.adoc#query-parameters[`@RestQuery` annotation], or the way Quarkus allows test containers to be used xref:getting-started-dev-services.adoc[without any configuration].

=== Codestart application template

Codestarts are templates which can be used to generate applications for users.
Extensions can xref:extension-codestart.adoc[provide their own codestart templates].

== Supersonic subatomic performance

Extensions should use build-time application knowledge to eliminate wasteful runtime code paths. We call this supersonic subatomic performance.
Because Quarkus moves work to the build stage, Quarkus applications should have fast startup, high throughput, and low memory requirements. Performance tuning is a large subject, but extensions should use build-time application knowledge to eliminate wasteful runtime code paths at runtime.

=== Static initialization

Do as much initialization as much as possible statically.
This avoid runtime overhead.

=== Replace reflection with generated bytecode

Many Java libraries make heavy use of reflection to delay decisions to run-time. Quarkus aims to improve performance by moving logic to build time, reducing unnecessary dynamism.
Extensions should aim to replace reflection with build-time code.
This is enabled by
xref:writing-extensions.adoc#scanning-deployments-using-jandex[Jandex], an "offline reflection" library. It may also be necessary to do some bytecode transformation of existing libraries.

For a case study of how to eliminate reflection and what the performance benefits turned out to be, see https://quarkus.io/blog/quarkus-metaprogramming/[reflectionless Jackson serialization]

=== Virtual thread support

Not every library is suitable for using with virtual threads.
xref:virtual-threads#why-not["Why not virtual threads everywhere?"] explains why, and talks through some of the steps extension authors can do to implement and test support.

=== Hot path performance optimization

Although Quarkus offers some unique opportunities for extension performance, extension developers shouldn't forget the basics of performance optimization.

=== Non-blocking internals

Quarkus's reactive core is a key contributor to its excellent throughput and scalability. Extensions should consider adopting this model for their own internal operations.

=== Add Mutiny-based APIs

For maximum scalability, go beyond the reactive core and enable fully reactive programming, using Mutiny. Most projects that support a reactive programming model offer two distinct extensions, a `-reactive` and a plain one.
See, for example, https://quarkus.io/extensions/io.quarkiverse.quarkus-elasticsearch/quarkus-elasticsearch/[ElasticSearch] and https://quarkus.io/extensions/io.quarkiverse.quarkus-elasticsearch-reactive/quarkus-elasticsearch-reactive/[ElasticSearch Reactive] extensions.

=== Replace CDI Beans With Synthetic Ones

Quarkus allows extensions to create xref:cdi-integration#synthetic_beans[synthetic beans].
These reduce the number of CDI beans at runtime, which improves memory footprint.

== Operations

Developer joy is important, but so are observability, maintainability, and other operational considerations.
Many of these characteristics come by default with the Quarkus framework or https://quarkus.io/extensions/io.quarkus/quarkus-opentelemetry/[observability-focussed extensions]. But extensions can do more.

=== Logging

Quarkus uses JBoss Logging as its logging engine, and xref:logging[supports several logging APIs]. Avoid using errors and warnings for conditions that will not affect normal operation. These outputs can cause false alarms in user monitoring systems.

=== Define health endpoints

Extensions may wish to xref:writing-extensions#extension-defined-endpoints[define library-specific endpoints].

=== Kubernetes integration

Quarkus is designed to be a Kubernetes-native runtime.
Extensions can continue this philosphy by adding library-specific integration points with Kubernetes.


== References

- xref:writing-extensions.adoc[Writing your own extension] guide
- xref:building-my-first-extension.adoc[Building your first extension]
- link:https://hub.quarkiverse.io.adoc[The Quarkiverse Hub documentation]
2 changes: 1 addition & 1 deletion docs/src/main/asciidoc/extension-metadata.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ include::_attributes.adoc[]
Quarkus extensions are distributed as Maven JAR artifacts that application and other libraries may depend on. When a Quarkus application project is built, tested or edited using the Quarkus dev tools, Quarkus extension JAR artifacts will be identified on the application classpath by the presence of the Quarkus extension metadata files in them.
This document describes the purpose of each Quarkus extension metadata file and its content.

IMPORTANT: Two of the metadata files have the same name but different extensions, `quarkus-extension.yaml` and `quarkus-extension.properties`. It is easy to mix them up, be careful. You will usually edit the YAML file and track it in your SCM. While you _can_ manually manage the properties file, Quarkus will generated it at build if you don't.
IMPORTANT: Two of the metadata files have the same name but different extensions, `quarkus-extension.yaml` and `quarkus-extension.properties`. It is easy to mix them up, be careful. You will usually edit the YAML file and track it in your SCM. While you _can_ manually manage the properties file, Quarkus will generate it at build if you don't.

[[quarkus-extension-yaml]]
== META-INF/quarkus-extension.yaml
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions docs/src/main/asciidoc/writing-extensions.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,10 @@ Too flexible to benefit from the build time boot promoted by Quarkus.
Most extension we have seen do not make use of these extreme flexibility capabilities.
The way to port a CDI extension to Quarkus is to rewrite it as a Quarkus extension which will define the various beans at build time (deployment time in extension parlance).

=== Levels of capability

Quarkus extensions can do lots of things. The xref:extension-maturity-matrix.adoc[extension maturity matrix] lays out a path through the various capabilities, with a suggested implementation order.

== Technical aspect

[[bootstrap-three-phases]]
Expand Down
Loading