                     (->DisallowedGet)
                     (->DisallowedPut)
                     (->DisallowedDelete)
-                    ]})
-           (s/validate {:handlers [(s/protocol Example)]})
+                    ]]
+      (s/validate [(s/protocol Example)] handlers)
+      ["/examples"
+       [["/"
+         (vec
+          (concat
+           (for [h handlers]
+             [(get-path h) (handler (keyword (basename h))
+                                    (make-async-handler (eval (resource-map h))))])
+           [["index.html"
+             (handler
+              ::index
+              (fn [_]
+                (ok
+                 (index (:routes @router) handlers))))]
+            ["tests.html"
+             (handler
+              ::tests
+              (fn [_]
+                (ok (tests (:routes @router) handlers))))
+             ]
+            ["" (redirect ::index)]]))]
+        ["" (redirect ::index)]]]
+      )))
+
+(defn new-examples-service [& {:as opts}]
+  (-> (->> opts
+           (merge {})
+
            map->ExamplesService)
       (using [])
       (co-using [:router])))


;; Conditional GETs

(defrecord ConditionalGet []
  Example
  (resource-map [_] {:body "Hello World!"})
  (request [_] {:method :get
                :headers {"Accept" "text/plain"}})
  (expected-response [_] {:status 200}))

   :headers {"content-type" "text/html;charset=utf-8"}
   :body body})

(defrecord ExamplesService [router]
  Lifecycle
  (start [component] (assoc component :start-time (java.util.Date.)))
  (stop [component] component)

  RouteProvider
  (routes [component]
    (let [handlers [(->BodyAsString)
                    (->StatusAndHeaders)
                    (->DynamicBody)
                    (->AsyncBody)
