From 33df731479123bc49dfdbdb42c822dc37d6a2cae Mon Sep 17 00:00:00 2001 From: Agnes Lin Date: Tue, 16 Jun 2020 10:44:11 -0400 Subject: [PATCH] docs: add Oracle connector tut for lb4 --- .../tutorials/connectors/Mongodb-tutorial.md | 2 +- .../tutorials/connectors/Mysql-tutorial.md | 4 +- .../tutorials/connectors/Oracle-tutorial.md | 319 ++++++++++++++++++ .../connectors/Postgresql-tutorial.md | 4 +- 4 files changed, 324 insertions(+), 5 deletions(-) create mode 100644 docs/site/tutorials/connectors/Oracle-tutorial.md diff --git a/docs/site/tutorials/connectors/Mongodb-tutorial.md b/docs/site/tutorials/connectors/Mongodb-tutorial.md index 1d8a4a9f62e6..da3f1eab63ef 100644 --- a/docs/site/tutorials/connectors/Mongodb-tutorial.md +++ b/docs/site/tutorials/connectors/Mongodb-tutorial.md @@ -1,6 +1,6 @@ --- lang: en -title: 'MongoDB connector tutorial' +title: 'MongoDB Connector Tutorial' keywords: LoopBack 4.0, LoopBack 4, Node.js, TypeScript, OpenAPI, Connector, MongoDB, Tutorial diff --git a/docs/site/tutorials/connectors/Mysql-tutorial.md b/docs/site/tutorials/connectors/Mysql-tutorial.md index 4b28928883cd..60f842ecaf74 100644 --- a/docs/site/tutorials/connectors/Mysql-tutorial.md +++ b/docs/site/tutorials/connectors/Mysql-tutorial.md @@ -1,6 +1,6 @@ --- lang: en -title: 'MySQL connector tutorial' +title: 'MySQL Connector Tutorial' keywords: LoopBack 4.0, LoopBack 4, Node.js, TypeScript, OpenAPI, Connector, MySQL, Tutorial @@ -260,7 +260,7 @@ details: export class User extends Entity { @property({ type: 'number', - required: true, + required: true, // set this to false if the value is auto-generated by the db precision: 10, scale: 0, id: 1, diff --git a/docs/site/tutorials/connectors/Oracle-tutorial.md b/docs/site/tutorials/connectors/Oracle-tutorial.md new file mode 100644 index 000000000000..a969148c9db8 --- /dev/null +++ b/docs/site/tutorials/connectors/Oracle-tutorial.md @@ -0,0 +1,319 @@ +--- +lang: en +title: 'Oracle Connector Tutorial' +keywords: + LoopBack 4.0, LoopBack 4, Node.js, TypeScript, OpenAPI, Connector, Oracle, + Tutorial +sidebar: lb4_sidebar +permalink: /doc/en/lb4/Connecting-to-Oracle.html +--- + +# Connecting to Oracle + +The following tutorial introduces how to set up Oracle as the data source of +LoopBack 4 applications with +[LoopBack Oracle connector](https://github.com/strongloop/loopback-connector-oracle). + +## Prerequisites + +Before starting this tutorial, make sure you have the following installed: + +- Node.js version 10 or higher +- LoopBack 4 CLI; see + [Getting Started with LoopBack 4](../../Getting-started.md) + +## Tutorial - Oracle + +### 1. Create a new LoopBack 4 app + +Let's use the [LB4 CLI](../../Command-line-interface.md) `lb4 app` to create a +LoopBack 4 application called `MyApp`: + +```bash +$ lb4 app +? Project name: my-app +? Project description: Oracle connector tutorial +? Project root directory: my-app +? Application class name: MyAppApplication +? Select features to enable in the project (Press to select, to togg +le all, to invert selection) +❯◉ Enable eslint: add a linter with pre-configured lint rules + ◉ Enable prettier: install prettier to format code conforming to rules + ◉ Enable mocha: install mocha to run tests + ◉ Enable loopbackBuild: use @loopback/build helpers (e.g. lb-eslint) + ◉ Enable vscode: add VSCode config files + ◉ Enable docker: include Dockerfile and .dockerignore + ◉ Enable repositories: include repository imports and RepositoryMixin +(Move up and down to reveal more choices) +``` + +### 2. Create models + +Let's create a simple model `User`. To keep the tutorial short, the prompts of +`lb4 model` are skipped: + +{% include code-caption.html content="user.model.ts" %} + +```ts +// imports +@model() +export class User extends Entity { + @property({ + type: 'number', + id: true, + generated: true, + }) + id: number; + + @property({ + type: 'string', + }) + name?: string; + + @property({ + type: 'boolean', + }) + hasAccount: boolean; + + constructor(data?: Partial) { + super(data); + } +} +``` + +### 3. Create a data source + +LoopBack allows you to connect to your Oracle database via different methods: +[Easy connect with host/port/database, TNS, and LDAP](https://loopback.io/doc/en/lb4/Oracle-connector.html#connector-properties). +Let's create a DataSource `db` using the Oracle connector with Easy connect +method by the prompts below: + +```bash +$ lb4 datasource +? Datasource name: db +? Select the connector for db: + ... + PostgreSQL (supported by StrongLoop) +❯ Oracle (supported by StrongLoop) + Microsoft SQL (supported by StrongLoop) + ... +? Connection String tns (eg: DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=MY_HOST)(P +ORT=MY_PORT))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=MY_DB))): +? host: localhost +? port: 1521 +? user: loopback +? password: [hidden] // example password: pa55w0rd +? database: xe + +Datasource Db was created in src/datasources/ +``` + +Under `src/datasources/db.datasource.ts`, we can find the `DbDataSource` class +and the config we just set: + +```ts +const config = { + name: 'db', + connector: 'oracle', + tns: '', + host: 'localhost', + port: 1521, + user: 'loopback', + password: 'pa55w0rd', + database: 'xe', +}; +``` + +The DataSource would then connect to your back-end service(Oracle) with the +config when the app starts. + +### 4. Create repositories + +A [Repository](../../Repository.md) is an artifact that ties the model and the +datasource. We will need to create the repository for the `User` class to access +the database. The steps of creating `UserRepository` by running `lb4 repository` +are skipped here: + +{% include code-caption.html content="user.repository.ts" %} + +```ts +// imports +export class UserRepository extends DefaultCrudRepository< + User, + typeof User.prototype.id, + UserRelations +> { + constructor(@inject('datasources.db') dataSource: DbDataSource) { + super(User, dataSource); + } +} +``` + +### 5. Database migration + +LoopBack provides a convenient way to create schemas/tables for our models if we +don't have corresponding schemas defined in the relational database. Once we +created the above artifacts, run the following commands: + +**1.** Build the project: + +```bash +$ npm run build +``` + +**2.** Migrate database schemas (alter existing tables): + +```bash +$ npm run migrate +``` + +This would generate the corresponding Oracle table `USER` using the metadata +from `User` model via auto-migrate if it does not exist. See +[Database Migration](#database-migration) section below for information. + +If you check the database, you should able to see the table `USER`. + +``` +SQL> SELECT column_name,data_type,data_length FROM all_tab_columns + WHERE table_name='USER' AND owner='LOOPBACK'; + +COLUMN_NAME DATA_TYPE DATA_LENGTH +----------------------------------------- +ID NUMBER 22 +NAME VARCHAR2 1024 +HASACCOUNT CHAR 1 +``` + +### 6. Create endpoints and view data using API Explorer + +Once we built a [controller](../../Controllers.md) with `lb4 controller` to +handle requests: + +```bash +$ lb4 controller +? Controller class name: user +Controller User will be created in src/controllers/user.controller.ts + +? What kind of controller would you like to generate? REST Controller with CRUD +functions +? What is the name of the model to use with this CRUD repository? User +? What is the name of your CRUD repository? UserRepository +? What is the name of ID property? id +? What is the type of your ID? number +? Is the id omitted when creating a new instance? Yes +? What is the base HTTP path name of the CRUD operations? /users +``` + +Notice that the id is omitted in the request here because it is autogenerated. + +From the project root, start the app: + +```bash +$ npm start +``` + +We can verify what we just created with API Explorer +[http://localhost:3000/explorer/](http://localhost:3000/explorer/). + +## Database Migration + +As we showed in the previous steps, +[Database migration](../../Database-migrations.md) helps you create relational +database schemas based on definitions of your models. Here are some tips: + +- if you make further changes to models, make sure to run `npm run build` before + running the migrate script again +- `npm run migrate` alters existing tables for you. If you'd like to drop any + existing schemas, you can do `npm run migrate -- --rebuild`. But notice that + all the data will be lost. + +Please check [Database migration](../../Database-migrations.md) for details. + +Besides the basic model metadata, you can also specify part of the database +schema definition via the property definition, which would be mapped to the +database. See +[Data Mapping Properties](https://loopback.io/doc/en/lb4/MySQL-connector.html#data-mapping-properties). + +## Model Discovery + +While database migration allows you to migrate models to the DB, LoopBack also +provides a command [`lb4 discover`](../../Discovering-models.md) to generate +models based on schemas from the database. For example, we can try to discover +the `USER` table we created previously: + +```bash +$ npm run build +$ lb4 discover +? Select the connector to discover db +? Select the models which to discover User +? Select a convention to convert db column names(EXAMPLE_COLUMN) to model proper +ty names: Camel case (exampleColumn) (Recommended) +? Overwrite src/models/user.model.ts? overwrite + force src/models/user.model.ts + update src/models/index.ts + +Models User was created in src/models/ +``` + +As we can see, the newly generated `User` model would contain database specific +details: + +```ts +// imports +@model({ + settings: {idInjection: false, oracle: {schema: 'LOOPBACK', table: 'USER'}}, +}) +export class User extends Entity { + @property({ + type: 'number', + required: true, // set this to false if the value is auto-generated by the db + length: 22, + id: 1, + oracle: { + columnName: 'ID', + dataType: 'NUMBER', + dataLength: 22, + dataPrecision: null, + dataScale: null, + nullable: 'N', + }, + }) + id: number; + + @property({ + type: 'string', + required: true, + length: 1024, + oracle: { + columnName: 'NAME', + dataType: 'VARCHAR2', + dataLength: 1024, + dataPrecision: null, + dataScale: null, + nullable: 'N', + }, + }) + name: string; + + @property({ + type: 'boolean', + required: true, + length: 1, + oracle: { + columnName: 'HASACCOUNT', + dataType: 'CHAR', + dataLength: 1, + dataPrecision: null, + dataScale: null, + nullable: 'N', + }, + }) + hasaccount: boolean; + // ... +} +``` + +The field `oracle.` maps to the database definition of a table/column. +This allows you to customize the table/column names and also specify some +database related settings. See +[Data Mapping Properties](https://loopback.io/doc/en/lb4/Model.html#data-mapping-properties). diff --git a/docs/site/tutorials/connectors/Postgresql-tutorial.md b/docs/site/tutorials/connectors/Postgresql-tutorial.md index 40515d5c9c53..401c8ce7ba13 100644 --- a/docs/site/tutorials/connectors/Postgresql-tutorial.md +++ b/docs/site/tutorials/connectors/Postgresql-tutorial.md @@ -1,6 +1,6 @@ --- lang: en -title: 'PostgreSQL connector tutorial' +title: 'PostgreSQL Connector Tutorial' keywords: LoopBack 4.0, LoopBack 4, Node.js, TypeScript, OpenAPI, Connector, PostgreSQL, Tutorial @@ -259,7 +259,7 @@ details: export class User extends Entity { @property({ type: 'number', - required: true, + required: true, // set this to false if the value is auto-generated by the db scale: 0, id: 1, postgresql: {