Node.js学习:使用Loopback3.0构建应用程序(一)
一、安装
安装LoopBack工具来创建和开发LoopBack 3.0应用程序。
安装Node.js
安装loopback工具
虽然你可以自己从头开始编写一个LoopBack应用程序,但是安装一个LoopBack CLI工具能够使它更容易入门。它将构建应用程序的基本结构,然后您可以根据需要进行自定义。
LoopBack提供了两个工具的选项:LoopBack CLI 和 IBM API Connect开发工具包,这里可以选择LoopBack CLI来进行应用程序的构建。
安装Loopback CLI工具
npm install -g loopback-cli
这一步将安装 lb
命令行工具,用于构建和修改LoopBack应用程序。
安装更新
如果之前安装过strongloop,需要进行一次版本的更新:
npm install -g strongloop
如果遇到任何问题,可以尝试卸载重装:
npm uninstall -g strongloop
npm cache clear
npm install -g strongloop
二、使用Loopback创建一个应用
创建一个简单的API
首先使用loopback-cli创建一个新的应用:
lb
LoopBack应用生成器将提示您输入应用程序的名称。
_-----_
| | .--------------------------.
|--(o)--| | Let's create a LoopBack |
`---------´ | application! |
( _´U`_ ) '--------------------------'
/___A___\
| ~ |
__'.___.'__
´ ` |° ´ Y `
[?] What's the name of your application? loopback-getting-started
[?] Enter name of the directory to contain the project: loopback-getting-started
这里可以替换成任何你喜欢的名字,本教程使用了官方文档中的名称:loopback-getting-started。
接下来cli工具会询问要创建什么样的应用程序:可以选择 hello-world
。
? What kind of application do you have in mind? (Use arrow keys)
api-server (A LoopBack API server with local User auth)
empty-server (An empty LoopBack API, without any configured models or datasources)
❯ hello-world (A project containing a controller, including a single vanilla Message and
a single remote method)
notes (A project containing a basic working example, including a memory database)
然后,生成器将在其构建应用程序时创建如下信息,包括:
- 初始化项目的文件夹结构。
- 创建默认的JSON文件。
- 创建默认的JavaScript文件。
- 下载并安装依赖节点模块(省去手动安装npm的一步)。
创建一个数据模型
完成了初始项目的构建,接下来我们将创建一个自动具有REST API接口的CoffeeShop模型。
进入应用程序目录,然后运行LoopBack模型生成器:
lb model
生成器将提示输入数据模型的名称,输入CoffeeShop:
[?] Enter the model name: CoffeeShop
它会询问您是否要将模型附加到已经一些已经定义的数据源。 此时,只有默认的内存数据源可用。按Enter键选择它:
...
[?] Select the data-source to attach CoffeeShop to: (Use arrow keys)
❯ db (memory)
然后,生成器将提示您使用基类作为模型。由于您在最终会把该模型连接到数据库中的持久数据源,所以这里选择PersistedModel:
[?] Select model's base class: (Use arrow keys)
Model
❯ PersistedModel
ACL
AccessToken
Application
Change
Checkpoint
PersistedModel是连接到持久性数据源(如数据库)的所有模型的基础对象,也就是基类。
关于Loopback中的模型:
模型是LoopBack的核心,表示如数据库或其他后端服务(REST,SOAP等)等后端数据源。 LoopBack模型是具有Node和REST API的JavaScript对象。
LoopBack的一个关键功能是当您定义一个模型时,它将自动附带预定义的REST API,并具有完整的创建,读取,更新和删除操作。
Basic模型对象具有添加钩子和验证数据的方法。其他模型对象都“继承”它。模型具有继承层次结构,如下图所示:将模型附加到持久性数据源时,它将成为具有创建,检索,更新和删除操作的连接模型。 LoopBack的内置模型继承自它。
model的继承关系
LoopBack的强大优点之一是它自动为您的模型生成REST API。生成器将询问您是否要公开此REST API。
再次输入Enter接受默认值,并通过REST暴露CoffeeShop模型:
[?] Expose CoffeeShop via the REST API? (Y/n) Y
LoopBack使用模型名称的复数自动创建与模型关联的REST路由。默认情况下,它将您的名称复数(通过添加“s”),但是如果需要,您可以指定自定义复数形式。
按Enter接受默认复数形式(CoffeeShops):
[?] Custom plural form (used to build REST URL):
接下来,系统会询问您是要仅在服务器上创建模型,还是在/common
目录中创建模型,这些模型可能由服务器端口和客户端LoopBack API使用。选择common,即使在这个应用程序中,你只使用服务器端模型:
? Common model or server only?
❯ common
server
每个模型都有属性。现在,您将为CoffeeShop模型定义一个属性“name”。
选择字符串作为属性类型:
Let's add some CoffeeShop properties now.
Enter an empty property name when done.
[?] Property name: name
invoke loopback:property
[?] Property type: (Use arrow keys)
❯ string
number
boolean
object
array
date
buffer
geopoint
(other)
每个属性可以是可选的或必需的。输入 y
以将 name
设为必需:
[?] Required? (y/N)
然后系统会提示您输入属性的默认值;按Enter键不设默认值:
? Default value[leave blank for none]:
然后,系统会提示您添加其他属性。按照提示添加名为“city”的必需属性。
Let's add another CoffeeShop property.
? Property name: city
? Property type: string
? Required? Yes
? Default value[leave blank for none]:
当提示输入下一个属性的名称时,按Enter键结束模型创建过程。
模型生成器将在应用程序的 common / models
目录中创建两个定义模型的文件: coffee-shop.json
和 coffee-shop.js
。
LoopBack模型生成器自动将驼峰式的模型名称(例如MyModel)转换为小写字母名称(my-model)。例如,如果您使用模型生成器创建一个名为“FooBar”的模型,它将在
common/models
中创建foo-bar.json
和foo-bar.js
文件。但是,模型名称(“FooBar”)将通过模型的名称属性进行保留。
运行应用程序
$ node .
...
Browse your REST API at http://0.0.0.0:3000/explorer
Web server listening at: http://0.0.0.0:3000/
现在打开你的浏览器到http://0.0.0.0:3000/explorer 或http://localhost:3000/explorer 。您将看到StrongLoop API资源管理器:
通过使用LoopBack的一系列简单的步骤,您创建了一个CoffeeShop模型并为它设置了一些属性,然后通过REST进行公开。
三、使用API资源管理器
运行API资源管理器
运行应用: node .
转到 http://localhost:3000/explorer。您将看到StrongLoop API资源管理器中显示了该应用程序的两个模型:User和CoffeeShop:
探索CoffeeShop模型
除了CoffeeShop模型之外,Loopback还会为每个应用程序生成默认的用户模型及其接口。
展开CoffeeShops之后,可以看到它所有的API接口。
大致浏览这些API接口:您可以看到它们涵盖了所有的创建,读取,更新和删除(CRUD)等操作。你可以去post一条数据来试试看。
四、将API连接到数据源
添加一个数据源
现在,您将使用数据源生成器定义数据源:
$ lb datasource
生成器将提示您命名数据源:
[?] Enter the data-source name:
接下来,生成器将提示您输入数据源的类型,这里以mySql为例:
? Select the connector for mysqlDs: (Use arrow keys)
❯ In-memory db (supported by StrongLoop)
IBM DB2 (supported by StrongLoop)
IBM DashDB (supported by StrongLoop)
IBM MQ Light (supported by StrongLoop)
IBM Cloudant DB (supported by StrongLoop)
IBM DB2 for z/OS (supported by StrongLoop)
MongoDB (supported by StrongLoop)
(Move up and down to reveal more choices)
然后该工具将提示您输入数据源配置,对于MySQL,您可以以URL格式或单独输入所有设置。
Connector-specific configuration:
? Connection String url to override other settings (eg: mysql://user:pass@host/db):
按回车键跳过。
提示:尽量使用自己的MySQL数据库服务器,并创建一个名为“getting_started”的新数据库,数据库名称可以自己定义,但是请确保datasources.json中的mysqlDs.database属性与之匹配。
如果没有,您可以使用在demo.strongloop.com上运行的StrongLoop MySQL服务器。但它是一个共享资源,两个用户可能会同时运行创建样本数据的脚本,这可能会引发冲突。因此,我们建议您使用自己的MySQL服务器。
如果使用StrongLoop MySQL服务器,请输入如下所示的设置。如果使用您自己的MySQL服务器,请输入服务器的主机名,端口号和登录信息。
? host: demo.strongloop.com
? port: 3306
? user: demo
? password: L00pBack
? database: getting_started
? Install loopback-connector-mysql@^2.2 Yes
当工具提示您安装连接器时,运行npm install loopback-connector-mysql --save
。该工具还将数据源定义添加到server/datasources.json
文件中,如下所示。请注意刚刚添加的“mysqlDs”数据源,以及名为“db”的内存数据源,默认情况下是这样。
/server/datasources.json
{
"db": {
"name": "db",
"connector": "memory"
},
"mysqlDs": {
"host": "demo.strongloop.com",
"port": 3306,
"url": "",
"database": "getting_started",
"password": "L00pBack",
"name": "mysqlDs",
"user": "demo",
"connector": "mysql"
}
}
将CoffeeShop模型连接到MySQL
现在你创建了一个MySQL数据源,并且有一个CoffeeShop模型,接下来需要把它们联系起来。LoopBack应用程序使用model-config.json文件将模型链接到数据源。编辑/server/model-config.json
并查找CoffeeShop条目:
/server/model-config.json
...
"CoffeeShop": {
"dataSource": "db",
"public": true
}
...
把dataSource属性从db更改为mysqlDs。使CoffeeShop模型附加到刚刚创建和配置的MySQL数据源:
/server/model-config.json
...
"CoffeeShop": {
"dataSource": "mysqlDs",
"public": true
}
...
添加一些测试数据
现在LoopBack中已经有了一个CoffeeShop模型,如何在MySQL数据库中创建相应的表?
您可以直接尝试执行一些SQL语句,不过LoopBack提供了一个Node API,可以自动执行一个称作auto-migration的程序。
loopback-getting-started
模块包含用于演示自动迁移的create-sample-models.js脚本。
注意:以下自动迁移脚本是在应用程序初始启动时LoopBack执行的引导脚本的示例。使用引导脚本进行初始化,并执行应用程序启动时执行的任何其他逻辑。
/server/boot/create-sample-models.js
module.exports = function(app) {
app.dataSources.mysqlDs.automigrate('CoffeeShop', function(err) {
if (err) throw err;
app.models.CoffeeShop.create([{
name: 'Bel Cafe',
city: 'Vancouver'
}, {
name: 'Three Bees Coffee House',
city: 'San Mateo'
}, {
name: 'Caffe Artigiano',
city: 'Vancouver'
}, ], function(err, coffeeShops) {
if (err) throw err;
console.log('Models created: \n', coffeeShops);
});
});
};
这将保存一些测试数据到数据源。
五、扩展API
添加远程方法
按着如下步骤:
- 查看您的应用程序的
/common/models
目录。你会注意到文件夹里有coffee-shop.js和coffee-shop.json这两个文件。 - 在编辑器中打开coffee-shop.js,默认情况下,它包含一个空的函数:
module.exports = function(CoffeeShop) {};
- 将以下代码添加到此函数中:
module.exports = function(CoffeeShop) {
CoffeeShop.status = function(cb) {
var currentDate = new Date();
var currentHour = currentDate.getHours();
var OPEN_HOUR = 6;
var CLOSE_HOUR = 20;
console.log('Current hour is %d', currentHour);
var response;
if (currentHour > OPEN_HOUR && currentHour < CLOSE_HOUR) {
response = 'We are open for business.';
} else {
response = 'Sorry, we are closed. Open daily from 6am to 8pm.';
}
cb(null, response);
};
CoffeeShop.remoteMethod(
'status', {
http: {
path: '/status',
verb: 'get'
},
returns: {
arg: 'status',
type: 'string'
}
}
);
};
这定义了一个称为“状态”的简单远程方法,它不需要任何参数,并且根据当前时间检查时间并返回一个表示“打开营业”或“对不起我们关闭”的JSON状态消息。
当然,在实践中,您可以使用远程方法来做更多有趣和复杂的事情,例如在将数据保留到数据库之前操纵输入数据。您还可以更改调用远程方法的路由,并定义复杂参数并返回值。
使用远程方法
- 回到应用程序根目录,运行应用程序:
$ node .
- 转到http:// localhost:3000 / explorer查看API资源管理器。然后点击CoffeeShops,你会看到有一个新的REST端点,GET / CoffeeShop / status调用远程方法。
点击try it out!您会看到调用远程方法的结果:
{
"status": "Open for business."
}
通过LoopBack,很轻易地添加了一个远程方法。
在远程方法中执行创建,检索,更新和删除方法
状态远程方法是微不足道的,但远程方法还可以访问任何标准模型创建,检索,更新和删除方法来执行数据处理和验证。这是一个简单的例子(这不是在loopback-getting-started库中):
module.exports = function(CoffeeShop) {
...
CoffeeShop.getName = function(shopId, cb) {
CoffeeShop.findById( shopId, function (err, instance) {
var response = "Name of coffee shop is " + instance.name;
cb(null, response);
console.log(response);
});
}
...
CoffeeShop.remoteMethod (
'getName',
{
http: {path: '/getname', verb: 'get'},
accepts: {arg: 'id', type: 'number', http: { source: 'query' } },
returns: {arg: 'name', type: 'string'}
}
);
}
然后如果您访问远程方法,例如:
http://0.0.0.0:3000/api/CoffeeShops/getname?id=1
将会得到响应:
{
"name": "Name of coffee shop is Bel Cafe"
}
六、添加一个静态页面
中间件简介
在继续之前,您首先需要了解Express中间件的基础知识。中间件只是一个JavaScript函数,可以访问表示HTTP请求的请求对象(req),表示HTTP响应的响应对象(res),以及Express应用程序的请求 - 响应周期中,由一个名为next的变量表示的下一个中间件。
中间件可以做什么?
- 执行任何代码。
- 更改请求和响应对象。
- 结束请求 - 响应周期。
- 调用堆栈中的下一个中间件。
LoopBack中间件就像Express中间件,除了LoopBack添加了相位的概念,使您能够轻松设置调用中间件的顺序。这避免了Express的一个棘手问题:确保中间件在需要的时候能够执行。
当您使用应用程序生成器创建应用程序时,它将创建一个server/middleware.json
文件,指定中间件在哪个阶段执行。注册新的中间件与编辑此JSON文件一样简单:
server/middleware.json
{
"initial:before": {
"loopback#favicon": {}
},
"initial": {
"compression": {},
"cors": {
"params": {
"origin": true,
"credentials": true,
"maxAge": 86400
}
},
"helmet#xssFilter": {},
"helmet#frameguard": {
"params": [
"deny"
]
},
"helmet#hsts": {
"params": {
"maxAge": 0,
"includeSubdomains": true
}
},
"helmet#hidePoweredBy": {},
"helmet#ieNoOpen": {},
"helmet#noSniff": {},
"helmet#noCache": {
"enabled": false
}
},
"session": {},
"auth": {},
"parse": {},
"routes": {
"loopback#rest": {
"paths": [
"${restApiRoot}"
]
}
},
"files": {},
"final": {
"loopback#urlNotFound": {}
},
"final:after": {
"strong-error-handler": {}
}
}
middleware.json
中的每个顶层键都定义了一个中间件阶段:initial
,session
,auth
等等,到final
为止。在给定阶段之前和之后,还有修改器注册中间件。在给定阶段的前后也有注册中间件的修改器。
更换或修改默认的根路由处理程序
应用程序通常需要提供静态内容,如HTML和CSS文件,客户端JavaScript文件,图像等。
使用LoopBack应用程序默认的脚手架很容易做到。您将去配置应用程序去启动/client文件夹中的静态资源。
首先,您必须禁用根URL的默认路由处理程序。当你加载应用程序的根URL [http:// localhost:3000/](http:// localhost:3000/)时,你看到应用程序用一个简单的状态消息,如这个:
{"started":"2014-11-20T21:59:47.155Z","uptime":42.054}
这是因为默认情况下,脚手架应用程序具有一个名为root.js的启动脚本,该脚本为根路径(“/”)设置路由处理中间件:
server/boot/root.js
module.exports = function(server) { // Install a `/` route that returns server status
var router = server.loopback.Router();
router.get('/', server.loopback.status());
server.use(router);
};
该代码说,对于根URI(“/”)的任何GET请求,应用程序将返回loopback.status()的结果。要加入您自己的静态页面,您需要禁用此脚本。要么删除它,要么将其重命名为没有.js结尾的东西(确保应用程序不会执行它)。
定义静态中间件
接下来,您需要定义静态中间件来为/ client目录中的文件提供服务。
server/middleware.json
...
"files": {},
...
添加以下内容:
server/middleware.json
...
"files": {
"loopback#static": {
"params": "$!../client"
}
},
...
添加一个HTML文件
这些行定义静态中间件,使应用程序将/ client目录中的文件作为静态内容。$!
字符表示路径是相对于middleware.json文件的位置。
/client/index.html
<head><title>LoopBack</title></head>
<body>
<h1>LoopBack Rocks!</h1>
<p>Hello World... </p>
</body>
运行
现在再次运行应用程序:
node .
七、添加自定义的Express路由
引入引导脚本
当LoopBack应用程序启动(也称为引导(bootstraps))时,它将运行/server/boot
目录中的脚本,称为引导脚本。默认情况下,LoopBack按字母顺序加载引导脚本。
应用程序生成器创建的标准LoopBack应用脚手架中包含执行基本初始化的以下标准引导脚本(在/ server / boot中):
-
authentication.js
- 通过调用app.enableAuth()来启用应用程序的身份验证。 -
root.js
- 使用loopback.status()中间件定义/
返回服务器状态的根路由。
添加一个新的启动脚本
例如,在/server/boot
目录中添加一个名为routes.js的新引导脚本,其代码如下:
/server/boot/routes.js
module.exports = function(app) {
// Install a "/ping" route that returns "pong"
app.get('/ping', function(req, res) {
res.send('pong');
});
}
除此之外,也可以使用Express路由器中间件,如下所示:
/server/boot/routes.js
module.exports = function(app) {
var router = app.loopback.Router();
router.get('/ping', function(req, res) {
res.send('pongaroo');
});
app.use(router);
}
实际上,您也可以使用Express API在server.js中添加路由。例如,在调用app.start()之前将此调用添加到app.use():
server/server.js
...
app.use('/express-status', function(req, res, next) {
res.json({ running: true });
});
// start the server if `$ node server.js`
if (require.main === module) {
app.start();
}
LoopBack应用程序可以轻松地执行Express应用程序可以执行的所有操作。如果您熟悉Express,LoopBack将会更容易学习。
运行引导脚本
现在,再次运行应用程序:
加载http://0.0.0.0:3000/ping。您会得到一个'pong'的响应。
现在一个简单的loopback应用程序就已经搭建完成了。
八、下一步
接下来的教程将涵盖:
- 在单个应用程序中使用多个数据源。
- 模型之间的关系。
- 远程钩子。
- 使用权限控制来保护REST接口。
- 用户注册和认证