pedestal

hlship 2025-04-19T18:41:31.334999Z

So I’ve been thinking about routes again.

hlship 2025-04-19T18:41:34.483629Z

https://github.com/pedestal/pedestal/issues/711

2025-04-20T10:58:51.676039Z

When resources are an overlay, as in the example /*path, that's a problem for which Pedestal already has an elegant solution ("everything is an interceptor") and the alternative seems to be making routing complex and perhaps incomplete. For example, someone will want to use resources from two different places in the classpath, and they will set up two instances of /*path, which might initially work (?) but then they might start to care about which one took precedence... better to leverage Pedestal's architectural solution from the start, and use distinct interceptors, and therefore offering overlays in the routing table could be an investment that will lead to higher maintenance disproportionate to its utility.

2025-04-20T11:11:07.636399Z

It seems analogous to the problem of what if you wanted to use multiple overlapping routing tables. The answer would be distinct interceptors. All questions of relative priority of one URL interpretation over another are the domain of interceptors.

2025-04-20T11:14:58.361729Z

I guess the key is that half-measures are difficult to evaluate. And this seems to be half-measures to enable one routing table to behave more like two routing tables.

hlship 2025-04-20T16:18:03.467249Z

Two routing tables is not particular feasible if you want to keep route/url-for working. I’d like to be able to feed asset paths into url-for, just like I can dynamic resources.

hlship 2025-04-20T16:19:57.030809Z

If you look at how Sawtooth works, it keeps “subdividing” the routing space; first by the major parts of the request map (port, scheme, host, method/verb) then by peeling terms of the URI.

hlship 2025-04-20T16:21:54.364099Z

It can detect that two non-wild-path routes conflict when their terms all match (as wildcards match wildcards or any literal term). wild-path routes are harder to deal with and are already a special case.

hlship 2025-04-20T16:24:23.681169Z

So we’d be tweaking the definition of wild-card-path from “matches at least one term” to “matches at least one term that doesn’t match another route”.

hlship 2025-04-20T16:27:44.154169Z

What’s frustrating to people in 0.7 is that wild-card routes (single element or paths) always win when using prefix-tree. I see a constant stream of Nubankers complaining that their tests fail when they add a new route that silently conflicts with an existing one, and have to bend their URIs out of shape to accommodate.

hlship 2025-04-20T16:28:27.317169Z

I’m not 100% sure that partially inverting that behavior (wild-card paths always lose) is the final solution however.

hlship 2025-04-20T16:29:29.934979Z

But I would like a solution that has a single routing table and the current solution, using interceptors for resources, is effectively two routing tables.

hlship 2025-04-20T16:32:31.429619Z

The alternative is to rethink having resources be exposed as routes at all, and maybe move some of the optimizations I created for routed resources into the existing routing interceptors.

hlship 2025-04-20T16:32:54.171309Z

Which is why it’s still alpha.

2025-04-19T19:27:03.981079Z

If /*x is lower-priority than anything without an asterisk, then it might as well also be lower-priority than /y/*x . That is, the position of * in the route pattern is the unimportance level of the route. If there are to be 2 priority levels (no-star and star), there might as well be N levels. I'm not sure I understand what the problem is though. If the right place to mount the resources is /, then routing has nothing to do with it. The routes take priority, and the resources are a catchall interceptor. Which means the resource interceptor's "enter" runs before routing (but does nothing) and its "leave" runs after routing's, and takes action only if the routes did not produce any response. And if resources' "leave" likewise yields no response then an outer catchall affixes a 404.

hlship 2025-04-20T05:01:48.824049Z

Yes, but in 0.8 you have the option of no resource interceptor, just resource routes in the routing table.

isak 2025-04-21T13:50:51.701349Z

> I’m not 100% sure that partially inverting that behavior (wild-card paths always lose) is the final solution however. I think that is how it works for every other web application library/framework that I've used. Even CSS works that way (albeit in a clunky way): the most specific options always win.

hlship 2025-04-19T18:46:02.312359Z

Because Sawtooth is new, it’s not too late to change its behavior. I’m thinking about changing it as outlined in the issue. Essentially, wild-card paths (those with a “/*path” in the URI) are not considered until non-wild-card paths are exhausted. This would mean that mapping resources at “/*path” would not conflict with routes such as “/version” or “/api/project/:id” … but would still conflict with “/foo/*bar”. I think this would make mapping resources as routes (new in 0.8.0) rather than as interceptors prior to routing, more useful. As currently stands, you would need to, say, map resources as “/public/*path” to avoid route conflicts.

➕ 1
hlship 2025-04-19T18:52:30.501599Z

And that’s not ideal for a root index page, which you’d end up having to map as its own route. I’d prefer a solution where a single route covers incoming URLs “/”, “/index.html”, “/css/style.css”, etc., by mapping “/*path”.

jlfischer 2025-04-19T00:01:31.051309Z

If I need to stick with Java 8 for Reasons, I need Pedestal 0.5.10, right?

hlship 2025-04-19T00:26:48.262289Z

Clojure is still compatible with Java 8 AFAIK, but the Servlet API that underpins Jetty … I’d check those dependencies.

jlfischer 2025-04-19T00:31:44.238459Z

Yeah, I figured moving past Jetty 9 was the problem part.