duct-framework / module.ataraxy

Duct module and router for the Ataraxy routing library
5 stars 4 forks source link

correct usage of `:ataraxy.error/failed-spec` #3

Open zerg000000 opened 7 years ago

zerg000000 commented 7 years ago

Here is a working example start from [module.ataraxy 0.17]. May I know using :example instead of :my.handler/example is intentional or not?

config.edn

{:duct.module/ataraxy
 {[:get "/example" {body :params}] [:example body]}
 :duct.router/ataraxy
 {:handlers {:ataraxy.error/failed-spec #ig/ref :my.handler/error}}
 :my.handler/error {}}

my.handler/example.clj

(defmethod ig/init-key :my.handler/example [_ options]
  (fn [{[_ body] :ataraxy/result}]
    [::response/ok (io/resource "my/handler/example/example.html")]))

(defmethod ataraxy/result-spec :example [_]
  (s/tuple any? :my.spec/example))

my.handler/error.clj

(defmethod ig/init-key :my.handler/error [_ options]
  (fn [{[_ error] :ataraxy/result}]
    (let [messages (map f/format
                        (-> error :clojure.spec.alpha/problems))]
      [::response/bad-request {:messages messages}])))
weavejester commented 7 years ago

May I know using :example instead of :my.handler/example is intentional or not?

If I've understood you correctly: it's intentional. Check the README for an explanation.

zerg000000 commented 7 years ago
(defmethod ataraxy/result-spec :example [_] ; <-- this is the keyword I doubted :example
  (s/tuple any? :my.spec/example))
weavejester commented 7 years ago

Yes, that's correct. See: https://github.com/weavejester/ataraxy#specs

weavejester commented 7 years ago

Though if you're using specs, you might want to give the result key a namespace to ensure it's somewhat unique.

zerg000000 commented 7 years ago

I mean the :aaa/example in route will be expanded to key :my.handler.aaa/example for searching the handler

{[:get "/example" {body :params}] [:aaa/example body]} ; this :aaa/example will match the handler :my.handler.aaa.example

(defmethod ig/init-key :my.handler.aaa/example [_ options]
  ...) ; this handler will be called for /example

However, For adding the result validation ataraxy/result-spec, I must use :aaa/example instead of the expanded key :my.handler.aaa/example

(defmethod ataraxy/result-spec :aaa/example [_] ;
  (s/tuple any? :my.spec/example))

The different handling between handler shorthand and the result-spec is quite surprise. If it is intended, it should be documented.

weavejester commented 7 years ago

I don't know why you consider it surprising. As the name suggests, araraxy.core/result-spec is part of Ataraxy. That means it only knows things Ataraxy knows, so it operates off the result key, rather than the Integrant-specific component key.

Maybe it would have been simpler to make the syntax:

{[:get "/example" {body :params}] [:my.handler.aaa/example body]}

That would unify the keys, which seem to be a source of confusion. But when I tried it, it just seemed to make the route syntax too verbose.

zerg000000 commented 7 years ago

I think a few words describing the usage of ataraxy.core/result-spec under duct framework is enough to ease this pain.