ataraxy icon indicating copy to clipboard operation
ataraxy copied to clipboard

Unification process in the route maps

Open green-coder opened this issue 7 years ago • 6 comments

It would be nice to have the meaning of string extended when they are used inside of route maps, so that they behave as constraints. It could allow an improved expressiveness.

For example, we could declare routes based on certain content-types:

;; From documentation at https://lacinia-pedestal.readthedocs.io/en/latest/request.html#post-application-json
;; This actually returns false, unfortunately.
(ataraxy/valid?
 '{"/graphql"
   {[:get #{query}] [:graphql-get query]
    [:post
     {{"application/json" "Content-Type"} :headers}
     {{:keys [query variables operationName]} :body}]
    [:graphql-post query variables operationName]}})

green-coder avatar Sep 14 '18 17:09 green-coder

My initial impression is that I the idea, but the syntax doesn't sit well with me, as the maps end up effectively being defined backward.

I'm also wondering about the use-cases. Dispatching on the content type is one example, but I'd rather have that be a more automated process, since the response for JSON and edn (for example) will be functionally the same, and differ only in format.

What other use-cases can you think of that would benefit from something like this?

weavejester avatar Sep 14 '18 17:09 weavejester

I was also not satisfied with syntax as it is very verbose, specially knowing that (if use as dispatch) it would be likely to be repeated in multiple places with different values to match with.

I am proposing an alternative syntax, which can be used in a more general way and might cover more use cases:

Currently, "", {} and [] have a special meaning in the routing structure, but () has not. I propose to use it to extend and generalize the representation of predicates, and to allow them to be user defined.

Example:

(ataraxy/valid?
 '{"/graphql"
   {[:get #{query}] [:graphql-get query]
    [:post
     (:content-type? "application/json")
     {{:keys [query variables operationName]} :body}]
    [:graphql-post query variables operationName]}})

Other example, where a variable is bound to the expression that matches the predicate:

(ataraxy/valid?
 '{[:get "/user" [id (:id?)]] [:user-by-id id]
   [:get "/user" [name (:name?)]] [:user-by-name]})

When the predicate is not using an explicit argument, we could accept it without parenthesis.

(ataraxy/valid?
 '{[:get "/user" [id :id?]] [:user-by-id id]
   [:get "/user" [name :name?]] [:user-by-name]})

That's just some ideas, they need further discussions.

green-coder avatar Sep 15 '18 03:09 green-coder

Metadata as alternative syntax proposal

Similarly to the syntax {^{:re #"/d.g"} w [:word w]}, we could have the matchers described as:

(ataraxy/valid?
 '{"/graphql"
   {[:get #{query}] [:graphql-get query]
    [:post
     ^{:content-type "application/json"} _
     {{:keys [query variables operationName]} :body}]
    [:graphql-post query variables operationName]}})

(ataraxy/valid?
 '{[:get "/user" ^:id id] [:user-by-id id]
   [:get "/user" ^:name name] [:user-by-name]})

green-coder avatar Sep 15 '18 06:09 green-coder

Thank you for the extra syntax ideas, however I feel like we're putting the cart before the horse right now. Could you give me some examples of why this sort of syntax would be useful?

weavejester avatar Sep 15 '18 12:09 weavejester

Not so many use cases, indeed.

green-coder avatar Sep 15 '18 13:09 green-coder

In which case, let's keep this issue around and revisit it in future. Perhaps then we'll have more use-cases that would justify a feature like this, or a syntax idea that ties into some other functionality more neatly.

weavejester avatar Sep 15 '18 14:09 weavejester