|
| 1 | +--- |
| 2 | +description: >- |
| 3 | + A repository is a data access object that provides an abstraction over the |
| 4 | + underlying data source. This document provides an overview of repositories |
| 5 | + and how they are used in the framework. |
| 6 | +--- |
| 7 | + |
| 8 | +Repository |
| 9 | +========== |
| 10 | + |
| 11 | +A repository is a data access object that provides an abstraction over the |
| 12 | +underlying data source. BotKit provides a few built-in repositories that |
| 13 | +can be used to interact with the database, but you can also create your own |
| 14 | +repositories to interact with other data sources. |
| 15 | + |
| 16 | + |
| 17 | +`KvRepository` |
| 18 | +-------------- |
| 19 | + |
| 20 | +It is the default repository provided by BotKit. If you omit the |
| 21 | +[`repository`](./bot.md#createbotoptions-repository) option of |
| 22 | +the [`createBot()`](./bot.md#instantiation) function, BotKit will use |
| 23 | +the `KvRepository` by default. |
| 24 | + |
| 25 | +The `KvRepository` is a repository that stores data in a key–value store |
| 26 | +through the [`KvStore`] interface, which is provided by the Fedify. |
| 27 | +Since the [`KvStore`] interface itself also abstracts over the underlying |
| 28 | +data source, you can easily switch between different key–value stores |
| 29 | +without changing the repository implementation. |
| 30 | + |
| 31 | +There are several [`KvStore`] implementations available in the Fedify: |
| 32 | + |
| 33 | +[`RedisKvStore`] |
| 34 | +: [`RedisKvStore`] is a key–value store implementation that uses Redis as |
| 35 | + the backend storage. It provides scalability and high performance, making |
| 36 | + it suitable for production use in distributed systems. It requires |
| 37 | + a Redis server setup and maintenance. |
| 38 | + |
| 39 | + > [!NOTE] |
| 40 | + > The [`RedisKvStore`] class is available in the [@fedify/redis] package. |
| 41 | + |
| 42 | +[`PostgresKvStore`] |
| 43 | +: [`PostgresKvStore`] is a key–value store implementation that uses |
| 44 | + PostgreSQL as the backend storage. It provides scalability and high |
| 45 | + performance, making it suitable for production use in distributed systems. |
| 46 | + It requires a PostgreSQL server setup and maintenance. |
| 47 | + |
| 48 | + > [!NOTE] |
| 49 | + > The [`PostgresKvStore`] class is available in the [@fedify/postgres] |
| 50 | + > package. |
| 51 | + |
| 52 | +[`DenoKvStore`] (Deno only) |
| 53 | +: [`DenoKvStore`] is a key–value store implementation for [Deno] runtime |
| 54 | + that uses Deno's built-in [`Deno.openKv()`] API. It provides persistent |
| 55 | + storage and good performance for Deno environments. It's suitable for |
| 56 | + production use in Deno applications. |
| 57 | + |
| 58 | + > [!NOTE] |
| 59 | + > The [`DenoKvStore`] class is available in *x/deno* module of |
| 60 | + > the [@fedify/fedify] package. |
| 61 | + |
| 62 | +[`MemoryKvStore`] |
| 63 | +: A simple in-memory key–value store that doesn't persist data. It's |
| 64 | + best suited for development and testing environments where data don't |
| 65 | + have to be shared across multiple nodes. No setup is required, making |
| 66 | + it easy to get started. |
| 67 | + |
| 68 | + > [!TIP] |
| 69 | + > Although [`MemoryKvStore`] is provided by Fedify, BotKit also re-exports |
| 70 | + > it for convenience. |
| 71 | + |
| 72 | +[`KvStore`]: https://fedify.dev/manual/kv |
| 73 | +[`RedisKvStore`]: https://fedify.dev/manual/kv#rediskvstore |
| 74 | +[@fedify/redis]: https://github.com/dahlia/fedify-redis |
| 75 | +[`PostgresKvStore`]: https://fedify.dev/manual/kv#postgreskvstore |
| 76 | +[@fedify/postgres]: https://github.com/dahlia/fedify-postgres |
| 77 | +[`DenoKvStore`]: https://fedify.dev/manual/kv#denokvstore-deno-only |
| 78 | +[Deno]: https://deno.com/ |
| 79 | +[`Deno.openKv()`]: https://docs.deno.com/api/deno/~/Deno.openKv |
| 80 | +[@fedify/fedify]: https://fedify.dev/ |
| 81 | +[`MemoryKvStore`]: https://fedify.dev/manual/kv#memorykvstore |
| 82 | + |
| 83 | + |
| 84 | +`MemoryRepository` |
| 85 | +------------------ |
| 86 | + |
| 87 | +The `MemoryRepository` is a repository that stores data in memory, which means |
| 88 | +that data is not persisted across restarts. It's best suited for development |
| 89 | +and testing environments where data don't have to be shared across multiple |
| 90 | +nodes. No setup is required, making it easy to get started. |
| 91 | + |
| 92 | +> [!TIP] |
| 93 | +> How does it differ from using [`KvRepository`](#kvrepository) with |
| 94 | +> [`MemoryKvStore`]?—In practice, there's no difference between using |
| 95 | +> `MemoryRepository` and [`KvRepository`](#kvrepository) with |
| 96 | +> [`MemoryKvStore`]. The only differences are that `MemoryRepository` is |
| 97 | +> a more convenient way to use `MemoryKvStore` and that it's slightly more |
| 98 | +> efficient because it doesn't have to go through the [`KvStore`] interface. |
| 99 | +
|
| 100 | + |
| 101 | +Implementing a custom repository |
| 102 | +-------------------------------- |
| 103 | + |
| 104 | +You can create your own repository by implementing the `Repository` interface. |
| 105 | +The `Repository` interface is a generic interface that defines the basic |
| 106 | +CRUD (create, read, update, delete) operations for data access. |
| 107 | + |
| 108 | +The `Repository` interface consists of the following five domains of operations |
| 109 | +in general: |
| 110 | + |
| 111 | +Key pairs |
| 112 | +: Key pairs are the singleton data that are used for the bot actor. |
| 113 | + At the surface level, the key pairs are represented as [`CryptoKeyPair`] |
| 114 | + objects, but you would typically store them as [JWK]. |
| 115 | + |
| 116 | + > [!TIP] |
| 117 | + > Fedify provides `exportJwk()` and `importJwk()` functions to convert |
| 118 | + > a [`CryptoKey`] object to a JWK object and vice versa. |
| 119 | + |
| 120 | +Messages |
| 121 | +: Messages are the data of the messages that are published by the bot. |
| 122 | + Remote messages received from the remote server are not included in this |
| 123 | + domain. Each message has its own UUID and represented by either |
| 124 | + a `Create` object or an `Announce` object (which both are provided by |
| 125 | + Fedify). |
| 126 | + |
| 127 | + You probably want to serialize the messages into JSON before |
| 128 | + storing them, so you can use [`toJsonLd()`] method that belong to |
| 129 | + the `Create` and `Announce` objects, and use [`fromJsonLd()`] method |
| 130 | + to deserialize them. |
| 131 | + |
| 132 | +Followers |
| 133 | +: Followers are the data of the actors that follow the bot. Each follower |
| 134 | + is represented by `Actor` object (provided by Fedify) and is associated |
| 135 | + with a follow ID, a URI of the `Follow` activity. |
| 136 | + |
| 137 | + Similar to messages, you can serialize the `Actor` object into JSON |
| 138 | + using the [`toJsonLd()`] method, and deserialize it using the |
| 139 | + [`fromJsonLd()`] method. |
| 140 | + |
| 141 | + > [!CAUTION] |
| 142 | + > The `Repository.hasFollower()` method takes the URI of an `Actor`, not |
| 143 | + > the follow ID. |
| 144 | + |
| 145 | +Sent follows |
| 146 | +: Sent follows are the data of the follow requests that the bot has sent. |
| 147 | + Each sent follow is represented by a `Follow` object (provided by Fedify) |
| 148 | + and is associated with its own UUID. |
| 149 | + |
| 150 | + Similar to messages and followers, you can serialize the `Follow` object |
| 151 | + into JSON using the [`toJsonLd()`] method, and deserialize it using the |
| 152 | + [`fromJsonLd()`] method. |
| 153 | + |
| 154 | +Followees |
| 155 | +: Followees are the data of the actors that the bot follows. Each followee |
| 156 | + is represented by a `Follow` object (provided by Fedify) instead of `Actor`, |
| 157 | + and associated with an actor ID (not a follow ID). |
| 158 | + |
| 159 | + Similar to messages, followers, and sent follows, you can serialize |
| 160 | + the `Follow` object into JSON using the [`toJsonLd()`] method, and |
| 161 | + deserialize it using the [`fromJsonLd()`] method. |
| 162 | + |
| 163 | +[`CryptoKeyPair`]: https://developer.mozilla.org/en-US/docs/Web/API/CryptoKeyPair |
| 164 | +[JWK]: https://datatracker.ietf.org/doc/html/rfc7517 |
| 165 | +[`CryptoKey`]: https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey |
| 166 | +[`toJsonLd()`]: https://fedify.dev/manual/vocab#json-ld |
| 167 | +[`fromJsonLd()`]: https://fedify.dev/manual/vocab#json-ld |
0 commit comments