本篇目录
Sails 安装
Sailsjs提供安装脚手架,使用之前可以先安装Sailjs
npm install sails -g
其中-g表示全局安装,这样安装之后就可以在任意一个项目(文件夹)中使用sailsjs了。
安装之后,就可以直接在nodejs里面使用sails命令行,在vscode终端(按ctrl+` 可以打开)输入:
sails new test-project //new 后面跟着的是项目名称,sails脚手架会自动创建同名子目录
接下来出现的界面里面,我们可以选择安装的模版:
Choose a template for your new Sails app:
1. Web App · Extensible project with auth, login, & password recovery
2. Empty · An empty Sails app, yours to configure
(type "?" for help, or <CTRL+> to cancel)
?
sails是可以做全站混合开发的。如果选择Web App 它将会帮我们创建全站模版,包含建议控制器和view。由于前后端分离具有更好的灵活性和松散耦合性,是目前行业比较流行的开发模式。本次项目开发我们采用前后端分离模式,因此我们只是需要的把sails当做后端来开发各种api控制器,实现数据库操作和业务逻辑。我们不需要其他Web App的模版,所以这个地方可以选择 2,创建一个空的带基础框架的Sails app。
安装完成之后,原来的目录下面后多出一个子目录test-project,里面就是一套可以执行的sails框架的源代码。这个时候vscode显示目录依然是当前目录而不是以test-project为根目录,可以通过cd指令改变当前目录到text-project,也可以在vscode中关闭文件夹,然后重新打开tst-project这个文件夹,实现以该文件夹为子目录的效果。
安装成功之后,在命令行里面执行
sails lift
或是 node app.js //sails以app.js为入口文件
启动后,可以看到如下画面,表示启动成功,当前版本号:1.5.3 运行端口:1337
info:
info: Sails <| .-..-.
info: v1.5.3 |\
info: /|.\
info: / || \
info: ,' |' \
info: .-'.-==|/_--'
info: `--'-------'
info: __---___--___---___--___---___--___
info: ____---___--___---___--___---___--___-__
info:
info: Server lifted in `E:\Writing\mytest\test-project`
info: To shut down Sails, press <CTRL> + C at any time.
info: Read more at https://sailsjs.com/support.
debug: -------------------------------------------------------
debug: :: Wed Nov 16 2022 17:18:38 GMT+0800 (中国标准时间)
debug: Environment : development
debug: Port : 1337
debug: -------------------------------------------------------
App结构
|-- test-project
|-- app.js sails启动入口
|-- package.json npm 配置文件,包含应用程序运行所依赖的所有节点模块的名称和版本
|-- README.md
|-- .tmp 编译后的静态文件
|-- api 数据模型,控制器等,MVC结构中的M和C
| |-- controllers
| |-- helpers
| |-- models
| |-- policies
|-- assets 保存sails用到的静态资源,模版文件等
|-- config 定义和配置文件
| |-- blueprints.js
| |-- bootstrap.js
| |-- custom.js
| |-- datastores.js
| |-- globals.js
| |-- http.js
| |-- i18n.js
| |-- local.js 端口设置等
| |-- log.js
| |-- models.js
| |-- policies.js
| |-- routes.js api路由设置与对应控制器的action
| |-- security.js 安全配置,比如设置跨域
| |-- session.js
| |-- sockets.js socket 服务配置,传输方法,心跳间隔,socket存储等
|-- tasks
|-- views 视图MVC里面的V,因为我们做控制器开发,views文件夹里面几乎不需要关注
修改端口
默认端口是1337,如果有需要在config/local.js里面可以修改port,例如
module.exports = {
port:1898
};
local.js会自动加载,有时候也会在这个地方加载一些需要全局使用的库,比如lodash:
- sails默认已经安装好了lodash,这是一个不错的工具库,可以通过local.js把它变成全局变量
/**
* 引入lodash,sails默认已经安装这个库,具体使用参考https://www.lodashjs.com/
*/
var _ = require('lodash');
module.exports = {
port:1898
};
跨域问题
因为我们的设计模式是前后端分离,我们的前后端是两个独立站,出于浏览器的同源策略限制(同源策略会阻止一个域的JavaScript脚本和另一个域的内容进行交互)。前端的js代码访问后端的时候将会返回跨域错误。
要解决这个问题,就需要修改config/security.js,开发前期为了测试方便,可以直接放开限制,设置如下:
module.exports.security = {
cors: {
allRoutes: true,
allowRequestMethods: 'GET, POST, PUT, DELETE, OPTIONS, HEAD',
allowOrigins: '*',
allowCredentials: false
},
}
生产环境下,可以对具体来源网站和端口进行限制。
第一个Api控制器
编写一个控制器是非常容易的,甚至都不需要自己写代码,直接使用sails脚手架就可以实现,执行以下指令,sails将自动创建一个名为helloworld的控制器
sails generate controller helloworld
执行后结果如下:
- 打开HelloworldController.js,编写控制器程序:
/**
* Hello 控制器
*/
Hello: function (req, res) {
res.status(200).send('Hello world');
},
- 增加控制器路由,打开config/routes.js,在module.exports.routes = {} 里面增加一条新路由如下:
module.exports.routes = {
'GET /api/hello':{action:'Helloworld/Hello'},
};
- 保存之后,执行
sails lift
- 在浏览器中打开:http://localhost:1337/api/hello,我们看到浏览器里显示出我们在控制器里面输出的“Hello world”,至此第一个控制器完成。
用Postman 做Api调试
我们的第一个Api采用的是Get方式请求数据,所以可以轻松通过浏览器进行请求测试。现在我们再Helloworld控制器里面再添加一个控制器,按Ctrl+C,退出Sailsjs,接下来
- 在控制器方面和上一个控制器没有什么不一样:
/**
* Post 请求
* @param {*} req
* @param {*} res
*/
TestPost: function (req, res) {
res.status(200).send('这是一个POST方式的请求测试');
},
- 在config/routes.js,新增一个路由
module.exports.routes = {
'GET /api/hello':{action:'Helloworld/Hello'},
'POST /api/testpost':{action:'Helloworld/TestPost'},//新增控制器
};
保存后,重新运行sails lift
- 使用 Postman
由于我们在路由器里面写的请求方式是POST,这个时候如果还是在浏览器地址栏里面输入网址http://localhost:1337/api/testpost,就会出现404错误。这种情况就需要Postman。Postman是一种常用的接口测试工具 点击下载 ,详见:https://www.postman.com/
下载安装之后,在postman里面,添加post请求,如下
MySql
为了更好的做数据库调试,如果是单人开发,可以自己安装MySql,如果是多人开发,可以考虑把MySql安装到云服务器,大家共同访问云服务器中的数据库。
我们以独立安装MySql为例,先到MySql官网下载社区版,下载地址,选择社区版下载,现在的版本号是8.0以上。下载后安装即可。另外可以再安装Navicat或是HeidiSQL之类的数据库连接和管理工具。
命令行操作MySql
- 找到mysql安装位置(mysql.exe所在目录),默认是C:\Program Files\MySQL\MySQL Server 8.0\bin,在空白处按住Shift+右单击,选择“在此处打开PowerShell 窗口”
- 输入 .\mysql -uroot -p123456 (这里.\mysql 是指本目录下的mysql指令 -u后面是用户名 -p后面是密码,实际数据根据自己设置的账号密码修改
- 至此我们已经用root账号,通过命令行登录mysql,可以执行后面的语句,执行完如果需要退出,可以打入 \quit 指令
8.0版本加密问题
MySQL8.0版本的加密方式(caching_sha2_password)和旧版本(mysql_native_password)不一样,目前Node还不支持caching_sha2_password加密方式。所以Sails连接MySql会有问题。修改调整MySql服务器的加密方式
- 更改加密方式 以 root账号为例,设置密码不过期 (可选)
ALTER USER 'root'@'localhost' IDENTIFIED BY 'password' PASSWORD EXPIRE NEVER;
- 修改密码,以下示例中 123456为新密码并且使用旧版本的加密方式mysql_native_password。
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '123456';
- 刷新:
FLUSH PRIVILEGES;
- 退出命令行的mysql
\quit
- 重启服务
进入windows服务管理,重启MySql80 服务 或者执行net stop mysql80 和 net start mysql80 指令
Sails 操作Mysql
- 在mysql上面创建一个数据库,比如admindata。
- 打开vscode,在终端中安装sails-mysql
npm intall sails-mysql -save
如果安装成功,可以看到package-json里面的依赖库会多一个"sails-mysql": “^3.0.0”
- 打开config/datastores 配置数据存储选项,在module.exports.datastores 的default属性内添加mysql适配器如下:其中url里面包含mysql用户名密码和数据库名称
adapter: 'sails-mysql',
url: 'mysql://root:123456@localhost:3306/admindata',
- 设置config/model
这个文件用于配置数据模型,有几个需要关注的设置
- schema: true, 这是设置严格匹配数据表的模式,建议设置为true,一般只要使用类似MongoDB这种非关系型数据库才会设置为false。
This setting is only relevant for models using schemaless databases like MongoDB
- migrate: 数据迁移配置,有三个选项:‘alter‘,‘’safe’,‘drop’, 其中:
- alter:与老数据自动合并,保留旧数据,但是如果修改旧字段类型并且有旧的数据,会提示错误,推荐使用。
- safe:sails启动的时候,不检查数据库,也不删除数据表。一般在开发结束使用。
- drop:sails启动的时候,会删除数据库中的所有表里面的数据,并且没有提示。一般在开发前期使用(慎重)。
alter 选项遇到mysql8.0 带有加密字段的时候,如果有旧数据,会出错,必须删除旧数据才能继续。这个是一个Bug,应该和MySql默认采用的authentication plugin是caching_sha2_password有关系。 MariaDB或其它版本MySql不会有这样的问题。
- attributes:
- 这个地方用来配置一些共有属性,比如每个表都要有个id,那么我们可以这样写
- id:{type:‘number’,autoIncrement:true}
- 考虑到在表的更新的时候,需要判断是否是最新,以及后面可能会用到的创建时间,我们可以添加两个每个表都会自动添加的属性createAt和updateAt 并且都分别设置为autoCreateAt和autoUpdateAt,照这个思路,attributes可以这样写:
- 这个地方用来配置一些共有属性,比如每个表都要有个id,那么我们可以这样写
attributes: {
createdAt: { type: 'number', autoCreatedAt: true, },
updatedAt: { type: 'number', autoUpdatedAt: true, },
id: { type: 'number', autoIncrement: true, },
},
- cascadeOnDestroy:关联删除,可以开启cascadeOnDestroy功能,用于如One-to-many关系下的关联删除。
- dataEncryptionKeys:对称加密密钥,可以配置对敏感属性数据加密时的密钥,比如密码字段等
创建第一个model
一个 model表示一组结构化数据,称为记录。model通常对应于数据库中的表/集合,attribute对应于列/字段,record对应于行/文档。基于现代程序设计的convention over configuration (约定大于配置)原则。model一般是由放在Sails应用程序的api/models/文件夹中创建文件来定义的。
我们尝试定义一个用户数据模型,在api/models/文件夹中创建user.js,代码如下:
module.exports = {
attributes: {
email: { type: 'string'},
password: { type: 'string'}
},
};
作为示例,这是一个非常简单的用户数据,里面只有email和password,后面再根据情况扩展。
实现一个model的增删改查
通过sails脚手架执行创建控制器指令(也可以通过在api/controllers 遵守文件名和控制器名称约定手动添加)
sails generate controller user
打开UserController.js,修改代码如下:
/**
* UserController
*
* @description :: Server-side actions for handling incoming requests.
* @help :: See https://sailsjs.com/docs/concepts/actions
*/
module.exports = {
//新增一条用户记录
create: async function (req, res) {
let result=await user.create({email:'abc@gmail.com',password:'123456'}).fetch();
return res.status(200).send(result);
},
};
添加路由:打开config/routes.js,添加路由如下:
'POST /api/testpost':{action:'user/create'},
打开postman,post到localhost:1337/api/testpost,测试结果如下:因为我们采用fetch,添加完数据之后,会返回我们添加的数据。我们发现返回的数据里面有createAt,updateAt,id三个字段,并且都自动赋值。这个就是我们在config/models.js里面设置的自动添加到每个表的配置。
使用Navicat或HeidiSQL之类第三方工具,打开MySql或MariaDB查看我们的admindata数据库,发现里面除了user表,还有一个archive,这个是sails自动生成的归档表。打开user表,可以看到id已经设为自动增长。sails的orm(waterline)已经帮我们做了许多的工作。
删除和修改操作先略过,我们会在下一篇Typescript的应用继续讲解。