作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.
约文。约万诺维奇的头像

By 约文。约万诺维奇

Jovan是一名企业家和工程师,具有很强的数学背景和解决问题的广泛技能.

以前在

益百利
分享

节点的日益普及就不用说了.用于应用程序开发的Js. 自2011年以来,eBay一直在运行生产节点API服务. PayPal正在积极重建他们的节点前端. 沃尔玛的移动网站已经成为最大的节点应用程序,流量方面. 2014年的感恩节周末, 沃尔玛服务器处理1个.50亿次请求其中70%是通过移动设备发送的,并由节点提供支持.js. 在开发端,节点包管理器(npm)继续快速增长,最近已超过150,000个托管模块.

Ruby有RailsPython Django作为节点的主流应用程序开发框架还没有建立起来吗. 但是,有一个强大的竞争者正在崛起: 回送是一个由加州圣马特奥(San Mateo)开发的开源API框架.、公司 StrongLoop. StrongLoop是最新的一个重要贡献者 节点的版本的长期维护者就更不用说了 表达是目前最流行的节点框架之一.

让我们通过将所有内容转化为实践并构建示例应用程序来深入了解回送及其功能.

什么是环回?它如何与节点一起工作?

环回是一个框架 创建api 并将它们与后端数据源连接起来. 建立在表达之上, 它可以接受数据模型定义,并轻松生成功能齐全的端到端REST API,可以由任何客户机调用.

环回带有内置客户端, API浏览器. 我们将使用它,因为它使我们更容易看到我们的工作结果, 这样我们的例子就可以专注于构建API本身.

当然,您需要在您的机器上安装节点才能进行操作. 得到它 在这里. 它附带了NPM,所以你可以很容易地安装必要的包. 让我们开始吧.

创建骨架

我们的应用程序将管理谁愿意捐赠礼物的人, 或者是他们不再需要的东西, 给可能需要它们的人. 因此,用户将是捐赠者和接收者. 捐献人可以创建新礼物并查看礼物列表. 接收者可以看到来自所有用户的礼物列表,并且可以认领任何未认领的礼物. 当然, 我们可以在同一实体(用户)上将捐赠者和接收者构建为独立的角色。, 但是让我们试着把它们分开,这样我们就可以看到如何在环回中建立关系. 这个开创性的应用程序的名字将是 Givesomebody.

通过npm安装StrongLoop命令行工具:

$ NPM install -g strongloop

然后运行回送的应用程序生成器:

$ SLC环回

     _-----_
    |       |    .--------------------------.
    |—(o)—| |让我们创建一个回送 |
   ' --------- ' |应用程序!       |
    ( _´U`_ )    '--------------------------'
    / ___A___ \    
     |  ~  |     
   __'.___.'__   
 ´   `  |° ´ Y ` 

? 您的应用程序的名称是什么? Givesomebody

让我们添加一个模型. 我们的第一个模型将被称为礼物. 回送将询问数据源和基类. 由于我们还没有设置数据源,我们可以放入 db(内存). 基类是一个自动生成的模型类,我们希望使用 Persisted模型 在本例中,因为它已经为我们包含了所有常用的CRUD方法. 下一个, 回送询问是否应该通过REST公开模型(是), 以及REST服务的名称. 在这里按enter键使用默认值,它只是模型名称的复数形式(在我们的示例中, 礼物).

$ SLC环回:模型

? 输入模型名称:礼物
? 选择要附加礼物的数据源:(使用方向键)
00 db(内存)
? 选择模型的基类:(使用方向键)
  模型
❯Persisted模型
? 通过REST API暴露礼物? (Y / n)是的
? 自定义复数形式(用于构建REST URL):

最后,我们给出属性的名称、它们的数据类型和必需/非必需标志. 礼物会有 名字描述 属性:

现在让我们添加一些礼物属性.

完成后输入一个空属性名.
? 属性名称:名字
   调用回路:房地产
? 属性类型:(使用方向键)
❯字符串
? 要求? (y / N)是的

输入一个空属性名,表示您已经完成了属性的定义.

模型生成器将创建两个文件来定义应用程序中的模型 公共/模型: 礼物.json礼物.js. JSON文件指定关于实体的所有元数据:属性, 关系, 验证, 角色和方法名称. JavaScript文件用于定义附加行为, 并指定在某些操作之前或之后调用的远程钩子.g.、创建、更新或删除).

另外两个模型实体将是我们的捐赠和Receiver模型. 我们可以使用相同的过程创建它们,只是这次我们把 用户 作为基类. 它会给我们一些性质,比如 用户名, 密码, 电子邮件 开箱即用. 例如,我们可以只添加姓名和国家来创建一个完整的实体. 对于接收者,我们也要添加送货地址.

项目结构

让我们看一下生成的项目结构:

项目结构

三个主要目录是: - /服务器 —包含节点应用脚本和配置文件. - /客户端 ——包含 .js, .超文本标记语言 .Css和所有其他静态文件. - /常见 —服务器端和客户端共用此文件夹. 模型文件放在这里.

下面是每个目录内容的详细细分,取自 回送文件:

文件或目录描述如何在代码访问
顶级应用程序目录
包.json标准的npm包规范. 看到 包.json N/A
/服务器目录-节点应用程序文件 
服务器.js主应用程序文件. N/A
配置.json应用程序设置. 看到 配置.json.应用程序.get(“setting-名字”)
数据源.json 数据源配置文件. 看到 数据源.json. 使用示例请参见 创建新数据源. 应用程序.数据源(“数据源名称”)
model-配置.json模型配置文件. 看到 model-配置.json. 有关更多信息,请参见  将模型连接到数据源. N/A
Middleware.jsonMiddleware定义文件. 有关更多信息,请参见 定义Middleware.N/A
/ boot 目录添加脚本来执行初始化和设置. 看到 启动脚本.脚本自动按字母顺序执行.
/客户端目录-客户端应用程序文件
自述.md回送生成器以markdown格式创建空的自述文件.N/A
其他添加你的HTML, CSS,客户端JavaScript文件. 
/常见目录-共享的应用程序文件
/模型 目录自定义模型文件:
  • 模型定义JSON文件按惯例命名 模型名称.json; for example 客户.json.
  • 自定义模型脚本按约定命名 模型名称.js; for example, 客户.js.
有关更多信息,请参见 模型定义JSON文件 定制模型.
节点:
my模型 = 应用程序.模型.my模型Name

建立关系

在我们的示例中,我们有几个重要的关系需要建模. 一个捐赠者可以捐赠很多礼物,这就给出了关系 捐赠者有许多礼物. 一个接收者也可以收到很多礼物,所以我们也有这个关系 收礼人有许多礼物. 另一方面, 礼物归捐赠人所有,也可以 属于接收方 如果接管人选择接受的话. 让我们把它转换成环回的语言.

$ SLC环回:关系

? 选择要从中创建关系的模型:捐赠
? 关系类型:有很多
? 选择一个模型来建立关系:礼物
? 输入关系的属性名称:礼物
? 可选地输入自定义外键:
? 需要一个直通模型? No

Note that t在这里 is no 通过 model; we are just holding the reference to the 礼物.

如果我们对Receiver重复上述过程,并加上2 属于 关系的礼物,我们将完成我们的模型设计后端. 回送自动更新模型的JSON文件,以准确地表达我们刚刚通过这些简单的对话框所做的事情:

/ /共同/模型/捐赠者.json
  ...
  "关系":{
    "礼物":{
      “类型”:“hasMany”,
      “模型”:“礼物”,
      “foreignKey”:“
    }
  },
  ...

添加数据源

现在让我们看看如何附加一个真实的数据源来存储所有应用程序数据. 在本例中,我们将使用 MongoDB,但回送模块连接Oracle, MySQL, PostgreSQL, Redis和SQL Server.

首先,安装连接器:

$ NPM install——save 回送-connector-mongodb

然后,在你的项目中添加一个数据源:

$ SLC环回:数据源

? 输入数据源名称:givesomebody
? 为givesomebody选择连接器:MongoDB(由StrongLoop支持)

下一个步骤是配置数据源 服务器/数据源.json. 在本地MongoDB服务器上使用以下配置:

  ...
  " givesomebody ": {
    “名称”:“givesomebody”,
    “连接器”:“mongodb”,
    “主机”:“localhost”,
    “端口”:27017年,
    “数据库”:“givesomebody”,
    “用户名”:“”,
    “密码”:“
  }
  ...

最后,开放 服务器/ model-配置.json 然后改变 数据源 对于我们希望在数据库中持久化的所有实体 “givesomebody”.

{
  ...
  "用户":{
    “数据源”:“givesomebody”
  },
  " AccessToken ": {
    “数据源”:“givesomebody”,
    “公共”:假的
  },
  " ACL ": {
    “数据源”:“givesomebody”,
    “公共”:假的
  },
  " 角色M应用程序ing ": {
    “数据源”:“givesomebody”,
    “公共”:假的
  },
  "角色":{
    “数据源”:“givesomebody”,
    “公共”:假的
  },
  "礼物":{
    “数据源”:“givesomebody”,
    “公共”:真的
  },
  “供体”:{
    “数据源”:“givesomebody”,
    “公共”:真的
  },
  “接收方”:{
    “数据源”:“givesomebody”,
    “公共”:真的
  }
}

测试REST API

是时候看看我们目前都做了些什么了! 我们将使用很棒的内置工具, API浏览器,它可以用作我们刚刚创建的服务的客户机. 让我们来测试一下 REST API 调用.

在一个单独的窗口中,启动MongoDB:

$ mongod

使用以下命令运行应用程序:

美元的节点 .

在浏览器中,转到 http://localhost:3000/资源管理器/. 您可以看到带有可用操作列表的实体. 尝试添加一个捐助者与POST /捐赠者 呼叫.

测试API 2

测试API 3

API浏览器 is very intuitive; select any of the exposed methods, 相应的模型方案将显示在右下角. 在 data 文本区域,可以编写自定义HTTP请求. 填好请求后, 点击“试用”按钮, 服务器的响应将显示在下面.

测试API 1

用户身份验证

如上所述,预先与回送一起构建的实体之一是用户类. 用户拥有登录和注销方法, 并且可以绑定到一个AccessToken实体,该实体保存特定用户的令牌. 事实上,一个完整的用户身份验证系统已经准备好了. 如果我们试着打电话 捐助者/登录 通过 API浏览器,我们得到的回应如下:

{
  “id”:“9 kvp4zc0rtrh7immergwtnc6iqnxpvfv7d17dechhsgcaf9z36a3cnppzj1igrms”,
  “ttl”:1209600,
  “创建”:“2015 - 05 - 26 - t01:24:41.561Z",
  “标识”:“
}

id AccessToken的值实际上是自动生成并保存在数据库中的吗. 正如您在这里看到的,可以设置访问令牌并将其用于每个后续请求.

用户身份验证

远程方法

远程方法是模型的静态方法,通过自定义REST端点公开. 远程方法可以用来执行回送的标准模型REST API没有提供的操作.

除了现成的CRUD方法之外,我们还可以添加任意数量的自定义方法. 它们都应该进入 (模型).js 文件. 在我们的例子中, 让我们向礼物模型添加一个远程方法来检查礼物是否已经被保留, 还有一个是列出所有不保留的礼物.

首先,让我们向模型添加一个附加属性 保留. 把这个添加到属性中 礼物.json:

    ...
    "保留":{
      “类型”:“布尔”
    }
    ...

中的远程方法 礼物.js 应该看起来像这样:

模块.exports = function(礼物) {

    //列出所有免费礼物的方法
    礼物.listFree = function(cb) {
        礼物.找到({
            领域:{
                保留:假
            }
        }, cb);
    };

    //通过REST公开上述方法
    礼物.remoteMethod (listFree, {
        返回:{
            参数:“礼物”,
            类型:“数组”
        },
        http: {
            路径:/ list-free,
            动词:“得到”
        }
    });

    //如果礼物是免费的,返回的方法
    礼物.isFree = function(id, cb) {
        var反应;
        礼物.找到({
            领域:{
                id: id
            }
        }, function(err, 礼物) {
            If (err) return cb(err);

            如果(礼物.保留)
                response =“对不起,礼物已预订”;
            其他的
                回应=“太好了,这个礼物可以是你的了”;

        });
        cb (null,响应);
    };

    //通过REST公开方法
    礼物.remoteMethod(‘自由’,{
        接受:{
            参数:“id”,
            类型:“数量”
        },
        返回:{
            参数:“反应”,
            类型:“字符串”
        },
        http: {
            路径:/免费,
            动词:“文章”
        }
    });
};

因此,要找出是否有特定的礼物,客户端现在可以发送POST请求到 / api /礼物/免费的,经过 id 有问题的礼物.

远程钩子

有时需要在远程方法之前或之后执行某些方法. 你可以定义两种远程钩子:

  • beforeRemote () 在远程方法之前运行.
  • afterRemote () 在远程方法之后运行.

这两种情况, 您可以提供两个参数:一个字符串,该字符串与要将函数“挂钩”到的远程方法相匹配, 还有回调函数. 远程钩子的强大之处在于字符串可以包含通配符, 所以它是由任何匹配方法触发的.

在我们的示例中,让我们设置一个钩子,以便在创建新的捐赠时将信息打印到控制台. 为了实现这一点,让我们添加一个“before create”钩子 捐赠.js:

模块.exports = function(捐赠) {
    捐赠.beforeRemote('create', function(上下文, 捐赠, next) {
        控制台.'保存名称为:的新捐赠者',上下文.要求的事情.body.的名字);
    
        next ();
    });
};

使用给定的方法调用请求 上下文,和 next () Middleware中的回调(将在下面讨论)在钩子运行后调用.

访问控制

环回应用程序通过模型访问数据, so controlling access to data means defining restrictions on 模型; that is, 指定谁或什么可以读写数据或执行模型上的方法. 环回访问控制由访问控制列表(acl)决定.

让我们允许未登录的捐赠者和接收者查看礼物, 但只有登录的捐赠者才能创建和删除它们.

$ SLC 回送:acl

首先,让我们拒绝每个人访问所有端点.

? 选择要应用ACL条目的模型:礼物
? 选择ACL范围:所有方法和属性
? 选择访问类型:All(匹配所有类型)
? 选择角色:所有用户
? 选择要应用的权限:显式拒绝访问

接下来,请大家从礼物模型中阅读:

$ SLC 回送:acl

? 选择要应用ACL条目的模型:礼物
? 选择ACL范围:所有方法和属性
? 选择访问类型:读
? 选择角色:所有用户
? 选择要应用的权限:显式授予访问权限

然后,我们希望允许经过身份验证的用户创建礼物:

$ SLC 回送:acl

? 选择要应用ACL条目的模型:礼物
? 选择ACL范围:单个方法
? 输入方法名:create
? 选择角色:任何通过身份验证的用户
? 选择要应用的权限:显式授予访问权限

最后,让我们允许礼物的主人做出任何改变:

$ SLC 回送:acl

? 选择要应用ACL条目的模型:礼物
? 选择ACL范围:所有方法和属性
? 选择访问类型:写
? 选择角色:对象所属的用户
? 选择要应用的权限:显式授予访问权限

当我们复习的时候 礼物.json,一切都应该到位;

“acl”:(
  {
    “accessType”:“*”,
    “principalType”:“角色”,
    “principalId”:“每个人”美元,
    “许可”:“否认”
  },
  {
    “accessType”:“读”,
    “principalType”:“角色”,
    “principalId”:“每个人”美元,
    “许可”:“允许”
  },
  {
    “accessType”:“执行”,
    “principalType”:“角色”,
    “principalId”:“身份验证”美元,
    “许可”:“允许”,
    “财产”:“创造”
  }
],

这里有一点很重要: 美元的验证 是一个预定义的角色,它对应于系统中的所有用户(捐赠者和接收者)。, 但我们只想让捐赠者创造新的礼物. 因此,我们需要一个自定义角色. 由于角色是我们开箱即用的另一个实体,我们可以利用它的API调用来创建 身份验证enticated捐赠美元 角色在开机功能,然后才修改 pricipalId in 礼物.json.

需要创建一个新文件, 服务器/ boot /脚本.js,并添加以下代码:

角色.创建({
    名称:“身份验证enticated捐赠”
},函数(err, role) {
    If (err)返回debug(err);
})

角色映射实体将角色映射到用户. 确保角色和角色M应用程序ing都是通过REST公开的. In 服务器/ model-配置.json,检查一下 “公共” 设为 真正的 用于角色实体. 然后在 捐赠.js,我们可以编写一个“before create”钩子来映射 用户标识roleID 在角色M应用程序ing POST API调用中.

Middleware

Middleware包含在向REST端点发出请求时执行的函数. 因为回送是基于表达的, 它使用带有一个附加概念的表达Middleware, 称为“Middleware阶段”.阶段用于明确定义Middleware中调用函数的顺序.

以下是预定义阶段的列表,在回送文档中提供:

  1. 最初的 -Middleware可以运行的第一个点.
  2. 会话 —准备会话对象.
  3. 身份验证 —处理认证授权.
  4. 解析 -解析请求体.
  5. 路线 - HTTP路由实现您的应用程序逻辑. 通过表达 API应用注册的Middleware.使用,应用.路线,应用.get(和其他HTTP动词)在这个阶段的开始运行. 此阶段也用于子应用程序,如回送/服务器/Middleware/rest或回送-资源管理器.
  6. 文件 -服务静态资产(请求在这里击中文件系统).
  7. 最后 —处理错误和未知url请求.

每个阶段有三个子阶段. 例如,初始阶段的子阶段为:

  1. 初始:在
  2. 最初的
  3. 初始:在

让我们快速查看一下我们的默认Middleware.json:

{
  “初步:在":{
    “回送#图标”:{}
  },
  “初始”:{
    “压缩”:{},
    “歌珥”:{
      " params ": {
        “起源”:没错,
        “凭证”:没错,
        “maxAge”:86400
      }
    }
  },
  “会话”:{
  },
  “身份验证”:{
  },
  “解析”:{
  },
  "路线":{
  },
  "文件":{
  },
  “最终”:{
    “回送# urlNotFound”:{}
  },
  “最后:在":{
    “errorh和ler”:{}
  }
}

在初始阶段,我们叫 回送.标识() (回送#标识 是该调用的Middlewareid). 然后是第三方npm模块 压缩歌珥 被调用(带或不带参数). 在最后阶段,我们还有两个电话. urlNotFound 是环回调用,而 errorh和ler 是第三方模块. 这个例子应该展示了很多内置调用可以像外部npm模块一样被使用. 当然,我们总是可以创建自己的Middleware,并通过这个JSON文件调用它们.

LoopBack-boot

作为总结,让我们提到一个导出 引导() 初始化应用程序的函数. In 服务器/服务器.js 你会发现下面的一段代码,它引导应用程序:

启动(应用程序, __dir名字, function(err) {
    If (err)抛出err;
  
    //启动服务器如果' 美元的节点 服务器 ..js`
    如果需要.主===模块)
        应用程序.开始();
});

这个脚本将搜索 服务器/启动 文件夹,并按字母顺序加载它在其中找到的所有脚本. 因此,在 服务器/启动,我们可以指定任何应该在开始时运行的脚本. 一个例子是 资源管理器.js,它运行 API浏览器,即我们用来测试API的客户端.

有重复的忧郁? 不要再从头开始构建节点 API了. 让环回来做!

结论

在我离开你们之前,我想提一下 StrongLoop弧,一个图形化的用户界面,可以作为一个替代 slc 命令行工具. 它还包括用于构建、分析和监视节点应用程序的工具. 对于那些不喜欢命令行的人来说,这绝对值得一试. 然而,StrongLoop弧即将被弃用,它的功能正在被集成到 IBM API Connect开发人员工具包.

结论

一般来说, 环回可以为您节省很多手工工作,因为您可以从盒子里取出很多东西. 它允许您专注于特定于应用程序的问题和业务逻辑. 如果你的申请是 基于CRUD操作 操纵预定义的实体, 如果您厌倦了重写用户身份验证和授权基础设施,而在您之前已经有大量开发人员编写了这些基础设施, 或者如果你想利用像表达这样优秀的web框架的所有优势, 然后用环回构建你的REST API可以让你的梦想成真. 小菜一碟!

就这一主题咨询作者或专家.
预约电话
约文。约万诺维奇的头像
约文。约万诺维奇

位于 贝尔格莱德,塞尔维亚

成员自 2014年8月21日

作者简介

Jovan是一名企业家和工程师,具有很强的数学背景和解决问题的广泛技能.

Toptal作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.

以前在

益百利

世界级的文章,每周发一次.

订阅意味着同意我们的 隐私政策

世界级的文章,每周发一次.

订阅意味着同意我们的 隐私政策

Toptal开发者

加入总冠军® 社区.