Very often, we want to validate our data against some schema.compojure-api allows us to provide custom schema with constraints for our data.
For our cards entities, we can add the following constraints:
- The name should not be blank and should not have more than 50 characters
- The description should have at least five characters but not more than 100
Create a util.clj file, where we'll include convenience functions:
(ns restful.util
(:require [clojure.string :as str]))
(def non-blank? (complement str/blank?))
(defn max-length? [length text]
(<= (count text) length))
(defn non-blank-with-max-length? [length text]
(and (non-blank? text) (max-length? length text)))
(defn min-length? [length text]
(>= (count text) length))
(defn length-in-range? [min-length max-length text]
(and (min-length? min-length text) (max-length? max-length text)))
We'll use these functions to define the schema for CardReqest, in cards.clj:
(ns restful.cards
(:require [compojure.api.sweet :refer [GET POST PUT DELETE]]
[restful.models.card :refer [Card]]
[restful.util :as str]
[ring.util.http-response :refer [ok not-found created]]
[schema.core :as s]
[toucan.db :as db]))
(defn valid-name? [name]
(str/non-blank-with-max-length? 50 name))
(defn valid-description? [description]
(str/length-in-range? 5 100 description))
(s/defschema CardRequestSchema
{:name (s/constrained s/Str valid-name?)
:description (s/constrained s/Str valid-description?)})
We've defined the schema for CardRequest, which should contain a valid :name and :description.