New quarkiverse extension - quarkus-qute-server-pages

37 views
Skip to first unread message

Martin Kouba

unread,
Mar 21, 2023, 10:52:35 AM3/21/23
to Quarkus Development mailing list
Hello everyone,

we've just released the 1.0.0.Beta1 of the quarkus-qute-server-pages
quarkiverse extension [1].

The goal of this simple extension is to automatically expose Qute [2]
templates located in the src/main/resource/templates directory via HTTP.
Automatically, no controllers needed. For example, the template
src/main/resource/templates/foo.html will be served from the paths
/qsp/foo and /qsp/foo.html by default.

In a template you can access the @Named CDI beans, static members of a
class annotated with @TemplateData, enums annotated with @TemplateEnum,
Namespace Extension Methods in general, global variables and the
current io.vertx.core.http.HttpServerRequest via CDI.

You can read the full docs here:
https://quarkiverse.github.io/quarkiverse-docs/quarkus-quteserverpages/dev/index.html

I've also prepared two elementary examples [3]. The first one shows the
content of a database table using the PanacheRepository pattern. The
other one is using the reactive rest client to fetch the data from the
https://stage.code.quarkus.io/api.

Feedback and comments are welcome!

Best regards,
Martin

[1]
https://github.com/quarkiverse/quarkus-qute-server-pages

[2]
https://quarkus.io/guides/qute-reference

[3]
https://github.com/mkouba/qsp-examples

Luca Masini

unread,
Mar 21, 2023, 10:53:54 AM3/21/23
to mko...@redhat.com, Quarkus Development mailing list
Great work Martin, really interesting for my use cases

--
You received this message because you are subscribed to the Google Groups "Quarkus Development mailing list" group.
To unsubscribe from this group and stop receiving emails from it, send an email to quarkus-dev...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/quarkus-dev/08c037ed-8490-56b4-a33d-641d94ccb4cd%40redhat.com.


--
****************************************
http://www.lucamasini.net
http://twitter.com/lmasini
http://www.linkedin.com/pub/luca-masini/7/10/2b9
****************************************

Stephane Epardaud

unread,
Mar 22, 2023, 11:20:26 AM3/22/23
to luca....@gmail.com, mko...@redhat.com, Quarkus Development mailing list
This is very cute :)

I wonder exactly what use-case it fills.
It certainly makes it much easier for templates that take zero parameters from their controllers. I've a number of those in my Renarde apps. I wonder if there's a way we can combine them.

Otherwise, it bypasses JAX-RS to let the template get its own data and parameters. That's a way of writing apps I'm not familiar with, so I'm not sure what to think of it :)




--
Stéphane Épardaud

Martin Kouba

unread,
Mar 23, 2023, 10:05:56 AM3/23/23
to Stephane Epardaud, luca....@gmail.com, Quarkus Development mailing list
On 22. 03. 23 16:20, Stephane Epardaud wrote:
> This is very cute :)
>
> I wonder exactly what use-case it fills.
> It certainly makes it much easier for templates that take zero
> parameters from their controllers.
> I've a number of those in my Renarde
> apps. I wonder if there's a way we can combine them.

You could combine them. But at the moment you would need to "hide" the
templates that should not be served by this extension with a regex:
https://quarkiverse.github.io/quarkiverse-docs/quarkus-quteserverpages/dev/index.html#quarkus-qsp_quarkus.qsp.hidden-templates

>
> Otherwise, it bypasses JAX-RS to let the template get its own data and
> parameters.

Yes, that the whole point. Sometimes the controllers are just an
unnecessary ceremony.

> That's a way of writing apps I'm not familiar with, so I'm
> not sure what to think of it :)

I was expecting this kind of statement from you ;-)

It's very similar to Facelets/JSP... which is probaly not a good
reference these days but sometimes it could be useful to build a very
simple UI.

>
>
> On Tue, 21 Mar 2023 at 15:53, Luca Masini <luca....@gmail.com
> <mailto:luca....@gmail.com>> wrote:
>
> Great work Martin, really interesting for my use cases
>
> Il giorno mar 21 mar 2023 alle ore 15:52 Martin Kouba
> <mko...@redhat.com <mailto:mko...@redhat.com>> ha scritto:
>
> Hello everyone,
>
> we've just released the 1.0.0.Beta1 of the
> quarkus-qute-server-pages
> quarkiverse extension [1].
>
> The goal of this simple extension is to automatically expose
> Qute [2]
> templates located in the src/main/resource/templates directory
> via HTTP.
> Automatically, no controllers needed. For example, the template
> src/main/resource/templates/foo.html will be served from the paths
> /qsp/foo and /qsp/foo.html by default.
>
> In a template you can access the @Named CDI beans, static
> members of a
> class annotated with @TemplateData, enums annotated with
> @TemplateEnum,
>     Namespace Extension Methods in general, global variables
> and the
> current io.vertx.core.http.HttpServerRequest via CDI.
>
> You can read the full docs here:
> https://quarkiverse.github.io/quarkiverse-docs/quarkus-quteserverpages/dev/index.html <https://quarkiverse.github.io/quarkiverse-docs/quarkus-quteserverpages/dev/index.html>
>
> I've also prepared two elementary examples [3]. The first one
> shows the
> content of a database table using the PanacheRepository pattern.
> The
> other one is using the reactive rest client to fetch the data
> from the
> https://stage.code.quarkus.io/api
> <https://stage.code.quarkus.io/api>.
>
> Feedback and comments are welcome!
>
> Best regards,
> Martin
>
> [1]
> https://github.com/quarkiverse/quarkus-qute-server-pages
> <https://github.com/quarkiverse/quarkus-qute-server-pages>
>
> [2]
> https://quarkus.io/guides/qute-reference
> <https://quarkus.io/guides/qute-reference>
>
> [3]
> https://github.com/mkouba/qsp-examples
> <https://github.com/mkouba/qsp-examples>
>
> --
> You received this message because you are subscribed to the
> Google Groups "Quarkus Development mailing list" group.
> To unsubscribe from this group and stop receiving emails from
> it, send an email to quarkus-dev...@googlegroups.com
> <mailto:quarkus-dev%2Bunsu...@googlegroups.com>.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/quarkus-dev/08c037ed-8490-56b4-a33d-641d94ccb4cd%40redhat.com <https://groups.google.com/d/msgid/quarkus-dev/08c037ed-8490-56b4-a33d-641d94ccb4cd%40redhat.com>.
>
>
>
> --
> ****************************************
> http://www.lucamasini.net <http://www.lucamasini.net>
> http://twitter.com/lmasini <http://twitter.com/lmasini>
> http://www.linkedin.com/pub/luca-masini/7/10/2b9
> <http://www.linkedin.com/pub/luca-masini/7/10/2b9>
> ****************************************
>
> --
> You received this message because you are subscribed to the Google
> Groups "Quarkus Development mailing list" group.
> To unsubscribe from this group and stop receiving emails from it,
> send an email to quarkus-dev...@googlegroups.com
> <mailto:quarkus-dev...@googlegroups.com>.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/quarkus-dev/CAG%3D-wFMOknpfHRh8gBBHAOx8p5ahk044dedhEuvPkJXNuPWj1g%40mail.gmail.com <https://groups.google.com/d/msgid/quarkus-dev/CAG%3D-wFMOknpfHRh8gBBHAOx8p5ahk044dedhEuvPkJXNuPWj1g%40mail.gmail.com?utm_medium=email&utm_source=footer>.
>
>
>
> --
> Stéphane Épardaud

--
Martin Kouba
Principal Software Engineer
Red Hat, Czech Republic

Stephane Epardaud

unread,
Mar 24, 2023, 5:26:34 AM3/24/23
to Martin Kouba, luca....@gmail.com, Quarkus Development mailing list
On Thu, 23 Mar 2023 at 15:05, Martin Kouba <mko...@redhat.com> wrote:
On 22. 03. 23 16:20, Stephane Epardaud wrote:
> This is very cute :)
>
> I wonder exactly what use-case it fills.
> It certainly makes it much easier for templates that take zero
> parameters from their controllers.
> I've a number of those in my Renarde
> apps. I wonder if there's a way we can combine them.

You could combine them. But at the moment you would need to "hide" the
templates that should not be served by this extension with a regex:
https://quarkiverse.github.io/quarkiverse-docs/quarkus-quteserverpages/dev/index.html#quarkus-qsp_quarkus.qsp.hidden-templates

So, I've a number of endpoints like these:

public class Application extends Controller {
 public static class Templates {
  public static native TemplateInstance index();
  public static native TemplateInstance about();
 }

public TemplateInstance index(){
 return Templates.index();
}

public TemplateInstance about(){
 return Templates.about();
}

}

Not _that_ many, beause after a while, even the index or other text-only page tend to load stuff from the DB to fill it up. But many applications start this way, and in the end, we stlil have "static" pages.

I would gladly write the following when I'm declaring parameter-less templates that I want rendered using QSP, but still specify the path:

public class Application extends Controller {

public native TemplateInstance index();

public native TemplateInstance about();

}

I thought of requiring a @CheckedTemplate annotation on the method, but let's be honest: what else could a native method returning a TemplateInstance possibly mean, here?

Yes, that the whole point. Sometimes the controllers are just an
unnecessary ceremony.

Agreed.
 

> That's a way of writing apps I'm not familiar with, so I'm
> not sure what to think of it :)

I was expecting this kind of statement from you ;-)

Well, don't take this as criticism, I'm just saying it takes me off guard and I'm less qualified to judge it, that's all :)
 

It's very similar to Facelets/JSP... which is probaly not a good
reference these days but sometimes it could be useful to build a very
simple UI.

I could imagine some Qute tags for accessing the request without JAX-RS: query params, POST params, url, method, headers, cookies. Perhaps draw a line at deserialisation?
But for any page that requires DB access or worse: actions (like sending mail or writing to a DB), do you think this would be appropriate?
I'm wondering where is the line we draw between QSP and JAX-RS+Qute.
--
Stéphane Épardaud

Martin Kouba

unread,
Mar 24, 2023, 6:36:20 AM3/24/23
to Stephane Epardaud, luca....@gmail.com, Quarkus Development mailing list

On 24. 03. 23 10:26, Stephane Epardaud wrote:
>
>
> On Thu, 23 Mar 2023 at 15:05, Martin Kouba <mko...@redhat.com
> <mailto:mko...@redhat.com>> wrote:
>
> On 22. 03. 23 16:20, Stephane Epardaud wrote:
> > This is very cute :)
> >
> > I wonder exactly what use-case it fills.
> > It certainly makes it much easier for templates that take zero
> > parameters from their controllers.
> > I've a number of those in my Renarde
> > apps. I wonder if there's a way we can combine them.
>
> You could combine them. But at the moment you would need to "hide" the
> templates that should not be served by this extension with a regex:
> https://quarkiverse.github.io/quarkiverse-docs/quarkus-quteserverpages/dev/index.html#quarkus-qsp_quarkus.qsp.hidden-templates <https://quarkiverse.github.io/quarkiverse-docs/quarkus-quteserverpages/dev/index.html#quarkus-qsp_quarkus.qsp.hidden-templates>
You don't need a tag for this. You can do just
{cdi:vertxRequest.getParam('foo')} or {cdi:vertxRequest.path}.

> Perhaps draw a
> line at deserialisation?
> But for any page that requires DB access or worse: actions (like sending
> mail or writing to a DB), do you think this would be appropriate?

So the idea was to use the QSP for the "view", i.e. to serve the content
for GET requests, not for handling POST requests. For these interactions
you'd need to use a custom route or JAX-RS resource.

As for the DB access - the aforementioned qsp-panache-example [1] shows
how easy it is to use a panache repository directly in your template.

[1]
https://github.com/mkouba/qsp-examples/tree/main/qsp-panache-example

> I'm wondering where is the line we draw between QSP and JAX-RS+Qute.

I don't think we need a line but in general, QSP is a good fit if you
need to visualize some data. Not so much to build a "complex" webapp,
where "complex" means a lot of user interactions with complex
validation, etc.

And it could be also combined with technologies such as HTMX [2] to add
AJAX, WebSockets/SSE functionality.

[2]
https://htmx.org/

> --
> Stéphane Épardaud

Stephane Epardaud

unread,
Mar 24, 2023, 9:38:32 AM3/24/23
to Quarkus Development mailing list
On Fri, 24 Mar 2023 at 11:36, Martin Kouba <mko...@redhat.com> wrote:

> I could imagine some Qute tags for accessing the request without JAX-RS:
> query params, POST params, url, method, headers, cookies.

You don't need a tag for this. You can do just
{cdi:vertxRequest.getParam('foo')} or {cdi:vertxRequest.path}.

Sure, but we could make this easier, with {qsp:param.foo} {qsp:path}
 
So the idea was to use the QSP for the "view", i.e. to serve the content
for GET requests, not for handling POST requests. For these interactions
you'd need to use a custom route or JAX-RS resource.

It starts like this… ;)
 
As for the DB access - the aforementioned qsp-panache-example [1] shows
how easy it is to use a panache repository directly in your template.

Yeah, but I found this a bit artificial, because in this case, the repo appears to serve the same purpose as the endpoint would if it were using a Panache entity without a repo. It's one repo bean vs one jax-rs bean.
--
Stéphane Épardaud


--
Stéphane Épardaud

Martin Kouba

unread,
Mar 24, 2023, 10:55:36 AM3/24/23
to stephane...@gmail.com, Quarkus Development mailing list
On 24. 03. 23 14:38, Stephane Epardaud wrote:
>
>
>
> On Fri, 24 Mar 2023 at 11:36, Martin Kouba <mko...@redhat.com
> <mailto:mko...@redhat.com>> wrote:
>
>
> > I could imagine some Qute tags for accessing the request without
> JAX-RS:
> > query params, POST params, url, method, headers, cookies.
>
> You don't need a tag for this. You can do just
> {cdi:vertxRequest.getParam('foo')} or {cdi:vertxRequest.path}.
>
>
> Sure, but we could make this easier, with {qsp:param.foo} {qsp:path}

Nice idea ;-)

>
> So the idea was to use the QSP for the "view", i.e. to serve the
> content
> for GET requests, not for handling POST requests. For these
> interactions
> you'd need to use a custom route or JAX-RS resource.
>
>
> It starts like this… ;)

Yeah, I know... :D

>
> As for the DB access - the aforementioned qsp-panache-example [1] shows
> how easy it is to use a panache repository directly in your template.
>
>
> Yeah, but I found this a bit artificial, because in this case, the repo
> appears to serve the same purpose as the endpoint would if it were using
> a Panache entity without a repo. It's one repo bean vs one jax-rs bean.

Well, I don't know if Panache repos are artificial but in general I
think that it's very common to define a reusable "service" bean that
calls the database and applies some business logic.

Anyway, it's probably a matter of opinion. You can either add a bean
(that can be used anywhere) or a jax-rs resource (that can only be used
to build REST endpoints)...

> --
> Stéphane Épardaud
>
>
> --
> Stéphane Épardaud
>
> --
> You received this message because you are subscribed to the Google
> Groups "Quarkus Development mailing list" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to quarkus-dev...@googlegroups.com
> <mailto:quarkus-dev...@googlegroups.com>.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/quarkus-dev/CAKU9E9tc5G1TuwjaqpioU7cdaZ4J8ewCufyDwFK2YXJ-ZUAomw%40mail.gmail.com <https://groups.google.com/d/msgid/quarkus-dev/CAKU9E9tc5G1TuwjaqpioU7cdaZ4J8ewCufyDwFK2YXJ-ZUAomw%40mail.gmail.com?utm_medium=email&utm_source=footer>.

Martin Kouba

unread,
Mar 24, 2023, 10:56:23 AM3/24/23
to stephane...@gmail.com, Quarkus Development mailing list
On 24. 03. 23 14:38, Stephane Epardaud wrote:
>
>
>
> On Fri, 24 Mar 2023 at 11:36, Martin Kouba <mko...@redhat.com
> <mailto:mko...@redhat.com>> wrote:
>
>
> > I could imagine some Qute tags for accessing the request without
> JAX-RS:
> > query params, POST params, url, method, headers, cookies.
>
> You don't need a tag for this. You can do just
> {cdi:vertxRequest.getParam('foo')} or {cdi:vertxRequest.path}.
>
>
> Sure, but we could make this easier, with {qsp:param.foo} {qsp:path}

Nice idea ;-)

>
> So the idea was to use the QSP for the "view", i.e. to serve the
> content
> for GET requests, not for handling POST requests. For these
> interactions
> you'd need to use a custom route or JAX-RS resource.
>
>
> It starts like this… ;)

Yeah, I know... :D

>
> As for the DB access - the aforementioned qsp-panache-example [1] shows
> how easy it is to use a panache repository directly in your template.
>
>
> Yeah, but I found this a bit artificial, because in this case, the repo
> appears to serve the same purpose as the endpoint would if it were using
> a Panache entity without a repo. It's one repo bean vs one jax-rs bean.

Well, I don't know if Panache repos are artificial but in general I
think that it's very common to define a reusable "service" bean that
calls the database and applies some business logic.

Anyway, it's probably a matter of opinion. You can either add a bean
(that can be used anywhere) or a jax-rs resource (that can only be used
to build REST endpoints)...

> --
> Stéphane Épardaud
>
>
> --
> Stéphane Épardaud
>
> --
> You received this message because you are subscribed to the Google
> Groups "Quarkus Development mailing list" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to quarkus-dev...@googlegroups.com
> <mailto:quarkus-dev...@googlegroups.com>.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/quarkus-dev/CAKU9E9tc5G1TuwjaqpioU7cdaZ4J8ewCufyDwFK2YXJ-ZUAomw%40mail.gmail.com <https://groups.google.com/d/msgid/quarkus-dev/CAKU9E9tc5G1TuwjaqpioU7cdaZ4J8ewCufyDwFK2YXJ-ZUAomw%40mail.gmail.com?utm_medium=email&utm_source=footer>.

Reply all
Reply to author
Forward
0 new messages