# Entities in Redis

An entity may live in a Redis store, for data that is short-lived and
harmless to lose. It must expire: `expires_after:` gives how long a record
lives, counted from its last write.

app.jadpo:

```jadpo
application {
    connections: {
        drafts: {
            driver: Driver.redis
            url: config.redis_url
        }
    }
}
```

domains/accounts/entities/sign_up_draft.jadpo:

```jadpo
/// A sign-up someone has started and not yet finished.
entity SignUpDraft {
    id: Uuid
    email: Email {
        unique: true
    }
    step: SignUpStep
    attempts: Int

    store: drafts
    expires_after: 2h
    indexes: {
        by_step: [step]
    }
}
```

Expired records are hidden from every read and update, as records
`visible:` hides are
([Entities in Redis](queries-on-entities-in-redis.md) under
Reads and writes). An `expires_after:` on an entity in a database, or a
Redis entity without one, is a compile error.

A Redis entity supports:

- **get, create, update and delete by `id`**, the generated operations
  every entity has. Counters are included: an update by `id` that adds to
  a stored whole number (`SignUpDraft.attempts + 1`) is one Redis
  `increment`.
- **lookup by a `unique:` field**, for which Jadpo keeps one key per
  unique field.
- **listing and counting by equality on one field** declared in
  `indexes:`, for which Jadpo keeps a set per value. Pages come in
  creation order.
- **concurrent-change checks**, through a revision Jadpo keeps on each
  record, as every write checks ([Logic](logic.md)).

Anything else is a compile error that names the reason and suggests
PostgreSQL instead: joins and `include`, ranges, ordering by any other
field, `matches`, an index over several fields, and policy grants beyond
equality on the record's own fields. So is a `lifecycle:`, since expiry
takes its place.

A record is stored as one JSON value, the same JSON the API sends, like a
cache entry.

Not built yet: entities in Redis, which come with the Redis driver.
