# 02: schemas

Here's the source for this chapter:

```scheme
(ns reifyhealth.specmonstah-tutorial.02
  (:require [reifyhealth.specmonstah.core :as sm]
            [loom.io :as lio]))

(def schema
  {:user {:prefix :u}
   :post {:prefix    :p
          :relations {:owner-id [:user :id]}}})
(defn ex-01
  []
  (sm/add-ents {:schema schema} {:post [[2]]}))

(-> (ex-01) (sm/ents-by-type))
(-> (ex-01) (sm/ent-relations :u0))
(-> (ex-01) (sm/all-ent-relations))
```

Specmonstah's ent dbs must have a *schema*. A schema is a map that defines *ent types*. Specmonstah uses ent types to create an ent graph when you call `sm/add-ents`, as in `ex-01` above. This section explains how to define ent types and the relationship between ent types and ent graph generation.

In the schema, each key is the name of an ent type (`:user` and `:post` above) and each ent type's definition is a map with the keys `:prefix` and (usually) `:relations`. These values are used to generate ent graphs.

In generating the ent graph, each node needs to have a unique name. `:prefix` is used to name ents. If you want to add three users with `(sm/add-ents {:schema schema} {:user [[3]]})`, the `:user` ent type's `:prefix` of `:u` is used to generate ents named `:u0` , `:u1`, and `:u2`. There's a pattern here: every generated ent is named `:{schema-prefix}{index}`.

`:relations` defines how ents reference each other. The `:post` definition includes `{:relations {:owner-id [:user :id]}}`, specifying that a `:post` should reference a `:user`. The relation also specifies that the `:post`'s `:owner-id` should be set to the `:user`'s `:id`, information that will be used when we use spec-gen to generate records for these ents. (Covered in a later section).

These `:relations` are also what allow Specmonstah queries to be concise.&#x20;

The ent db's schema defines *ent types*. Ent types are used to generate the ent graph. When you call&#x20;

```scheme
(sm/add-ents {:schema schema} {:post [[2]]})
```

You don't explicitly specify that a `:user` should be created, but Specmonstah knows to add one because the `:post` ent type's `:relations` key specifies that `:post`s reference a `:user`.

Ent types usually correspond to database tables. If you're building a form that has posts and users, you'll probably create a `:post` ent type and `:user` ent type. You can also define more than one ent type per database table; if you find yourself often testing authentication scenarios, for example, you could create an `:invalid-user` ent type and write code that would insert the data for those ents into your `user` table (how to do this will be clear by the end of the tutorial). Ent type names are not in any way magical, you should use whatever names are most convenient for you.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://sweet-tooth.gitbook.io/specmonstah/tutorial/02-schemas.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
