Repository

In this guide, we'll go through the steps to create a new repository in your SoapJS project. You can create repositories using CLI commands, interactive forms, or by defining them in a JSON file.

In this example, the CustomerRepository is an abstraction layer for accessing customer data. The concrete implementation, CustomerRepositoryImpl, utilizes a MongoDB context defined by the DataContext type. This context includes the collection source, the mapper from entities to MongoDB models, and a query factory for creating database queries.

// Example repository abstract class (or interface)
export abstract class CustomerRepository<Customer> extends Repository {
  static Token = "CustomerRepository";
  // place for additional methods ...
}

// Example repository implementation
export class CustomerRepositoryImpl<Customer> extends RepositoryImpl implements CustomerRepository {
  constructor(
    mongoContext: DataContext<Customer, CustomerMongoModel>,
    // feel free to add more contexts if you need
  ) {
    super(mongoContext);
  }
  // place for additional methods ...
}

In SoapJS projects, repositories play a crucial role in abstracting the data access layer. They provide a clean separation between the application's business logic and data access mechanisms. When using Inversion of Control (IoC) containers, such as InversifyJS, repositories can be integrated seamlessly into your application's dependency injection framework.

It's important to note that creating a separate implementation class for your repository, such as CustomerRepositoryImpl, is not always necessary. If you do not require additional methods beyond those provided by the base Repository class, or if you are only interacting with a single database type, you can directly use a generic repository implementation RepositoryImpl.

Below is an example of how a CustomerRepository is added to the Dependencies class, which acts as the configurator for our application's dependencies. This step is essential if you've chosen an IoC option in your project configuration.

export class Dependencies {
  public async configure() {
    // rest of the components ...
    // connect mongo etc.
    const context = {
      collection: new MongoCollection<CustomerMongoModel>(mongoClient, 'customers'), 
      // OR
      // collection: new CustomerMongoCollection(mongoClient), 
      mapper: new CustomerMongoMapper(),
      queries: new MongoQueryFactory()
    }
    const impl = new CustomerRepositoryImpl(context);
    // OR
    // const impl = new RepositoryImpl(context)
    container
      .bind<CustomerRepository>(CustomerRepository.Token)
      .toContantValue(impl);
  }
}

Creating new repository

Using CLI Command with options

To create a new repository directly via the CLI, use the following command:

soap new repository -n "Customer" -e "shop" -t "Customer" -m "Customer" -s "mongo" -w -f

Options explained:

  • -n: Name of the repository (e.g., "Customer").

  • -e: Endpoint associated with the entity (e.g., "shop").

  • -t: Name the entity associated with the repository. If not set uses repository name.

  • -m: Name the model associated with the repository. If not set uses repository name.

  • -s: Storage type(s) (e.g., mongo), separated by commas.

  • -c: Generate custom collection implementation

  • -i: Generate custom repository implementation

  • --no-tests: Skip test generation.

  • --no-rel: Skip generating related files. You can also specify specific groups.

  • --force: Force the creation, overwrite files if necessary.

  • --patch: Add content to the files if they exists.

  • --help: display help for command

Using Interactive Form

If you prefer to use an interactive form to specify your repository details, simply run:

soap new repository -w -f

Follow the prompts to enter your repository's details.

Using JSON Configuration

Alternatively, you can define your repositories in a JSON file. Here is an example structure:

{
  "repositories": [
    {
      "name": "Customer",
      "endpoint": "shop",
      "methods": [],
      "entity": "Customer", // (optional) if not set will use name of the repository
      "contexts": [ 
        {
          "type": "mongo",
          "collection": { // (optional) if not set will use name of the repository and default table name based on repository name
            "name": "Customer",
            "table": "customer.collection"
          },
          "mapper": "Customer", // (optional) if not set will use name of the repository
          "model": "Customer" // (optional) if not set will use name of the repository
        }
      ]
      /*
      OR
      "contexts": ["mongo"],
      */
    }
  ]
}

In the JSON structure, you can use strings with database aliases instead of objects in contexts

Save this to a file, for example api.json, and run:

soap new --json "./path/to/api.json" -w -f

Options:

  • --json: Path to your JSON configuration file.

  • -w: Generate with dependencies included.

  • -f: Force the creation, overwrite files if necessary.

File Structure

After creating your repository, your file structure (assuming default configuration settings) should look like this:

src/
  - shop/
    - data/
      - dtos/
        - customer.dtos.ts
        - index.ts
      - collections/
        - customer.mongo.collection.ts
        - index.ts
      - mapper/
        - customer.mongo.mapper.ts
        - index.ts
      - repositories/
        - customer.repository-impl.ts
        - index.ts
    - domain/
      - repositories/
        - customer.repository.ts
        - index.ts
      - entities/
        - customer.ts
        - index.ts
...

Last updated