diff --git a/packages/repository/README.md b/packages/repository/README.md index 7ef0994ea6b8..cbe058abe3ce 100644 --- a/packages/repository/README.md +++ b/packages/repository/README.md @@ -153,6 +153,161 @@ export class RepoApplication extends BootMixin( } ``` +## Concepts + +### Repository + +`Repository` represents a specialized `Service` interface that provides +strong-typed data access (for example, CRUD) operations of a domain model +against the underlying database or service. + +`Repository` can be defined and implemented by application developers. LoopBack +ships a few predefined `Repository` interfaces for typical CRUD and KV +operations. These `Repository` implementations leverage `Model` definition and +`Datasource` configuration to fulfill the logic for data access. + +```js +interface Repository {} + +interface CustomerRepository extends Repository { + find(filter?: Filter, options?: Options): Promise; + findByEmail(email: string): Promise; + // ... +} +``` + +See more examples at: +- [Repository/CrudRepository/EntityRepository](src/repository.ts) +- [KVRepository](src/kv-repository.ts) + +### Model + +A model describes business domain objects, for example, `Customer`, `Address`, +and `Order`. It usually defines a list of properties with name, type, and other +constraints. + +Models can be used for data exchange on the wire or between different systems. +For example, a JSON object conforming to the `Customer` model definition can be +passed in REST/HTTP payload to create a new customer or stored in a document +database such as MongoDB. Model definitions can also be mapped to other forms, +such as relational database schema, XML schema, JSON schema, OpenAPI schema, or +gRPC message definition, and vice versa. + +There are two subtly different types of models for domain objects: + +- Value Object: A domain object that does not have an identity (ID). Its + equality is based on the structural value. For example, `Address` can be + modeled as `Value Object` as two US addresses are equal if they have the same + street number, street name, city, and zip code values. For example: + ```json + { + "name": "Address", + "properties": { + "streetNum": "string", + "streetName": "string", + "city": "string", + "zipCode": "string" + } + } + ``` + +- Entity: A domain object that has an identity (ID). Its equality is based on + the identity. For example, `Customer` can be modeled as `Entity` as each + customer should have a unique customer id. Two instances of `Customer` with + the same customer id are equal since they refer to the same customer. For + example: + ```json + { + "name": "Customer", + "properties": { + "id": "string", + "lastName": "string", + "firstName": "string", + "email": "string", + "address": "Address" + } + } + ``` + +### Datasource + +`Datasource` is a named configuration of a connector. The configuration +properties vary by connectors. For example, a datasource for `MySQL` needs to +set the `connector` property to `loopback-connector-mysql` with settings as +follows: + +```json +{ + "host": "localhost", + "port": 3306, + "user": "my-user", + "password": "my-password", + "database": "demo" +} +``` + +When a `Datasource` is instantiated, the configuration properties will be used +to initialize the connector to connect to the backend system. + +### Connector + +`Connector` is a provider that implements data access or api calls with a +specific backend system, such as a database, a REST service, a SOAP Web Service, +or a gRPC micro-service. It abstracts such interactions as a list of operations +in the form of Node.js methods. + +Typically, a connector translates LoopBack query +and mutation requests into native api calls supported by the underlying Node.js +driver for the given backend. For example, a connector for `MySQL` will map +`create` method to SQL INSERT statement, which can be executed through MySQL +driver for Node.js. + +### Mixin + +`Mixin` is a way of building up classes from reusable components by combining +simpler partial classes, which can be modeled as `Mixin`. + +For example, the mixins belows add methods and properties to a base class to +create a new one. + +```ts +import {Class} from '@loopback/repository'; + +// Mixin as a function +function timestampMixin>(Base: T) { + return class extends Base { + created: Date = new Date(); + modified: Date = new Date(); + }; +} + +// The base class +class Customer { + id: string; + lastName: string; + firstName: string; +} + +// Mix in timestamp +const CustomerWithTS = timestampMixin(Customer); +``` + +### Type + +To support property and parameter typing, LoopBack 4 introduces an extensible +typing system to capture the metadata and perform corresponding checks and +coercion. The following types are supported out of box. + +- StringType +- BooleanType +- NumberType +- DateType +- BufferType +- AnyType +- ArrayType +- UnionType +- ObjectType + ## Related resources - https://martinfowler.com/eaaCatalog/repository.html @@ -161,7 +316,7 @@ export class RepoApplication extends BootMixin( ## Contributions -- [Guidelines](https://github.com/strongloop/loopback-next/blob/master/docs/DEVELOPING.md) +- [Guidelines](https://github.com/strongloop/loopback-next/blob/master/docs/site/DEVELOPING.md) - [Join the team](https://github.com/strongloop/loopback-next/issues/110) ## Tests