Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom :parameter-aliases #150

Open
onetom opened this issue Mar 2, 2022 · 2 comments
Open

Custom :parameter-aliases #150

onetom opened this issue Mar 2, 2022 · 2 comments

Comments

@onetom
Copy link

onetom commented Mar 2, 2022

Problem

In our applications, we are aiming to use fully qualified keywords whenever possible, to reduce ambiguity in data.

Martian contributes to attaining this goal, by allowing API request keys in kebab form, via the :parameter-aliases mechanism, lowering the impedance mismatch between the data structures of external data sources and Clojure programs internal nomenclature.

While this :parameter-aliases mechanism seems to be an internal API, since its structure is not explained, I assumed it might be customisable on a per-handler basis, but the automatically generated aliases override the custom ones.

  (-> "api-url"
      (martian/bootstrap
        [{:parameter-aliases
          {:path-schema
           {[] {:qb.company/realm-id :realmId}}}}])
      :handlers first :parameter-aliases :path-schema)
=> {}

or more specifically:

(-> "api-url"
      (martian/bootstrap
        [{:path-schema {:realmId s/Str}
          :parameter-aliases
          {:path-schema
           {[] {:qb.company/realm-id :realmId}}}}])
      :handlers first :parameter-aliases :path-schema)
=> {[] {:realm-id :realmId}}

Solution

I can introduce a custom interceptor, which would also do this kind of aliasing, but if martian.core/enrich-handler would be modified as follows:

(defn- enrich-handler [handler]
  (-> handler
      (update :parameter-aliases
              (fn [aliases]
                (reduce (fn [aliases parameter-key]
                          (update aliases parameter-key
                                  #(merge-with merge % (parameter-aliases (get handler parameter-key)))))
                        aliases
                        parameter-schemas)))))

then, in the example above, the per-handler, custom, namespaced aliases would be retained:

(-> "api-url"
      (martian/bootstrap
        [{:path-schema {:realmId s/Str}
          :parameter-aliases
          {:path-schema
           {[] {:qb.company/realm-id :realmId}}}}])
      :handlers first :parameter-aliases :path-schema)
=> {[] {:qb.company/realm-id :realmId, :realm-id :realmId}}

@oliyh, would you consider incorporating such a change or is it a bad idea, to piggyback this feature for providing handcrafted aliases?

@onetom
Copy link
Author

onetom commented Mar 2, 2022

btw, currently im working the problem around by retouching the handlers of a bootstrapped martian api:

(defn req-param-alias
  "Attach a parameter alias for a martian handler."
  [martian-handler key-alias schema & param-key-path]
  (-> martian-handler
      (assoc-in [:parameter-aliases
                 schema
                 (vec (butlast param-key-path))
                 key-alias]
                (last param-key-path))))

(defn mk-api
  [api-url handlers opts]
  (-> api-url
      (martian/bootstrap handlers opts)
      (update :handlers
              (partial map #(req-param-alias
                              % :qb.company/realm-id :path-schema :realmId)))))

but this adds an extra wrapper layer around martian.core/bootstrap...

@oliyh
Copy link
Owner

oliyh commented Mar 2, 2022

Hello,

Yes, I am in favour of letting data flow through and for any 'enriching' to be additive and not destructive, so what you propose sounds good. If you make a PR, there is a spec at https://github.com/oliyh/martian/blob/master/core/src/martian/spec.cljc describing the martian input data structure, you'll need to update that to include the :parameter-aliases key.

Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants