Add input validation
Input validation uses Malli coercion. Sadly enough, email is validated with a regexp.
This commit is contained in:
@@ -27,3 +27,5 @@ The following links proved more than useful when working on this assignment:
|
|||||||
|
|
||||||
* <https://practical.li/clojure-web-services/building-api/>
|
* <https://practical.li/clojure-web-services/building-api/>
|
||||||
* <https://github.com/metosin/reitit/blob/master/doc/ring/content_negotiation.md>
|
* <https://github.com/metosin/reitit/blob/master/doc/ring/content_negotiation.md>
|
||||||
|
* <https://ostash.dev/posts/2021-08-22-data-validation-in-clojure/>
|
||||||
|
* <https://clojurecivitas.github.io/malli/elements_of_malli.html>
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
[ring/ring-core "1.15.3"]
|
[ring/ring-core "1.15.3"]
|
||||||
[ring/ring-jetty-adapter "1.15.3"]
|
[ring/ring-jetty-adapter "1.15.3"]
|
||||||
[metosin/reitit "0.10.0"]
|
[metosin/reitit "0.10.0"]
|
||||||
|
[metosin/reitit-malli "0.10.0"]
|
||||||
[metosin/muuntaja "0.6.11"]]
|
[metosin/muuntaja "0.6.11"]]
|
||||||
:main ^:skip-aot yohoho.core
|
:main ^:skip-aot yohoho.core
|
||||||
:target-path "target/%s"
|
:target-path "target/%s"
|
||||||
|
|||||||
@@ -2,10 +2,26 @@
|
|||||||
(:require [reitit.ring :as ring]
|
(:require [reitit.ring :as ring]
|
||||||
[ring.adapter.jetty :as http-server]
|
[ring.adapter.jetty :as http-server]
|
||||||
[reitit.ring.middleware.muuntaja :as muuntaja]
|
[reitit.ring.middleware.muuntaja :as muuntaja]
|
||||||
[muuntaja.core :as m])
|
[muuntaja.core :as m]
|
||||||
|
[reitit.coercion.malli :as malli]
|
||||||
|
[reitit.ring.coercion :as coercion])
|
||||||
(:gen-class))
|
(:gen-class))
|
||||||
|
|
||||||
|
|
||||||
|
;; Data schema ----------------------------------------------------
|
||||||
|
;; Malli schemas for validation
|
||||||
|
|
||||||
|
;; Validating an email address is hard.
|
||||||
|
;; Regexp shamelessly taken from https://emailregex.com/
|
||||||
|
(def email-regexp #"(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*\")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])")
|
||||||
|
|
||||||
|
(def Email [:re email-regexp])
|
||||||
|
|
||||||
|
(def Item
|
||||||
|
[:map
|
||||||
|
[:name :string]
|
||||||
|
[:email Email]])
|
||||||
|
|
||||||
|
|
||||||
;; Handlers -------------------------------------------------------
|
;; Handlers -------------------------------------------------------
|
||||||
(defn ahoy-handler
|
(defn ahoy-handler
|
||||||
@@ -52,11 +68,19 @@
|
|||||||
(ring/router
|
(ring/router
|
||||||
[["/ahoy" {:get ahoy-handler}]
|
[["/ahoy" {:get ahoy-handler}]
|
||||||
["/items" {:get get-items-handler
|
["/items" {:get get-items-handler
|
||||||
:post post-items-handler}]]
|
:post {:handler post-items-handler
|
||||||
;; Use muuntaja middleware to automatically decode JSON
|
:parameters {:body Item}}}]]
|
||||||
{:data {:muuntaja m/instance
|
;; Middlewares:
|
||||||
|
;; - wrap-content-type-json: ensure POST routes are sent JSON payload
|
||||||
|
;; - muuntaja middleware to automatically decode JSON
|
||||||
|
;; - malli + coercion: handle data validation
|
||||||
|
{:data {:coercion malli/coercion
|
||||||
|
:muuntaja m/instance
|
||||||
:middleware [wrap-content-type-json
|
:middleware [wrap-content-type-json
|
||||||
muuntaja/format-middleware]}})
|
muuntaja/format-middleware
|
||||||
|
coercion/coerce-exceptions-middleware
|
||||||
|
coercion/coerce-request-middleware
|
||||||
|
coercion/coerce-response-middleware]}})
|
||||||
;; Default route: anything not explicitely handled should give a 404
|
;; Default route: anything not explicitely handled should give a 404
|
||||||
(ring/create-default-handler
|
(ring/create-default-handler
|
||||||
{:not-found (constantly {:status 404
|
{:not-found (constantly {:status 404
|
||||||
|
|||||||
Reference in New Issue
Block a user