diff --git a/packages/boot/src/__tests__/acceptance/crud-rest-builder.acceptance.ts b/packages/boot/src/__tests__/acceptance/crud-rest-builder.acceptance.ts index 5a530272dce6..00ee00e7d572 100644 --- a/packages/boot/src/__tests__/acceptance/crud-rest-builder.acceptance.ts +++ b/packages/boot/src/__tests__/acceptance/crud-rest-builder.acceptance.ts @@ -6,10 +6,14 @@ import {ApplicationConfig} from '@loopback/core'; import {juggler, RepositoryMixin} from '@loopback/repository'; import {RestApplication} from '@loopback/rest'; -import {CrudRestComponent} from '@loopback/rest-crud'; +import { + CrudRestComponent, + defineCrudRepositoryClass, +} from '@loopback/rest-crud'; import {expect, givenHttpServerConfig, TestSandbox} from '@loopback/testlab'; import {resolve} from 'path'; import {BootMixin, ModelApiBooter} from '../..'; +import {Product} from '../fixtures/product.model'; describe('CRUD rest builder acceptance tests', () => { let app: BooterApp; @@ -53,6 +57,42 @@ module.exports = { ); }); + it('uses bound repository class if it exists', async () => { + await sandbox.copyFile( + resolve(__dirname, '../fixtures/product.model.js'), + 'models/product.model.js', + ); + + await sandbox.writeTextFile( + 'model-endpoints/product.rest-config.js', + ` +const {Product} = require('../models/product.model'); +module.exports = { + model: Product, + pattern: 'CrudRest', + dataSource: 'db', + basePath: '/products', +}; + `, + ); + + const ProductRepository = defineCrudRepositoryClass(Product); + app.repository(ProductRepository); + + const binding = app.getBinding('repositories.ProductRepository'); + expect(binding.key).to.eql('repositories.ProductRepository'); + + // Boot & start the application + await app.boot(); + await app.start(); + + expect(app.getBinding('repositories.ProductRepository')).to.eql(binding); + + expect(app.getBinding('controllers.ProductController').key).to.eql( + 'controllers.ProductController', + ); + }); + it('throws if there is no base path in the config', async () => { await sandbox.copyFile( resolve(__dirname, '../fixtures/product.model.js'), diff --git a/packages/rest-crud/src/crud-rest-builder.plugin.ts b/packages/rest-crud/src/crud-rest-builder.plugin.ts index 301618ee974d..79bd45eaaa2d 100644 --- a/packages/rest-crud/src/crud-rest-builder.plugin.ts +++ b/packages/rest-crud/src/crud-rest-builder.plugin.ts @@ -50,11 +50,22 @@ export class CrudRestApiBuilder implements ModelApiBuilder { } const entityClass = modelClass as typeof Entity & {prototype: Entity}; - // TODO Check if the repository class has been already defined. - // If yes, then skip creation of the default repository - const repositoryClass = setupCrudRepository(entityClass, config); - application.repository(repositoryClass); - debug('Registered repository class', repositoryClass.name); + let repoClassName = entityClass.name + 'Repository'; + + try { + application.getBinding('repositories.' + repoClassName); + debug( + 'Using repository class', + repoClassName, + ', as it is already bound to application', + ); + } catch { + // repository class does not exist + const repositoryClass = setupCrudRepository(entityClass, config); + application.repository(repositoryClass); + repoClassName = repositoryClass.name; + debug('Registered repository class', repoClassName); + } const controllerClass = setupCrudRestController(entityClass, config); application.controller(controllerClass);