diff --git a/doc/SUMMARY.md b/doc/SUMMARY.md index 2ed3f462..a477bd95 100644 --- a/doc/SUMMARY.md +++ b/doc/SUMMARY.md @@ -21,6 +21,7 @@ * [Dev Workflow](advanced/dev_workflow.md) * [Ring](ring/README.md) * [Ring-router](ring/ring.md) + * [Default handler](ring/default_handler.md) * [Static Resources](ring/static.md) * [Dynamic Extensions](ring/dynamic_extensions.md) * [Data-driven Middleware](ring/data_driven_middleware.md) diff --git a/doc/ring/README.md b/doc/ring/README.md index d0d88756..623dac80 100644 --- a/doc/ring/README.md +++ b/doc/ring/README.md @@ -1,6 +1,7 @@ # Ring * [Ring-router](ring.md) +* [Default handler](default_handler.md) * [Static Resources](static.md) * [Dynamic Extensions](dynamic_extensions.md) * [Data-driven Middleware](data_driven_middleware.md) diff --git a/doc/ring/default_handler.md b/doc/ring/default_handler.md new file mode 100644 index 00000000..7fc38604 --- /dev/null +++ b/doc/ring/default_handler.md @@ -0,0 +1,82 @@ +# Default handler + +By default, if no routes match, `nil` is returned, which is not valid response in Ring: + +```clj +(require '[reitit.ring :as ring]) + +(defn handler [_] + {:status 200, :body ""}) + +(def app + (ring/ring-handler + (ring/router + ["/ping" handler]))) + +(app {:uri "/invalid"}) +; nil +``` + +Setting the default-handler as a second argument to `ring-handler`: + +```clj +(def app + (ring/ring-handler + (ring/router + ["/ping" handler]) + (constantly {:status 404, :body ""}))) + +(app {:uri "/invalid"}) +; {:status 404, :body ""} +``` + +To get more correct http error responses, `ring/create-default-handler` can be used. It differentiates `:not-found` (no route matched), `:method-not-accepted` (no method matched) and `:not-acceptable` (handler returned `nil`). + +With defaults: + +```clj +(def app + (ring/ring-handler + (ring/router + [["/ping" {:get handler}] + ["/pong" (constantly nil)]]) + (ring/create-default-handler))) + +(app {:request-method :get, :uri "/ping"}) +; {:status 200, :body ""} + +(app {:request-method :get, :uri "/"}) +; {:status 404, :body ""} + +(app {:request-method :post, :uri "/ping"}) +; {:status 405, :body ""} + +(app {:request-method :get, :uri "/pong"}) +; {:status 406, :body ""} +``` + +With custom responses: + +```clj +(def app + (ring/ring-handler + (ring/router + [["/ping" {:get handler}] + ["/pong" (constantly nil)]]) + (ring/create-default-handler + {:not-found (constantly {:status 404, :body "kosh"}) + :method-not-allowed (constantly {:status 405, :body "kosh"}) + :not-acceptable (constantly {:status 406, :body "kosh"})}))) + +(app {:request-method :get, :uri "/ping"}) +; {:status 200, :body ""} + +(app {:request-method :get, :uri "/"}) +; {:status 404, :body "kosh"} + +(app {:request-method :post, :uri "/ping"}) +; {:status 405, :body "kosh"} + +(app {:request-method :get, :uri "/pong"}) +; {:status 406, :body "kosh"} +``` \ No newline at end of file diff --git a/doc/ring/ring.md b/doc/ring/ring.md index f85afac7..f80be622 100644 --- a/doc/ring/ring.md +++ b/doc/ring/ring.md @@ -125,87 +125,6 @@ Middleware is applied correctly: ; {:status 200, :body [:api :admin :db :delete :handler]} ``` -# Default handler - -By default, if no routes match, `nil` is returned, which is not valid response in Ring: - -```clj -(defn handler [_] - {:status 200, :body ""}) - -(def app - (ring/ring-handler - (ring/router - ["/ping" handler]))) - -(app {:uri "/invalid"}) -; nil -``` - -Setting the default-handler as a second argument to `ring-handler`: - -```clj -(def app - (ring/ring-handler - (ring/router - ["/ping" handler]) - (constantly {:status 404, :body ""}))) - -(app {:uri "/invalid"}) -; {:status 404, :body ""} -``` - -To get more correct http error responses, `ring/create-default-handler` can be used. It differentiates `:not-found` (no route matched), `:method-not-accepted` (no method matched) and `:not-acceptable` (handler returned `nil`). - -With defaults: - -```clj -(def app - (ring/ring-handler - (ring/router - [["/ping" {:get handler}] - ["/pong" (constantly nil)]]) - (ring/create-default-handler))) - -(app {:request-method :get, :uri "/ping"}) -; {:status 200, :body ""} - -(app {:request-method :get, :uri "/"}) -; {:status 404, :body ""} - -(app {:request-method :post, :uri "/ping"}) -; {:status 405, :body ""} - -(app {:request-method :get, :uri "/pong"}) -; {:status 406, :body ""} -``` - -With custom responses: - -```clj -(def app - (ring/ring-handler - (ring/router - [["/ping" {:get handler}] - ["/pong" (constantly nil)]]) - (ring/create-default-handler - {:not-found (constantly {:status 404, :body "kosh"}) - :method-not-allowed (constantly {:status 405, :body "kosh"}) - :not-acceptable (constantly {:status 406, :body "kosh"})}))) - -(app {:request-method :get, :uri "/ping"}) -; {:status 200, :body ""} - -(app {:request-method :get, :uri "/"}) -; {:status 404, :body "kosh"} - -(app {:request-method :post, :uri "/ping"}) -; {:status 405, :body "kosh"} - -(app {:request-method :get, :uri "/pong"}) -; {:status 406, :body "kosh"} -``` - # Async Ring All built-in middleware provide both 2 and 3-arity and are compiled for both Clojure & ClojureScript, so they work with [Async Ring](https://www.booleanknot.com/blog/2016/07/15/asynchronous-ring.html) and [Node.js](https://nodejs.org) too. diff --git a/doc/ring/static.md b/doc/ring/static.md index 64beb482..740f5bc6 100644 --- a/doc/ring/static.md +++ b/doc/ring/static.md @@ -1,6 +1,6 @@ # Static Resources (Clojure Only) -Static resources can be served with a help of `reitit.ring/create-resource-handler`. It takes optionally an options map and returns a ring handler to serve files from Classpath. It returns `java.io.File` instances, so ring adapters can use NIO to effective Stream the files. +Static resources can be served with a help of `reitit.ring/create-resource-handler`. It takes optionally an options map and returns a ring handler to serve files from Classpath. There are two options to serve the files. @@ -59,6 +59,6 @@ To serve files from conflicting paths, e.g. `"/*"`, one option is to mount them ### TODO -* support for things like `:cache`, `:last-modified?`, `:index-files` and `:gzip` +* support for things like `:cache`, `:etag`, `:last-modified?`, `:index-files` and `:gzip` * support for ClojureScript * serve from file-system