Hi, this is more a proposition to simplify of what's already working as a quick fix in LB4. With loopback 3 we could select the db configuration with the file name :
example :
dbName.production.js // for NODE_ENV=PRODUCTION
dbName.js // for NODE_ENV ignoring (local development)
This could be interesting to do something similar with loopback 4 later. Anyway it's more to propose something if someone is looking for a quick fix solution for now.
Here is the quick-fix : the goal is to detect if the NODE_ENV equals 'PRODUCTION' (or whatever) and override the db configuration thanks to the DbDataSource constructor :
const dataSourceConfigProd = {
name: 'db',
connector: 'postgresql',
url: process.env.DATABASE_URL
}
const dbDataSource = new DbDataSource(dataSourceConfigProd);
this.bind('datasources.db').to(dbDataSource);
dataSourceConfigProd is your db production configuration, can work with anything (connector mysql, mongodb, etc... , host, port, password, etc...). (make sure to install the good connector)
in application.ts
import {BootMixin} from '@loopback/boot';
import {ApplicationConfig} from '@loopback/core';
import {RepositoryMixin} from '@loopback/repository';
import {RestApplication} from '@loopback/rest';
import {ServiceMixin} from '@loopback/service-proxy';
import {DbDataSource} from './datasources/db.datasource'; // import DbDataSource
export class Application extends BootMixin(
ServiceMixin(RepositoryMixin(RestApplication)),
) {
constructor(options: ApplicationConfig = {}) {
super(options);
// HERE IS START OF THE BLOCK TO ADD
if(process.env.NODE_ENV === 'PRODUCTION') {
const dbDataSource = new DbDataSource({
name: 'db',
connector: 'postgresql',
url: process.env.DATABASE_URL
});
this.bind('datasources.db').to(dbDataSource);
}
// HERE IS END OF THE BLOCK TO ADD
// Set up the custom sequence
this.sequence(MySequence);
this.projectRoot = __dirname;
// Customize @loopback/boot Booter Conventions here
this.bootOptions = {
controllers: {
// Customize ControllerBooter Conventions here
dirs: ['controllers'],
extensions: ['.controller.js'],
nested: true,
}
};
}
}
So, this works for now
Later, just change the json names with db.json and db.production.json for example, like in LB3
Regards.
I put back my working solution :
// src/datasources/db.datasource.ts
import {inject} from '@loopback/core';
import {juggler} from '@loopback/repository';
import * as devConfig from './app.datasource.json'; // import dev json
import * as prodConfig from './app.ds.production.json'; // import prod json
export class DataSourceSettings{
name: string
connector: string
url?: string
file?: string
};
let config: DataSourceSettings;
if( process.env.NODE_ENV === 'PRODUCTION') {
console.log(' --- Database in Prod Mode --- ')
config = prodConfig;
config.url = process.env.DATABASE_URL; // can add properties from environment var at start.
console.log(config);
} else {
console.log(' --- Database in Dev Mode --- ')
config = devConfig;
console.log(config);
}
export class AppDataSource extends juggler.DataSource {
static dataSourceName = 'db';
constructor(
@inject('ds.config.db', {optional: true}) dsConfig: object = config,
) {
// console.log(dsConfig);
super(dsConfig);
}
}
dev datasource JSON
{
"name": "db",
"connector": "memory",
"file": "./data/db.json"
}
prod datasource JSON
{
"name": "db",
"connector": "postgresql",
"url": ""
}
I would like to propose a different solution, see https://github.com/strongloop/loopback-next/issues/2556
@bajtos I'm ok with your solution. This issue can be closed
Most helpful comment
I put back my working solution :
dev datasource JSON
prod datasource JSON