0.2.1-123541b docs





    Oct 7, 2015

    Moved to plumatic

    Index of all namespaces

    « Project + dependencies

    Transform lightly-annotated functions into a full-fledged web service

    Proof-of-concept, ultra-primitive HTML doc generation from a fnhouse API spec,
    including schemas and per-namespace handler doc pages.
    Utilities for turning a set of fnhouse handlers into an API description.
    A fnhouse handler is an ordinary Clojure function that accepts a map
    with two keys:
      :request is a Ring-style request [1] (see fnhouse.schemas/Request)
      :resources is an arbitrary map of resources (e.g., database handles).
    By default, the name of the function specifies the path and method of
    the handler (overridable with :path and :method metadata).  The handler
    must also be annotated with metadata describing schemas [2] for the required
    resources, key portions of the request (uri-args, query-params and body),
    and response bodies.
    The simplest way to specify this data is to use a defnk from
    plumbing.core [2], which can simultaneously destructure items from the
    resources and request, and produce the necessary corresponding schema
    For example, here is an example of a minimal fnhouse handler:
    (defnk unimaginative$GET
      {:responses {200 String}}
      {:body "Hello, world!"})
    which defines a GET handler at path /unimaginative, which always returns
    the string "Hello, world!".
    A more complex example that illustrates most of the features of fnhouse:
    (s/defschema Idea {:name String :difficulty Double})
    (defn hammock$:id$ideas$POST
      "Save a new idea to hammock :id, and return the list of existing ideas"
      {:responses {200 [Idea]}}
        [:uri-args id :- Long]
        [:query-params {hard? :- Boolean false}]
        body :- Idea]
       [:resources ideas-atom]]
      {:body ((swap! ideas-atom update-in [id] conj
                     (if hard? (update-in idea [:difficulty] * 2) idea))
    This is a handler that accepts POSTS at URIs like /hammock/12/ideas,
    with an optional Boolean query-param hard?, and a body that matches the
    Idea schema, adds the Idea to hammock 12, and returns the list of all
    current ideas at hammock 12.  The state of ideas is maintained in ideas-atom,
    which is explicitly passed in as a resource (assigned the default schema
    of s/Any by defnk).
    This handler can be called as an ordinary Clojure function (i.e., in tests),
    and runtime schema checking can be turned on following instructions in [2].
    The handler can also be turned into an API description by calling nss->handlers-fn
    (or related functions) and then passing in the map of resources, like:
    ((nss->handlers-fn {"" 'my-namespace})
     {:ideas-atom (atom {})})
    With this API description, you can do many things.  Out of the box, there is support
      - Turning the full API into a normal Ring handler using fnhouse.routes
      - Enabling schema checking and coercion using fnhouse.middleware
        (so, e.g., the Long id in uri-args is automatically parsed for you)
      - Producing minimal API docs
      - Generating model classes and client libraries for ClojureScript and
        Objective C using, e.g., coax [4]
    For a complete example, see the included 'examples/guesthouse' project.
    Middleware for coercing and schema-validating requests and responses.
    By default -- passing (constantly nil) for input-coercer and output-coercer --
    ordinary schema validation is applied, with default string coercion for input uri-args
    and query-params and json coercion for the body (see schema.coerce).  Schema
    validation errors will throw with a helpful error message.
    In addition, custom RequestRelativeCoercionMatchers can be passed for input and
    output coercion, which enable the coercion of custom types in the input and output.
    For examples, see the included 'examples/guesthouse' project.
    A simple and efficient library for routing an API of fnhouse
    handlers (see fnhouse.handlers).  The sole entry point to the ns
    is the 'root-handler' fn.
    Paths can be concrete (simple strings to be matched exactly), or
    can contain one or more uri arguments specified with colons.
    For example, the path /a/b/c only matches the same literal URI, but
    the path /a/:b/c/:d can match any path with non-empty segments that
    don't contain slashes for :b and :c.  I.e., it can match
    /a/123/c/asdf but not /a/123/c/ or /a/b1/b2/c/d.  The segments
    matching uri arguments are inserted into the request as :uri-args,
    url-decoded for example {:b "123" :d "asd f"} for /a/123/c/as%20df.
    A path can also contain a single trailing 'wildcard' uri-arg, which
    can match any number of trailing segments in the uri.  For example,
    /a/:** can match /a, /a/b, or /a/b/c/d.  The wildcard match is
    included in the :uri-args in the request, e.g. {:** "b/c/d"},
    but is not url-decoded.
    Routing is performed with an efficient hierarchical algorithm,
    whose runtime is independent of the number of handler for exact
    matches, and can be much better than a linear traversal of all methods
    in almost every situation.
    If multiple handlers can match a URI, the precedence rules are
    specified hierarchically over segments. At each level, the lookup
    prioritizes literal matches over single-wildcards, and
    single-wildcards over multiple-wildcards.  The search will
    backtrack to try all possible matching routes.
    Defines schemas for Handlers and HandlerInfo, fnhouse's API description format.
    See docstrings below for details.