Entities (defentity)

Entities in workflo/macros define the types of data in your system (e.g. users, accounts, articles). The following list sums up the key features of entities:

  • Specs — entities are fully specified using clojure.spec
  • Relationships — relationships between entities can easily be defined. This includes one-to-one, one-to-many and many-to-many relations
  • Entity registry — entities defined with defentity are stored in a global registry, from where they can be looked up at any time
  • Schema generation — schemas for popular Clojure(Script) databases such as Datomic and DataScript can be derived from entities easily
  • Authorizationdefentity comes with built-in support for authorization to control access to entities in your system
  • Hints — entities can be tagged with arbitrary hints to allow special-casing entity data in the system (e.g. prevent certain entities from being persisted)

Usage

General structure

(require '[workflo.macros.entity :refer [defentity]])

(defentity <name>
  "description"    ; Optional
  (hints [...])    ; Optional
  (spec ...)       ; Required
  (auth-query ...) ; Optional
  (auth ...)       ; Optional
  )

Simple example

(require '[clojure.spec.alpha :as s])
(require '[workflo.macros.specs.types :as types])
(require '[workflo.macros.entity :refer [defentity]])

;;;; Specs for user attributes

(s/def :user/name ::types/string)
(s/def :user/email ::types/string)
(s/def :user/friends (types/entity-ref 'user :many? true))
(s/def :user/todos (types/entity-ref 'todo :many? true))

;;;; User entity

(defentity user
  "A user in a multi-user todo app"
  (spec
    (s/keys :req [:workflo/id
                  :user/name
                  :user/email]
            :opt [:user/friends
                  :user/todos]))

;;;; Specs for todo attributes

(s/def :todo/text ::types/string)
(s/def :todo/done? ::types/boolean)
(s/def :todo/complexity (s/and ::types/enum
                               {:todo.complexity/easy
                                :todo.complexity/medium
                                :todo.complexity/hard}))

;;;; Todo entity

(defentity todo
  "A todo item in a multi-user todo app"
  (spec
    (s/keys :req [:workflo/id
                  :todo/text
                  :todo/done?
                  :todo/complexity])))

API documentation

The following is a list of pointers to the namespaces that are related to entities: