The argument seems to take the leap from 'Ring is the wrong abstraction for what I want to do' (fair enough) and concludes 'Ring is inadequate, and therefore Clojure has a viability problem.'
Ring is explicitly designed to be web-server agnostic and therefore intentionally does not expose the full Jetty/Jakarta surface. Many using ring aren't using Jetty!
If your app requirements are specifically EE/Jetty-centric, then bypassing Ring may be entirely reasonable, but I don't see how that becomes an argument against Ring's design, much less against Clojure’s viability for enterprise applications...when enterprise means "serious business" not "Jakarta EE".
There are a few actual issues with Ring's design (that are in the issue tracker) I can think of when it comes to it's ability to express valid HTTP semantics. But "it doesn't OIDC" isn't one of them (that's sort of a category error?)
All that said... The charitable reading of "Clojure has a larger problem for its future [...] in which we can produce enterprise-grade web applications" is one where the "we" is limited to Derek's company/team, which yea, sounds like they need more Jetty/Java EE than Ring provides. But if the "we" is the Clojure community as a whole, then I would dissent.
I wonder how much of this is actually tied to the very partial clojure support for java annotations. Most other popular JVM languages have a much better integration story for annotations but they also embrace the OO approach.
Can, and most importantly should, clojure better support java annotations? Is it possible without harming its philosophy? Aren't we looking through the ring at the larger issue of clojure departure from the OO mindset which remains a strong assumption from all java (enterprise) API?
Clojure has some limited support for Java annotations, it's just that support is a bit ungainly, and that introduces enough difficulty that it leads to frameworks like Quarkus having no real adoption in the Clojure community.
Quarkus also relies on byte-code rewriting which may also cause difficulty for Clojure, but that's an aside.
Better annotations support wouldn't necessarily improve the ease of annotation-driven web frameworks in Clojure because the issue is more fundamental than that.
The real problem for Clojure is, from the original article:
It's because in Jakarte EE 11 Context and Dependency Injection (CDI) officially becomes the single, unified component model across the entire enterprise Java ecosystem ... CDI is entirely driven by annotations, and annontations are entirely not Clojurish.
What I mean here specifically is CDI is the 'blessed' solution for DI in Java, CDI is clearly derived from many years of innovation by Spring, other DI frameworks in Java. Annotations is the path forward.
That means DI in Java is driven at a code-oriented, not data-oriented. Code-oriented is more natural in Java, and to give you a counterpoint, when I first worked with Spring (and very briefly with Rod Johnson for a couple of weeks on a client engagement, boring story) it was possible to configure Spring in XML.
Spring XML would be the equivalent of data-oriented in Java. Nobody in Java wants to do that, they want annotations instead.
In the article I say:
configuring systems in code is a pale imitation of configuring systems in data. I much prefer my data-oriented system config library in Clojure to annotations in Java.
As it turns out I wrote something on reddit about this recently, you can find that here:
Sorry for quoting myself and links back to reddit, feels a bit odd.
The point is - when you start configuring things in code, you are leaning into Java objects and/or code-level constructs for dependency injection, rather than the frankly far better approach in Clojure of using the wonderful Integrant library which relies on Clojure datastructures:
And then of-course Slipway, which is also entirely Clojure maps.
If you are using annotations to configure your web server, you are better to write your webserver code in Java and have the server handlers call out to Clojure at the handler level. It inverts your entire codebase back into 'Java is in charge, clojure is an adjunct to that'.
I had first-hand experience with the way java developers avoid XML config. In my early days I wrote some javabean mapper framework but it wasn't liked by my peers becaused it was driven by XML. Back then EJB, Struts, and many web/enterprise frameworks used XML for config, so it was a no brainer to continue the trend. However the DX of XML in Java wasn't that great I have to admit. This is what made Spring so successful with its annotation-driven approach to config: you can annotate directly in the code, no need to manually create or edit XML files.
Clojure does not have this issue at all: XML easily translate into clojure data structures, and vice-versa, and from there you no longer feel any pain. I find it ironic that for a language in which data is code and code is data, you need to revert to java to integrate with annotations which is metadata added to code.
I guess the fundamental question is: do we want clojure to develop a parallel story for enterprise development, or do we want to improve clojure for better integration with enterprise frameworks. Back to slipway: what do you think can be done on the clojure side to make the slipway integration story easier to reproduce for other enterprise frameworks? I doubt the JDK will change for us so best is for us to adapt as much as possible (despite such conclusion [0]).
do we want clojure to develop a parallel story for enterprise development
I don't think this is feasible, partly because these enterprise frameworks tend to be abstract systems, and I haven't seen any evidence in the Clojure world of anyone building anything similar to Quarkus for instance.
It's too big a job, we have too few people doing this work in Clojure with the relevant experience to maintain something serious.
Much of my thought is put into how do I achieve the standard necessary for my company, and that's where Slipway comes from. But I have to consider how I will also support enterprise grade SAML for instance, and how those lands are shifting, and a number of other similar needs.
These are the things that are normally captured by the framework, and those JVM frameworks are moving in a non-Clojurish way.
what do you think can be done on the clojure side to make the slipway integration story easier to reproduce for other enterprise frameworks?
Unfortunately I don't have an answer to this, and I'm not sure there is one. Slipway can work with Jetty because Jetty is POJO, and that is becoming more rare in this space.
Which would put us back at your first question, 'do we want clojure to develop a parallel story for enterprise development'.
Comments
(as discussed in clojurian slack):
The argument seems to take the leap from 'Ring is the wrong abstraction for what I want to do' (fair enough) and concludes 'Ring is inadequate, and therefore Clojure has a viability problem.'
Ring is explicitly designed to be web-server agnostic and therefore intentionally does not expose the full Jetty/Jakarta surface. Many using ring aren't using Jetty!
If your app requirements are specifically EE/Jetty-centric, then bypassing Ring may be entirely reasonable, but I don't see how that becomes an argument against Ring's design, much less against Clojure’s viability for enterprise applications...when enterprise means "serious business" not "Jakarta EE".
There are a few actual issues with Ring's design (that are in the issue tracker) I can think of when it comes to it's ability to express valid HTTP semantics. But "it doesn't OIDC" isn't one of them (that's sort of a category error?)
All that said... The charitable reading of "Clojure has a larger problem for its future [...] in which we can produce enterprise-grade web applications" is one where the "we" is limited to Derek's company/team, which yea, sounds like they need more Jetty/Java EE than Ring provides. But if the "we" is the Clojure community as a whole, then I would dissent.
I wonder how much of this is actually tied to the very partial clojure support for java annotations. Most other popular JVM languages have a much better integration story for annotations but they also embrace the OO approach.
Can, and most importantly should, clojure better support java annotations? Is it possible without harming its philosophy? Aren't we looking through the ring at the larger issue of clojure departure from the OO mindset which remains a strong assumption from all java (enterprise) API?
Hello, I'm the author.
Clojure has some limited support for Java annotations, it's just that support is a bit ungainly, and that introduces enough difficulty that it leads to frameworks like Quarkus having no real adoption in the Clojure community.
Quarkus also relies on byte-code rewriting which may also cause difficulty for Clojure, but that's an aside.
Better annotations support wouldn't necessarily improve the ease of annotation-driven web frameworks in Clojure because the issue is more fundamental than that.
The real problem for Clojure is, from the original article:
What I mean here specifically is CDI is the 'blessed' solution for DI in Java, CDI is clearly derived from many years of innovation by Spring, other DI frameworks in Java. Annotations is the path forward.
That means DI in Java is driven at a code-oriented, not data-oriented. Code-oriented is more natural in Java, and to give you a counterpoint, when I first worked with Spring (and very briefly with Rod Johnson for a couple of weeks on a client engagement, boring story) it was possible to configure Spring in XML.
Spring XML would be the equivalent of data-oriented in Java. Nobody in Java wants to do that, they want annotations instead.
In the article I say:
As it turns out I wrote something on reddit about this recently, you can find that here:
https://www.reddit.com/r/Clojure/comments/1vm668q/comment/p3...
Sorry for quoting myself and links back to reddit, feels a bit odd.
The point is - when you start configuring things in code, you are leaning into Java objects and/or code-level constructs for dependency injection, rather than the frankly far better approach in Clojure of using the wonderful Integrant library which relies on Clojure datastructures:
https://github.com/weavejester/integrant
And then of-course Slipway, which is also entirely Clojure maps.
If you are using annotations to configure your web server, you are better to write your webserver code in Java and have the server handlers call out to Clojure at the handler level. It inverts your entire codebase back into 'Java is in charge, clojure is an adjunct to that'.
I had first-hand experience with the way java developers avoid XML config. In my early days I wrote some javabean mapper framework but it wasn't liked by my peers becaused it was driven by XML. Back then EJB, Struts, and many web/enterprise frameworks used XML for config, so it was a no brainer to continue the trend. However the DX of XML in Java wasn't that great I have to admit. This is what made Spring so successful with its annotation-driven approach to config: you can annotate directly in the code, no need to manually create or edit XML files.
Clojure does not have this issue at all: XML easily translate into clojure data structures, and vice-versa, and from there you no longer feel any pain. I find it ironic that for a language in which data is code and code is data, you need to revert to java to integrate with annotations which is metadata added to code.
I guess the fundamental question is: do we want clojure to develop a parallel story for enterprise development, or do we want to improve clojure for better integration with enterprise frameworks. Back to slipway: what do you think can be done on the clojure side to make the slipway integration story easier to reproduce for other enterprise frameworks? I doubt the JDK will change for us so best is for us to adapt as much as possible (despite such conclusion [0]).
[0] https://blog.jakubholy.net/translating-enterprise-spring-app...
I don't think this is feasible, partly because these enterprise frameworks tend to be abstract systems, and I haven't seen any evidence in the Clojure world of anyone building anything similar to Quarkus for instance.
It's too big a job, we have too few people doing this work in Clojure with the relevant experience to maintain something serious.
Much of my thought is put into how do I achieve the standard necessary for my company, and that's where Slipway comes from. But I have to consider how I will also support enterprise grade SAML for instance, and how those lands are shifting, and a number of other similar needs.
These are the things that are normally captured by the framework, and those JVM frameworks are moving in a non-Clojurish way.
Unfortunately I don't have an answer to this, and I'm not sure there is one. Slipway can work with Jetty because Jetty is POJO, and that is becoming more rare in this space.
Which would put us back at your first question, 'do we want clojure to develop a parallel story for enterprise development'.