Sails API 开发 (1/2): 数据层 - 模型、连接、Waterline、API - Blueprint,以及相关
连接各个部分,解释 Sails 数据层的模块化。
引言
本文
- 力求为 Sails 数据层建模和连接到 MySQL / Mongo 等基本数据库提供一个起点。
- 力求解释 Sails 框架为您的应用程序所做的巨大工作量。
先决条件
- 已经对 Node.js 和 Sails 框架有实验水平或以上的了解。
- 使用过 git 项目的工具,了解 Web 应用项目所需的数据建模基础知识。
背景
本文可视为 Sails.org 文档中使用 Sails 的补充文档。假设我们已经掌握了 Sails 和 Node.js,让我们进入数据层和 Sails API 的创建。
数据库连接
我们将创建数据库,然后在 Sails 中对其进行建模。定义数据库,然后在代码中对其进行建模是个人偏好。虽然反向也很有趣,但不确定 Sails 是否有像 PHP 的 Laravel 或 Microsoft 的 Entity Framework 那样的工具,可以根据模型更改来更新/创建数据库对象 -> 代码优先的... 方法。
我将从 MongoDB 开始。
MongoDB 数据库和集合
创建一个数据库(暂时没有集合)。
[请记住:如果您安装了 MongoDB 但没有明确设置任何用户……您可能需要从这里开始,使用mongo shell,或者如果您忘记了密码,最好是这里。]
Connections.js
在 \config\connections.js 下,添加 MongoDB 连接信息。
model.js
在 \config\model.js 下,将 MongoDB 连接名称设置为您的默认连接。
connection: 'myMongo',
Sails 生成 API
您将到处听到/读到... 要生成 REST API,请运行
sails generate api user
所以,让我们这样做,并且您会立即听到/读到您可以访问类似 https://:1337/user
的内容。
在 Sails 框架的默认用法中,这会奏效,因为默认数据源是 sails-disk
,它也能与 MongoDB 配合使用。
但是,如果您使用 MySQL,并且没有名为 user 的表,它将无法正常工作。
(对于我们中的一些人来说,默认的 sails-disk 可能会出现错误,如果下载的 Sails 框架版本没有正确地访问 sails-disk……那么您需要 `npm install sails-disk` 在您的项目目录中…… 甚至有时 `npm install sails` 在您的项目目录中 - 在 Windows 上我经常遇到这种情况。 我错了。在 Windows 上,我遇到这个问题是因为我没有通过管理员命令提示符运行 'sails new <project>'…… Sails 无法创建符号链接,并建议在项目下执行 npm install。)
“生成 API”命令的内部工作原理如下:
- 为具有服务名称或基本路由路径为
user
的 API 生成一个Blueprint API 模型和路由。- 除非在 api\controllers\UserController.js 和 config\routes.js 下定义了任何内容。
- 使用Waterline ORM将 API 连接到数据源,使用 model.js 下的默认连接,或使用 sails-disk 作为默认连接。
- 除非在 api\models\User.js 下覆盖了连接(是的,如果我们指定,例如,那里的 MySQL 连接,它将从不同的源加载。我们的每个模型都可以轻松地指向不同的数据连接,如果需要)。
- 如果 api\models\User.js 下没有定义结构,则使用基于数据库的默认/动态模型……如果是非关系型数据库(NoSQL),则为动态模型,因为 NoSQL 集合可以有任意数量的键……如果为 MySQL,则需要 3 个默认列(如下所述)。
理解以上内容(的庞大/巨大)非常重要。
要点 1:Sails 使用Blueprint API:Blueprint 本身就是一个广泛的框架…… something that apiary.io uses (apiary 是您今天想要在生产环境中使用的 API 的地方,而无需了解所有这些,只需使用 API)。
要点 2:Sails 使用Waterline ORM:这是 Sails 创建者创建的,它是一个 ORM,可以链接到您的实体(entities)的 No-SQL 和 SQL 数据源,并且每个模型都被单独处理。这使得 Sails 具有极大的灵活性。它还会根据底层连接的数据库更改对模型的期望。
即使有上述有趣的特性,您也可以编辑、自定义和控制您的应用程序,而无需触及 Blueprint 或 Waterline 的实现。
最后,这一切都使 Sails 成为一个有很大发展空间的框架,并且在不同的版本中会进行一些结构调整,这可能会导致重大更改。而且重要的是,需要一些耐心才能让一切正常工作……尤其是如果您才刚刚开始使用/考虑 Sails。
Sails API 生成后
现在,让我们进行连接。
- 创建您的数据库。
- 在 connections.js 中设置连接,并在 config\model.js 中将其设置为默认连接。
- 暂时将 api\models\User.js 保持为默认设置。
- 调用以下 URL,您应该会看到一个用户数组(如果用户不存在,则为空数组)。
https://:1337/user
为 API 设置数据库结构
调用以下 URL 来添加用户
https://:1337/user/create?name=nodejssailstest
如果您没有看到 500 服务器错误,请验证用户是否已添加到数据库。
现在,我们使用 MongoDB,它会在集合不存在时创建新集合,所以可能不会有问题……但如果您使用 MySQL 等数据库,您会看到类似 table user not present
的错误。
如果您使用 NoSQL,如 MongoDB
您不会遇到太多麻烦,因为它没有 SQL 需要遵守的结构。例如,在下面无需对模型或数据库进行任何更改即可正常工作。您只需要 `sails generate api monster` 来为 Blueprint 框架创建 API 路由(因为我们在下面使用了 monster)。
https://:1337/monster/create?name=nodejssailstest3&age=34&
gender=m&address=akjsdflakjdsf
如果您使用 MySQL
创建一个与您在生成服务时使用的名称相同的表(在上面的示例中,它将是 user / monster)。
以下字段是 API 在您的表设计上正常工作的最低要求。
id
列 - integer / varchar 值(* 可以自定义指向不同的主键字段名)createdAt
列 - date / datetime / timestampupdatedAt
列 - date / datetime / timestamp
提示:如果您不想显式定义模型,可以通过调用列表 URL,如 https://:1337/monster 或创建 URL 来进行操作,当出现 500 错误时,请查看 Sails 窗口中的错误并更新表结构。错误会显示 Sails 推送到 MySQL 的查询错误。但是,如果您使用的是像 MySQL 这样具有明确数据结构的数据库,那么您应该创建一个如下所示的模型定义。
api/model/User.js:
(if you are still choosing to exclude the createdAt and updatedAt columns
make sure they are there on the table structure)
module.exports = {
connection: 'myMySql',
tableName: 'user',
attributes: {
id: {
type: 'integer',
unique: true,
primaryKey: true,
columnName: 'id'
},
name: {
type: 'string',
columnName: 'name'
}
}
};
如果模型中定义了主键列,则 id
列是可选的...
如果您像下面这样在模型中显式定义一个属性,并定义了主键约束,那么 Sails 将会把主键映射到这个列,并且不会期望数据库中存在 id
列。
module.exports = {
attributes: {
name: {
type: 'string',
columnName: 'name'
},
guid: { //*** suppose your design has a guid primary key column,
//and no 'id' column.
type: 'string',
unique: true,
primaryKey: true,
columnName: 'guid'
}
}
};
NoSQL 和关系型 SQL 之间的重要用法差异
- 除了默认字段(
id
、createdAt
、updatedAt
)之外,如果您想要任何其他字段,例如 'name
' 或 'age
' 等,您必须在上面的模型中显式添加它们,否则 Sails 不知道将其映射到您的数据库列,并且在 'create
' 调用中传递值时,未显式映射的字段将被忽略。 - 如果您的数据库中的
id
列不是自动递增的,Sails 将在插入第一条记录后失败。您应该在创建 API 调用中传递 'id
' 的值。
切换数据库连接
再次,我使用以下方法在默认连接上进行尝试
under \config\model.js
//connection: 'myMySql',
connection: 'myMongo',
如果您只想在某个模型上这样做,也就是说,您确实打算为不同的模型使用多个数据库
under \api\models\your-service-name.js
module.exports = {
//connection: 'myMySql',
//tableName: 'user',
connection: 'myMongo',
...
数据验证
Sails 默认不执行任何验证。
所有数据库错误都会被转换为 API 响应并返回。因此,如果您使用 NoSQL,您可能直到使用数据时才看到数据错误。
本文的第二部分将更详细地介绍如何自定义 API 以执行此操作及更多操作……如果您愿意,可以称之为高级内容。