Skip to content

Commit

Permalink
Add explanation/concept for extension maturity model
Browse files Browse the repository at this point in the history
  • Loading branch information
holly-cummins committed Aug 9, 2024
1 parent d41ab4c commit 9c13618
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 1 deletion.
95 changes: 95 additions & 0 deletions docs/src/main/asciidoc/extension-maturity-model.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@

[id="extension-maturity-model"]
= Extension maturity model
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 may wish to include.

Check warning on line 8 in docs/src/main/asciidoc/extension-maturity-model.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.TermsWarnings] Consider using 'might (for possiblity)' or 'can (for ability)' rather than 'may' unless updating existing content that uses the term. Raw Output: {"message": "[Quarkus.TermsWarnings] Consider using 'might (for possiblity)' or 'can (for ability)' rather than 'may' unless updating existing content that uses the term.", "location": {"path": "docs/src/main/asciidoc/extension-maturity-model.adoc", "range": {"start": {"line": 8, "column": 120}}}, "severity": "WARNING"}

Check warning on line 8 in docs/src/main/asciidoc/extension-maturity-model.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.TermsWarnings] Consider using 'want' rather than 'wish' unless updating existing content that uses the term. Raw Output: {"message": "[Quarkus.TermsWarnings] Consider using 'want' rather than 'wish' unless updating existing content that uses the term.", "location": {"path": "docs/src/main/asciidoc/extension-maturity-model.adoc", "range": {"start": {"line": 8, "column": 124}}}, "severity": "WARNING"}
////
The document header ends at the first blank line. Do not remove the blank line between the header and the abstract summary.
////

= A maturity model for Quarkus extensions

What makes a good Quarkus extension? What capabilities is a Quarkus extension expected to provide?

* It actually works
** Works in JVM mode
** Works in dev mode
** Works in native
* Dev service (if there is an external service dependency)
* Developer joy
** Configuration support
** Use build-time application knowledge to remove boilerplate
* Dev UI
* Supersonic subatomic performance
** Use build-time application knowledge to eliminate wasteful runtime code paths
* Codestart application template

Check warning on line 28 in docs/src/main/asciidoc/extension-maturity-model.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.Spelling] Use correct American English spelling. Did you really mean 'Codestart'? Raw Output: {"message": "[Quarkus.Spelling] Use correct American English spelling. Did you really mean 'Codestart'?", "location": {"path": "docs/src/main/asciidoc/extension-maturity-model.adoc", "range": {"start": {"line": 28, "column": 3}}}, "severity": "WARNING"}

The order in this model isn't exact. Different developers will have different views on what capabilities are most important. You may wish to (say) prioritise performance over enhancing your extension's Dev UI tile. That's fine!

Check warning on line 30 in docs/src/main/asciidoc/extension-maturity-model.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.TermsWarnings] Consider using 'might (for possiblity)' or 'can (for ability)' rather than 'may' unless updating existing content that uses the term. Raw Output: {"message": "[Quarkus.TermsWarnings] Consider using 'might (for possiblity)' or 'can (for ability)' rather than 'may' unless updating existing content that uses the term.", "location": {"path": "docs/src/main/asciidoc/extension-maturity-model.adoc", "range": {"start": {"line": 30, "column": 130}}}, "severity": "WARNING"}

Check warning on line 30 in docs/src/main/asciidoc/extension-maturity-model.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.TermsWarnings] Consider using 'want' rather than 'wish' unless updating existing content that uses the term. Raw Output: {"message": "[Quarkus.TermsWarnings] Consider using 'want' rather than 'wish' unless updating existing content that uses the term.", "location": {"path": "docs/src/main/asciidoc/extension-maturity-model.adoc", "range": {"start": {"line": 30, "column": 134}}}, "severity": "WARNING"}
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.

Also note that this list only includes the technical features of your extension.

Check warning on line 33 in docs/src/main/asciidoc/extension-maturity-model.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.Fluff] Depending on the context, consider using 'Be concise: rewrite the sentence to not use' rather than 'note that'. Raw Output: {"message": "[Quarkus.Fluff] Depending on the context, consider using 'Be concise: rewrite the sentence to not use' rather than 'note that'.", "location": {"path": "docs/src/main/asciidoc/extension-maturity-model.adoc", "range": {"start": {"line": 33, "column": 6}}}, "severity": "INFO"}
You might also want to think about how you share your extension.
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.

Here are some pointers on how to achieve those capabilities.

== It actually works

=== 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#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#integrating-with-development-mode[special handling for dev mode].
To add automated tests which validate dev mode, you can xref:writing-extensions#testing-hot-reload[add tests which extend the `QuarkusDevModeTest`].

=== Works as a native application

For many libraries, native mode support is the motivation for creating an extension. See xref:writing-extensions#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 part of the Quarkus philosophy.
Quarkus extensions should aim to xref:writing-extensions#expose-your-components-via-cdi[exponents components via CDI], so that they can be consimed in a frictionless way by user applications.

=== Configuration

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

=== Use build-time application knowledge to remove boilerplate

Many Quarkus extensions take advantage of being able to inspect the application at build-time to eliminate boilerplate and improve the developer experience.
xref:writing-extensions#scanning-deployments-using-jandex[Jandex] allows user code to be scanned for annotations and other markers.

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

== Dev service

To provide a dev service, use the `DevServicesResultBuildItem` build item.

== Dev UI

Extensions can take advantage of the Dev UI to present extra information to users. See the xref:dev-ui[Dev UI for extension developers] guide.

== 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.

== Codestart application template

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

== References

- xref:writing-extensions[Writing your own extension] guide
- xref:building-my-first-extension[Building your first extension]
- link:https://hub.quarkiverse.io[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.

Check warning on line 11 in docs/src/main/asciidoc/extension-metadata.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.TermsSuggestions] Depending on the context, consider using 'because' or 'while' rather than 'as'. Raw Output: {"message": "[Quarkus.TermsSuggestions] Depending on the context, consider using 'because' or 'while' rather than 'as'.", "location": {"path": "docs/src/main/asciidoc/extension-metadata.adoc", "range": {"start": {"line": 11, "column": 36}}}, "severity": "INFO"}

Check warning on line 11 in docs/src/main/asciidoc/extension-metadata.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.TermsWarnings] Consider using 'might (for possiblity)' or 'can (for ability)' rather than 'may' unless updating existing content that uses the term. Raw Output: {"message": "[Quarkus.TermsWarnings] Consider using 'might (for possiblity)' or 'can (for ability)' rather than 'may' unless updating existing content that uses the term.", "location": {"path": "docs/src/main/asciidoc/extension-metadata.adoc", "range": {"start": {"line": 11, "column": 96}}}, "severity": "WARNING"}

Check warning on line 11 in docs/src/main/asciidoc/extension-metadata.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.SentenceLength] Try to keep sentences to an average of 32 words or fewer. Raw Output: {"message": "[Quarkus.SentenceLength] Try to keep sentences to an average of 32 words or fewer.", "location": {"path": "docs/src/main/asciidoc/extension-metadata.adoc", "range": {"start": {"line": 11, "column": 111}}}, "severity": "INFO"}
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

Check warning on line 17 in docs/src/main/asciidoc/extension-metadata.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.Headings] Use sentence-style capitalization in 'META-INF/quarkus-extension.yaml'. Raw Output: {"message": "[Quarkus.Headings] Use sentence-style capitalization in 'META-INF/quarkus-extension.yaml'.", "location": {"path": "docs/src/main/asciidoc/extension-metadata.adoc", "range": {"start": {"line": 17, "column": 4}}}, "severity": "INFO"}
Expand Down
3 changes: 3 additions & 0 deletions docs/src/main/asciidoc/writing-extensions.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,9 @@ 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-model[extension maturity model] lays out a path through the various capabilities, with a suggested implementation order.

== Technical aspect

[[bootstrap-three-phases]]
Expand Down

0 comments on commit 9c13618

Please sign in to comment.