anchor.diff:  and paths to function names; these can be extended or overridden by meta-data on the functions in the namespace.
   
   The end result is that a proper web service resource can be created in very little code.
  +
  +Rook makes use of https://github.com/weavejester/compojure[Compojure] to handle request routing.
  +
  +Rook is available under the terms of the Apache Software License 2.0.
   
   == Resource Handler Functions
   
  
positive.code:   ...)
  ----
  
  The `+:path-spec` contains two values: the keyword for the verb (this may also be the value `:all`) and the path to match.
  
  == Middleware
  
  Ring is divided into two main pieces: a _middleware_ and a _handler_.
  
  The middleware analyzes the namespace and the incoming request; it will identify the matching resource handler function, storing
  the information about it under the `:rook` request key.
  
  The _handler_ checks for that information; if present it invokes the identified resource handler function.
  
  
negative.code: 
  == Argument Resolution
  
  Ring assists with extracting information from the request and provides it as arguments to the invoked resource handler function.
  
  Ring uses the name of the argument to identify the value to provide.
  
  An argument named +request+ is passed the Ring request map.
  
  Otherwise, the argument name is converted to a pair of Clojure keywords.  The first keyword is the direct translation of the symbol
  to a keyword (e.g., +user-id+ to +:user-id+), this is the *argument keyword*.
  The second keyword converts embedded dashes to underscores (e.g., +user-id+ to +:user_id+).footnote:[
  The second keyword exists to pragmatically support clients sending JSON, rather than EDN, data; in JavaScript, underscores are
  easier to wrangle than dashes.] This is the *API keyword*.
  
  It is assumed that standard http://ring-clojure.github.io/ring/ring.middleware.keyword-params.html[Ring middleware] is in place to
  convert the +:params+ map from string keys to keyword keys.
  
  The order of search:
  
  * Invoke any argument resolver functions (see next section), passing the argument keyword.
  
  * A parameter name +request+ is resolved to the Ring request map.
  
  * Check the the request's +:route-params+, first for the argument keyword, then the API keyword; these represent keywords in the path specification.
  
  * Check the request's +:params+, first for the argument keyword, then the API keyword; these are parameters provided via the request's query string, or form
  submission.
  
  * Finally, unmatched arguments simply default to +nil+.
  
  Argument resolution is performed by the +rook-handler+ function, just before invoking the resource handler function.
  
  == Extending Argument Resolution
  
  Argument resolution can be extended by providing argument resolver functions.  An argument resolver function
  is passed the argument keyword, and the Ring request map
  and returns the resolved value for the argument.
  
  Argument resolvers can fulfill many purposes:
  
  * They can validate inputs from the client.
  
  * They can convert inputs from strings to other types, such as numbers or dates.
  
  * They can provide access to other resources, such as database connection pools.
  
  Argument resolver functions can be specified as meta-data directly on the resource handler function;
  the +:argument-resolvers+ meta-data key is a sequence of resolvers.
  
  Argument resolver functions take precedence over the default argument resolvers.
  
  In addition, middleware may provide resolvers as the key +:default-arg-resolvers+ under the +:rook+ request key;
  this is a list of argument resolver functions that apply to any resource handler function.
  
  WARNING: Currently, default argument resolvers are invoked _first_, before function-specific resolvers; this seems backwards
  and is likely to change.
  
  Function +arg-resolver-middleware+ is used to specify additional functions for +:default-arg-resolvers+.
  
  Function +build-map-arg-resolver+ constructs an argument resolver function from a map; It simply returns values from
  the map.
  
  Function +build-fn-arg-resolver+ constructs an argument resolver function from  a map of _functions_; The functions
  are selected by the argument keyword, and passed the request.
  
  Function +request-arg-resolver+ is an argument resolver that resolvers the argument keyword against the Ring request map itself.
  
  These can be composed:
  
  ----
  (defn add-standard-resolvers
    [handler conn-pool]
    (arg-resolver-middleware handler
                             (build-map-arg-resolver {:conn-pool conn-pool})
                             request-arg-resolver))
  ----
  
  == Mapping Namespaces
  
  A typical web service will expose some number of resources; under Ring this means mapping a number of namespaces.
  
  The +namespace-handler+ function is the easy way to do this mapping. It combines +compojure.core/context+ with Rook's
  +namespace-middleware+ (which identifies the function to be invoked within the namespace) and +rook-handler+ (which resolves
  arguments and invokes the identified function).
  
  ----
  (defroutes api-routes
    (namespace-handler "/users" 'org.example.resources.users)
    (namespace-handler "/orders" 'org.example.resources.orders))
  ----
  
  WARNING: You must be sure to +require+ the resource namespaces.
  
  Remember that the way +context+ works is to match and strip off the prefix, so an incoming GET request for +/users/232+
  will be matched as context +/users/+; the Rook will identify function +show+ with path +/:id+; ultimately invoking it
  with the _string_ value +232+ for the +id+ parameter.
  
  == Writing Rook Middleware
  
  Rook uses the +:rook+ key of the request to store information needed to process requests.
  With the exception of +:default-arg-resolvers+, the values are supplied by the the +namespace-middleware+ function.
  
  +:default-arg-resolvers+::
  List of argument resolvers that apply to any invoked resource handler function.
  +:namespace+::
  The symbol identifying the namespace containing the matched function.
  +:function+::
  The matched function, which will be invoked by +rook-handler+.
  +:metadata+::
  The meta-data for the matched function.
  +:arg-resolvers+::
  List of argument resolvers from the matched function's meta-data.
  
  Rook middleware that fits between +namespace-middleware+ and +rook-handler+ should check for nested request key +[:rook :function]+ to
  see if a function has been identified.
  
  WARNING: It is likely that a future change will make the handler provided by +namespace-middleware+ not delegate
  to its handler unless a function is identified.