1 | # @loopback/repository
|
2 |
|
3 | This module provides a common set of interfaces for interacting with databases.
|
4 |
|
5 | ## Overview
|
6 |
|
7 | This module provides data access facilities to various databases and services as
|
8 | well as the constructs for modeling and accessing those data.
|
9 |
|
10 | ## Installation
|
11 |
|
12 | ```sh
|
13 | npm install --save @loopback/repository
|
14 | ```
|
15 |
|
16 | ## Basic use
|
17 |
|
18 | At the moment, we only have implementations of `Repository` based on LoopBack
|
19 | 3.x `loopback-datasource-juggler` and connectors. The following steps illustrate
|
20 | how to define repositories and use them with controllers.
|
21 |
|
22 | ### Defining a legacy datasource and a model
|
23 |
|
24 | The repository module provides APIs to define LoopBack 3.x data sources and
|
25 | models. For example,
|
26 |
|
27 | ```ts
|
28 | // src/datasources/db.datasource.ts
|
29 | import {juggler} from '@loopback/repository';
|
30 |
|
31 | export const db: juggler.DataSource = new juggler.DataSource({
|
32 | name: 'db',
|
33 | connector: 'memory',
|
34 | });
|
35 | ```
|
36 |
|
37 | ```ts
|
38 | // src/models/note.model.ts
|
39 | import {model, Entity, property} from '@loopback/repository';
|
40 |
|
41 | @model()
|
42 | export class Note extends Entity {
|
43 | @property({id: true})
|
44 | id: string;
|
45 | @property()
|
46 | title: string;
|
47 | @property()
|
48 | content: string;
|
49 | }
|
50 |
|
51 | export interface NoteRelations {
|
52 | // describe navigational properties here
|
53 | }
|
54 |
|
55 | export type NoteWithRelations = Note & NoteRelations;
|
56 | ```
|
57 |
|
58 | **NOTE**: There is no declarative support for data source and model yet in
|
59 | LoopBack 4. These constructs need to be created programmatically as illustrated
|
60 | above.
|
61 |
|
62 | ### Defining a repository
|
63 |
|
64 | A repository can be created by extending `DefaultCrudRepository` and using
|
65 | dependency injection to resolve the datasource.
|
66 |
|
67 | ```ts
|
68 | // src/repositories/note.repository.ts
|
69 | import {DefaultCrudRepository, DataSourceType} from '@loopback/repository';
|
70 | import {Note, NoteRelations} from '../models';
|
71 | import {inject} from '@loopback/core';
|
72 |
|
73 | export class NoteRepository extends DefaultCrudRepository<
|
74 | Note,
|
75 | typeof Note.prototype.id,
|
76 | NoteRelations
|
77 | > {
|
78 | constructor(@inject('datasources.db') protected dataSource: DataSourceType) {
|
79 | super(Note, dataSource);
|
80 | }
|
81 | }
|
82 | ```
|
83 |
|
84 | ### Defining a controller
|
85 |
|
86 | Controllers serve as handlers for API requests. We declare controllers as
|
87 | classes with optional dependency injection by decorating constructor parameters
|
88 | or properties.
|
89 |
|
90 | ```ts
|
91 | // src/controllers/note.controller.ts
|
92 | import {repository} from '@loopback/repository';
|
93 | import {NoteRepository} from '../repositories';
|
94 | import {Note} from '../models';
|
95 | import {post, requestBody, get, param} from '@loopback/rest';
|
96 |
|
97 | export class NoteController {
|
98 | constructor(
|
99 | // Use constructor dependency injection to set up the repository
|
100 | @repository(NoteRepository) public noteRepo: NoteRepository,
|
101 | ) {}
|
102 |
|
103 | // Create a new note
|
104 | @post('/note')
|
105 | create(@requestBody() data: Note) {
|
106 | return this.noteRepo.create(data);
|
107 | }
|
108 |
|
109 | // Find notes by title
|
110 | @get('/note/{title}')
|
111 | findByTitle(@param.path.string('title') title: string) {
|
112 | return this.noteRepo.find({where: {title}});
|
113 | }
|
114 | }
|
115 | ```
|
116 |
|
117 | ### Run the controller and repository together
|
118 |
|
119 | #### Using the Repository Mixin for Application
|
120 |
|
121 | A Repository Mixin is available for Application that provides convenience
|
122 | methods for binding and instantiating a repository class. Bound instances can be
|
123 | used anywhere in your application using Dependency Injection. The
|
124 | `.repository(RepositoryClass)` function can be used to bind a repository class
|
125 | to an Application. The mixin will also instantiate any repositories declared by
|
126 | a component in its constructor using the `repositories` key.
|
127 |
|
128 | Repositories will be bound to the key `repositories.RepositoryClass` where
|
129 | `RepositoryClass` is the name of the Repository class being bound.
|
130 |
|
131 | We'll use `BootMixin` on top of `RepositoryMixin` so that Repository bindings
|
132 | can be taken care of automatically at boot time before the application starts.
|
133 |
|
134 | ```ts
|
135 | import {BootMixin} from '@loopback/boot';
|
136 | import {ApplicationConfig} from '@loopback/core';
|
137 | import {RepositoryMixin} from '@loopback/repository';
|
138 | import {RestApplication} from '@loopback/rest';
|
139 | import {db} from './datasources/db.datasource';
|
140 |
|
141 | export class RepoApplication extends BootMixin(
|
142 | RepositoryMixin(RestApplication),
|
143 | ) {
|
144 | constructor(options?: ApplicationConfig) {
|
145 | super(options);
|
146 | this.projectRoot = __dirname;
|
147 | this.dataSource(db);
|
148 | }
|
149 | }
|
150 | ```
|
151 |
|
152 | ## Related resources
|
153 |
|
154 | - <https://martinfowler.com/eaaCatalog/repository.html>
|
155 | - <https://msdn.microsoft.com/en-us/library/ff649690.aspx>
|
156 | - <http://docs.spring.io/spring-data/data-commons/docs/2.0.0.M3/reference/html/#repositories>
|
157 |
|
158 | ## Contributions
|
159 |
|
160 | - [Guidelines](https://github.com/loopbackio/loopback-next/blob/master/docs/CONTRIBUTING.md)
|
161 | - [Join the team](https://github.com/loopbackio/loopback-next/issues/110)
|
162 |
|
163 | ## Tests
|
164 |
|
165 | Run `npm test` from the root folder.
|
166 |
|
167 | ## Contributors
|
168 |
|
169 | See
|
170 | [all contributors](https://github.com/loopbackio/loopback-next/graphs/contributors).
|
171 |
|
172 | ## License
|
173 |
|
174 | MIT
|