Fork me on GitHub

@ordnungswidrig: if you get time, can you give me your impression of - I've worked hard to refactor it since your last feedback and I want to know if I'm going in the right direction to meet your design preferences


@malcolmsparks: great! You totally use PRs so I can leave nasty comments 😉


well, this isn't a PR, I haven't been sending myself those simple_smile not sure if you can comment directly on code with github


the idea is that when you have created a handler (yada.core/handler ...) you get back a map (a record) which is the data model for the resource - all the things that are determined from the resource regardless of any incoming requets


that design has forced some hard choices on me - for example - having to determine the set of representations without having the request to drive it


so the set of representations is 'static', and the request simply influences the 'selection' process


I had to do this because of If-Match - the spec. says the If-Match header value has to be checked against every possible representation for the resource. That's expensive unless you can pre-compute the set of representations


Oh, yes. Never thought about the implications on If-Match!


That means that if-match and content negotiation need to work together?


No, they can still be independent.


(let [version (p/version (:resource ctx) ctx)
            etags (into {} (map (juxt identity (partial p/to-etag version))
                                (-> ctx :handler :representations)))]

        (if (empty? (set/intersection matches (set (vals etags))))
           (ex-info "Precondition failed"
                    {:status 412
                     ::http-response true}))



the resource's version cannot be determined ahead of time (because it changes!), so what I do in the if-match function is recompute the etag of each and every representation. The set of representation 'metadatas' are pre-computed, the version isn't, so all the etags are recomputed.


etag = hash(version + representation-metadata)


this looks to be expensive if you have many representations, but I can't think of another way of faithfully implementing this part of the spec.


(code formatting problem is just slack!)


(-> ctx :handler :representations) is a fixed list, pre-calculated when the (yada.yada/handler ...) function is called.


This is a design decision to be somewhat more static than dynamic. If you really NEED dynamic representation metadata you can build the yada handler upon every request! Clojure will let you do that, you just pay a small performance penalty for doing so because yada is optimized for request handling performance over handler creation performance.


btw. I haven't yet implemented If-None-Match so there is still a small chance this might all change 😉


Oh I see. You practically spoken the client could send an If-Match for a json representation but Accepts and sends a edn representation in that request, right?