You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: content/recipes/mikroorm.md
+47-70Lines changed: 47 additions & 70 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,27 +1,19 @@
1
1
### MikroORM
2
2
3
-
This recipe is here to help users getting started with MikroORM in NestJS. MikroORM is the TypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. It is well maintained and the maintainer responds quick to questions and issues. It is a great alternative to TypeORM and migration from TypeORM should be fairly easy.
3
+
This recipe is here to help users getting started with MikroORM in Nest. MikroORM is the TypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. It is a great alternative to TypeORM and migration from TypeORM should be fairly easy. The complete documentation on MikroORM can be found [here](https://mikro-orm.io/docs).
4
4
5
-
[The complete documentation on MikroORM can be found here.](https://mikro-orm.io/docs)
6
-
7
-
> info **info**@mikro-orm/nestjs is a third party package and not managed by the NestJS core team. Please bring any issues found with the library to the [appropriate repository](https://github.com/mikro-orm/nestjs)
5
+
> info **info**`@mikro-orm/nestjs` is a third party package and is not managed by the NestJS core team. Please, report any issues found with the library in the [appropriate repository](https://github.com/mikro-orm/nestjs).
8
6
9
7
#### Installation
10
8
11
9
Easiest way to integrate MikroORM to Nest is via [`@mikro-orm/nestjs` module](https://github.com/mikro-orm/nestjs).
12
-
Simply install it next to Nest, MikroORM and underlying driver:
10
+
Simply install it next to Nest, MikroORM and underlying driver:
13
11
14
12
```bash
15
-
$ yarn add @mikro-orm/core @mikro-orm/nestjs @mikro-orm/mysql# for mysql/mariadb
13
+
$ npm i @mikro-orm/core @mikro-orm/nestjs @mikro-orm/mysql # for mysql/mariadb
16
14
```
17
15
18
-
or
19
-
20
-
```bash
21
-
$ npm i -s @mikro-orm/core @mikro-orm/nestjs @mikro-orm/sqlite # for sqlite
22
-
```
23
-
24
-
MikroORM also supports `postgres` and `mongo`. See the [official docs](https://mikro-orm.io/docs/usage-with-sql/) for all the drivers.
16
+
MikroORM also supports `postgres`, `sqlite`, and `mongo`. See the [official docs](https://mikro-orm.io/docs/usage-with-sql/) for all drivers.
25
17
26
18
Once the installation process is completed, we can import the `MikroOrmModule` into the root `AppModule`.
27
19
@@ -43,7 +35,7 @@ export class AppModule {}
43
35
44
36
The `forRoot()` method accepts the same configuration object as `init()` from the MikroORM package. Check [this page](https://mikro-orm.io/docs/configuration) for the complete configuration documentation.
45
37
46
-
Alternatively we can [configure the CLI](https://mikro-orm.io/docs/installation#setting-up-the-commandline-tool) by creating a configuration file `mikro-orm.config.ts` and then call the `forRoot()` without any arguments. This won't work when you use a build tools that use tree shaking.
38
+
Alternatively we can [configure the CLI](https://mikro-orm.io/docs/installation#setting-up-the-commandline-tool) by creating a configuration file `mikro-orm.config.ts` and then call the `forRoot()` without any arguments. This won't work when you use a build tools that use tree shaking.
47
39
48
40
```typescript
49
41
@Module({
@@ -59,32 +51,29 @@ Afterward, the `EntityManager` will be available to inject across entire project
59
51
60
52
```ts
61
53
import { MikroORM } from'@mikro-orm/core';
62
-
import { EntityManager } from'@mikro-orm/mysql'; // Import EntityManager from your driver package or `@mikro-orm/knex`
54
+
// Import EntityManager from your driver package or `@mikro-orm/knex`
55
+
import { EntityManager } from'@mikro-orm/mysql';
63
56
64
57
@Injectable()
65
58
exportclassMyService {
66
-
67
-
constructor(privatereadonlyorm:MikroORM,
68
-
privatereadonlyem:EntityManager) {
69
-
}
70
-
59
+
constructor(
60
+
privatereadonlyorm:MikroORM,
61
+
privatereadonlyem:EntityManager,
62
+
) {}
71
63
}
72
64
```
73
65
74
-
> info **info** Notice that the `EntityManager` is imported from the `@mikro-orm/driver` package, where driver is `mysql`, `sqlite`, `postgres` or what driver you are using.
75
-
>
76
-
> In case you have `@mikro-orm/knex` installed as a dependency, you can also import the `EntityManager` from there.
66
+
> info **info** Notice that the `EntityManager` is imported from the `@mikro-orm/driver` package, where driver is `mysql`, `sqlite`, `postgres` or what driver you are using. In case you have `@mikro-orm/knex` installed as a dependency, you can also import the `EntityManager` from there.
77
67
78
68
#### Repositories
79
-
MikroORM supports the repository design pattern. For every entity we can create a repository. Read the complete [documentation on repositories here](https://mikro-orm.io/docs/repositories). To define which repositories shall be registered in the current scope you can use the `forFeature()` method. For example, in this way:
80
69
81
-
> info **info** You should **not** register your base entities via `forFeature()`, as there are no
82
-
> repositories for those. On the other hand, base entities need to be part of the list
83
-
> in `forRoot()` (or in the ORM config in general).
70
+
MikroORM supports the repository design pattern. For every entity we can create a repository. Read the complete documentation on repositories [here](https://mikro-orm.io/docs/repositories). To define which repositories should be registered in the current scope you can use the `forFeature()` method. For example, in this way:
71
+
72
+
> info **info** You should **not** register your base entities via `forFeature()`, as there are no
73
+
> repositories for those. On the other hand, base entities need to be part of the list in `forRoot()` (or in the ORM config in general).
84
74
85
75
```typescript
86
76
// photo.module.ts
87
-
88
77
@Module({
89
78
imports: [MikroOrmModule.forFeature([Photo])],
90
79
providers: [PhotoService],
@@ -110,10 +99,8 @@ In this way we can inject the `PhotoRepository` to the `PhotoService` using the
> info **info**`autoLoadEntities` option was added in v4.1.0
148
+
> info **info**`autoLoadEntities` option was added in v4.1.0
171
149
172
-
Manually adding entities to the entities array of the connection options can be
173
-
tedious. In addition, referencing entities from the root module breaks application
174
-
domain boundaries and causes leaking implementation details to other parts of the
150
+
Manually adding entities to the entities array of the connection options can be
151
+
tedious. In addition, referencing entities from the root module breaks application
152
+
domain boundaries and causes leaking implementation details to other parts of the
175
153
application. To solve this issue, static glob paths can be used.
176
154
177
-
Note, however, that glob paths are not supported by webpack, so if you are building
178
-
your application within a monorepo, you won't be able to use them. To address this
179
-
issue, an alternative solution is provided. To automatically load entities, set the
180
-
`autoLoadEntities` property of the configuration object (passed into the `forRoot()`
181
-
method) to `true`, as shown below:
155
+
Note, however, that glob paths are not supported by webpack, so if you are building
156
+
your application within a monorepo, you won't be able to use them. To address this
157
+
issue, an alternative solution is provided. To automatically load entities, set the
158
+
`autoLoadEntities` property of the configuration object (passed into the `forRoot()`
159
+
method) to `true`, as shown below:
182
160
183
161
```ts
184
162
@Module({
@@ -192,44 +170,42 @@ method) to `true`, as shown below:
192
170
exportclassAppModule {}
193
171
```
194
172
195
-
With that option specified, every entity registered through the `forFeature()`
196
-
method will be automatically added to the entities array of the configuration
173
+
With that option specified, every entity registered through the `forFeature()`
174
+
method will be automatically added to the entities array of the configuration
197
175
object.
198
176
199
-
> info **info**Note that entities that aren't registered through the `forFeature()` method, but
200
-
> are only referenced from the entity (via a relationship), won't be included by
177
+
> info **info** Note that entities that aren't registered through the `forFeature()` method, but
178
+
> are only referenced from the entity (via a relationship), won't be included by
201
179
> way of the `autoLoadEntities` setting.
202
180
203
-
> info **info**Using `autoLoadEntities` also has no effect on the MikroORM CLI - for that we
181
+
> info **info** Using `autoLoadEntities` also has no effect on the MikroORM CLI - for that we
204
182
> still need CLI config with the full list of entities. On the other hand, we can
205
183
> use globs there, as the CLI won't go thru webpack.
206
184
207
185
#### Request scoped handlers in queues
208
186
209
-
> info **info**`@UseRequestContext()` decorator was added in v4.1.0
187
+
> info **info**`@UseRequestContext()` decorator was added in v4.1.0
210
188
211
-
As mentioned in the [docs](https://mikro-orm.io/docs/identity-map), we need a clean state for each request. That is handled automatically thanks to the `RequestContext` helper registered via middleware.
189
+
As mentioned in the [docs](https://mikro-orm.io/docs/identity-map), we need a clean state for each request. That is handled automatically thanks to the `RequestContext` helper registered via middleware.
212
190
213
191
But middlewares are executed only for regular HTTP request handles, what if we need
214
-
a request scoped method outside of that? One example of that is queue handlers or
215
-
scheduled tasks.
192
+
a request scoped method outside of that? One example of that is queue handlers or
193
+
scheduled tasks.
216
194
217
195
We can use the `@UseRequestContext()` decorator. It requires you to first inject the
218
-
`MikroORM` instance to current context, it will be then used to create the context
219
-
for you. Under the hood, the decorator will register new request context for your
220
-
method and execute it inside the context.
196
+
`MikroORM` instance to current context, it will be then used to create the context
197
+
for you. Under the hood, the decorator will register new request context for your
198
+
method and execute it inside the context.
221
199
222
200
```ts
223
201
@Injectable()
224
202
exportclassMyService {
225
-
226
-
constructor(privatereadonlyorm:MikroORM) { }
203
+
constructor(privatereadonlyorm:MikroORM) {}
227
204
228
205
@UseRequestContext()
229
206
async doSomething() {
230
207
// this will be executed in a separate context
231
208
}
232
-
233
209
}
234
210
```
235
211
@@ -281,4 +257,5 @@ export class PhotoModule {}
281
257
```
282
258
283
259
#### Example
260
+
284
261
A real world example of NestJS with MikroORM can be found [here](https://github.com/mikro-orm/nestjs-realworld-example-app)
<p>If you need to add some custom logic around the serialization of responses on the client side, you can use a custom class that extends the <code>ClientProxy</code> class or one of its child classes. For modifying successful requests you can override the <code>serializeResponse</code> method, and for modifying any errors that go through this client you can override the <code>serializeError</code> method. To make use of this custom class, you can pass the class itself to the <code>ClientsModule.register()</code> method using the <code>customClass</code> property. Below is an example of a custom <code>ClientProxy</code> that serializes each error into an <code>RpcException</code>.</p>
info "><strong>hint</strong> This is the class itself being passed to <code>customClass</code>, not an instance of the class. Nest will create the instance under the hood for you, and will pass any options given to the <code>options</code> property to the new <code>ClientProxy</code>.
0 commit comments