Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move datasource config from JSON to TS files #5000

Merged
merged 2 commits into from
Apr 24, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion docs/site/Appsody-LoopBack.md
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,6 @@ Model Todo was created in src/models/
? Select the connector for db: In-memory db (supported by StrongLoop)
? window.localStorage key to use for persistence (browser only):
? Full path to file for persistence (server only): ./data/db.json
create src/datasources/db.datasource.config.json
create src/datasources/db.datasource.ts
update src/datasources/index.ts

Expand Down
88 changes: 43 additions & 45 deletions docs/site/Calling-other-APIs-and-Web-Services.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,31 +53,31 @@ servicMethodName: {
```

If you have more than one operations to map, it might be easier to edit the
DataSource JSON after it's been created. See below for the example of the
mapping of the WSDL binding operations and Node.js methods.
DataSource configuration after it's been created. See below for the example of
the mapping of the WSDL binding operations and Node.js methods.

```json
{
"name": "ds",
"connector": "soap",
"url": "http://calculator-webservice.mybluemix.net/calculator",
"wsdl": "http://calculator-webservice.mybluemix.net/calculator?wsdl",
"remotingEnabled": true,
```ts
const config = {
name: 'ds',
connector: 'soap',
url: 'http://calculator-webservice.mybluemix.net/calculator',
wsdl: 'http://calculator-webservice.mybluemix.net/calculator?wsdl',
remotingEnabled: true,
// ADD THIS SNIPPET
"operations": {
"add": {
"service": "CalculatorService", //WSDL service name
"port": "CalculatorPort", //WSDL port name
"operation": "add" //WSDL operation name
operations: {
add: {
service: 'CalculatorService', //WSDL service name
port: 'CalculatorPort', //WSDL port name
operation: 'add', //WSDL operation name
},
"subtract": {
"service": "CalculatorService",
"port": "CalculatorPort",
"operation": "subtract"
}
}
subtract: {
service: 'CalculatorService',
port: 'CalculatorPort',
operation: 'subtract',
},
},
// END OF THE SNIPPET
}
};
```

For details, you can refer to the SOAP connector's operations property:
Expand All @@ -98,7 +98,6 @@ petstore.json
? Validate spec against Swagger spec 2.0?: No
? Security config for making authenticated requests to API:
? Use positional parameters instead of named parameters?: No
create src/datasources/ds.datasource.config.json
create src/datasources/ds.datasource.ts
```

Expand Down Expand Up @@ -127,8 +126,7 @@ $ lb4 datasource
? Use default CRUD mapping: No
```

The next step is to edit the DataSource JSON file for `options` and
`operations`.
The next step is to edit the DataSource file for `options` and `operations`.

The REST connector uses the
[request module](https://www.npmjs.com/package/request) as the HTTP client. You
Expand All @@ -139,30 +137,30 @@ The `template` object specifies the REST API invocation as a JSON template. You
can find more details in the
[Defining a custom method using a template page](https://loopback.io/doc/en/lb4/REST-connector.html#defining-a-custom-method-using-a-template).

```json
{
"name": "restds",
"connector": "rest",
"baseURL": "https://swapi.co/api/",
"crud": false,
"options": {
"headers": {
"accept": "application/json",
"content-type": "application/json"
}
```ts
const config = {
name: 'restds',
connector: 'rest',
baseURL: 'https://swapi.co/api/',
crud: false,
options: {
headers: {
accept: 'application/json',
'content-type': 'application/json',
},
},
"operations": [
operations: [
{
"template": {
"method": "GET",
"url": "https://swapi.co/api/people/{personId}"
template: {
method: 'GET',
url: 'https://swapi.co/api/people/{personId}',
},
"functions": {
"getCharacter": ["personId"]
}
}
]
}
functions: {
getCharacter: ['personId'],
},
},
],
};
```

## Add a service
Expand Down
95 changes: 91 additions & 4 deletions docs/site/DataSource-generator.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,97 @@ Once all the prompts have been answered, the CLI will do the following:

- Install `@loopback/repository` and the connector package (if it's not a custom
connector).
- Create a file with the connector configuration as follows:
`/src/datasources/${dataSource.dataSourceName}.datasource.config.json`
- Create a DataSource class which recieves the connector config using
- Create a DataSource class which receives the connector config using
[Dependency Injection](Dependency-injection.md) as follows:
`/src/datasources/${dataSource.dataSourceName}.datasource.ts`
`/src/datasources/${dataSourceName}.datasource.ts`. The connector
configuration provided via CLI is available via static property
`defaultConfig`.
- Update `/src/datasources/index.ts` to export the newly created DataSource
class.

### Legacy JSON-based configuration

Datasources created by a CLI version from before April 2020 are using JSON-based
file convention for defining datasources:

- `/src/datasources/${dataSourceName}.datasource.config.json` contains
datasource configuration in JSON format, e.g. the connector name, target host
& port, credentials, and so on.
- `/src/datasources/${dataSourceName}.datasource.ts` defines a datasource class,
the default configuration is loaded from the JSON file.

CLI commands like `lb4 repository` and `lb4 service` support both the old
(JSON-based) and the current (pure TypeScript) styles, there are no changes
immediately needed to make your existing project work with the recent CLI
versions.

However, we recommend to eventually migrate existing datasource files to the new
style.

#### Migration guide

1. Open `{dataSourceName}.datasource.ts` file and replace import of `config`
from the JSON file with the actual content of the JSON file.

For example:

```diff
-import config from './db.datasource.config.json';
+
+const config = {
+ "name": "db",
+ "connector": "memory",
+ "localStorage": "",
+ "file": "./data/db.json",
+};
```

2. Save the file, run Prettier to fix the coding style (change double-quotes `"`
to single-quotes `'`, remove quotes from property names like `connector` and
`file`).

Example output using LoopBack's coding style:

```ts
const config = {
name: 'db',
connector: 'memory',
localStorage: '',
file: './data/db.json',
};
```

3. Add a static `defaultConfig` property to your datasource class.

For example:

```diff
export class DbDataSource extends juggler.DataSource {
static dataSourceName = 'db';
+ static readonly defaultConfig = config;

constructor(
```

4. Modify the tests importing the default datasource configuration from the JSON
file, get the default configuration via the new static property instead.

This is typically needed by tests for service proxies, which are are working
with a datasource connected to a web service. Datasources connected to a
database usually don't need different configuration for tests.

For example:

```diff
-import GEO_CODER_CONFIG from '../datasources/geocoder.datasource.config.json';
+import {GeocoderDataSource} from '../datasources/geocoder.datasource';
nabdelgadir marked this conversation as resolved.
Show resolved Hide resolved

//...

export function getProxiedGeoCoderConfig(proxy: HttpCachingProxy) {
- return merge({}, GEO_CODER_CONFIG, {
+ return merge({}, GeocoderDataSource.defaultConfig, {
options: {
```

5. Delete the datasource JSON file, it's no longer needed.
20 changes: 11 additions & 9 deletions docs/site/DataSources.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,27 +20,29 @@ It is recommended to use the [`lb4 datasource` command](DataSource-generator.md)
provided by the CLI to generate a DataSource. The CLI will prompt for all
necessary connector information and create the following files:

- `${dataSource.dataSourceName}.datasource.config.json` containing the connector
configuration
- `${dataSource.dataSourceName}.datasource.ts` containing a class extending
`juggler.DataSource`. This class can be used to override the default
DataSource behaviour programaticaly. Note: The connector configuration stored
in the `.json` file is injected into this class using
[Dependency Injection](Dependency-injection.md).
DataSource behavior programmatically. Note: The connector configuration is
available in a static property `defaultConfig` and can be injected into the
class constructor using [Dependency Injection](Dependency-injection.md).

Both the above files are generated in `src/datasources/` directory by the CLI.
It will also update `src/datasources/index.ts` to export the new DataSource
class.
The above file is generated in `src/datasources/` directory by the CLI. CLI will
also update `src/datasources/index.ts` to export the new DataSource class.

Example DataSource Class:

```ts
import {inject} from '@loopback/core';
import {juggler} from '@loopback/repository';
import config from './db.datasource.config.json';

const config = {
name: 'db',
connector: 'memory',
};

export class DbDataSource extends juggler.DataSource {
static dataSourceName = 'db';
static readonly defaultConfig = config;

constructor(
@inject('datasources.config.db', {optional: true})
Expand Down
23 changes: 9 additions & 14 deletions docs/site/OpenAPI-generator.md
Original file line number Diff line number Diff line change
Expand Up @@ -397,19 +397,6 @@ export class AccountController {
If `--client` is specified, a datasource is generated to configure the
connection to the endpoint that exposes an OpenAPI spec.

{% include code-caption.html content="src/datasources/test2.datasource.config.json"
%}

```json
{
"name": "test2",
"connector": "openapi",
"spec": "customer.yaml",
"validate": false,
"positional": true
}
```

{% include code-caption.html content="src/datasources/test2.datasource.ts"
%}

Expand All @@ -421,12 +408,20 @@ import {
ValueOrPromise,
} from '@loopback/core';
import {juggler} from '@loopback/repository';
import config from './test2.datasource.config.json';

const config = {
name: 'test2',
connector: 'openapi',
spec: 'customer.yaml',
validate: false,
positional: true,
};

@lifeCycleObserver('datasource')
export class Test2DataSource extends juggler.DataSource
implements LifeCycleObserver {
static dataSourceName = 'test2';
static readonly defaultConfig = config;

constructor(
@inject('datasources.config.test2', {optional: true})
Expand Down
Loading