如何用Eggjs从零开始开发一个项目(1)
前言
“纸上得来终觉浅,绝知此事要躬行。”虽然node一直在断断续续地学,但总是东一榔头西一榔头的,没有一点系统,所以打算写一个项目来串联一下之前的学习成果。
为什么选择Eggjs呢?其实我觉得如果是个人开发或者小型项目Koa就足够轻量与灵活了,但是如果是有过团队开发的经历,就会更注重项目的管理。Eggjs项目相对于Koa我比较看中的有以下几点:
- 完善的文档,这意味不管是交接还是项目有新成员加入,直接把官方文档甩出去就行了,而且官方文档同时也是一个很好的学习材料;
- Egg 奉行『约定优于配置』。我很中意这个设定,在多人协作的项目中,我们有时候需要花很多功夫来统一不同的编程习惯,比如有人喜欢把公用的方法放到utils/index文件夹中,有的干脆直接建一个utils.js,还有的util不加s的,这些都没有对错之分,但是多人协作项目中会使得项目混乱,难以管理,增加code review的成本。『约定优于配置』则很好地解决了这个问题,大家都统一按官方要求写,有偏差的直接翻文档,没有撕逼了;
- 基于Koa,所以Koa的轮子做一下适配就能用,不担心生态问题。
我也是一个node菜鸟,所以这个系列我会按照自己从零实现的步骤去记录整个开发过程。
创建一个Eggjs项目
$ mkdir egg-server && cd egg-server
$ npm init egg --type=simple
$ npm i
OK,项目初始成功了,下面我们的任务是链接数据库。
数据库链接
数据库我选择mysql,毕竟行业主流嘛,这里我们使用Sequelize来管理、操作数据库,Sequelize 是一个基于 promise 的 Node.js ORM,这样你就不用去写一坨一坨的sql语句了。数据库安装这里就不细说了,跟着菜鸟教程安装就好了。安装好并打开数据库。
安装并配置 egg-sequelize 插件(它会辅助我们将定义好的 Model 对象加载到 app 和 ctx 上)和 mysql2 模块:
npm install --save egg-sequelize mysql2
在
app/config/plugin.js中引入插件(egg中引入插件都需要在这个文件中配置):sequelize: {
enable: true,
package: 'egg-sequelize',
}
在
app/config/config.default.js中配置Sequelize的配置项:config.sequelize = {
dialect: 'mysql', // 表示使用mysql
host: '127.0.0.1', // 连接的数据库主机地址
port: 3306, // mysql服务端口
database: 'egg-db', // 数据库名
username: 'root', // 你的数据库用户名
password: 'root', // 你的数据库密码
define: {
timestamps: true, // 默认添加createdAt,updatedAt,deletedAt时间戳
paranoid: true, // 设置软删除,删除时不删除数据,而是通过更新deleteAt标识删除
freezeTableName: true, // 冻结表名,防止建表时表名修改为复数形式
underscored: false, // 防止驼峰式字段被转为下划线
},
// 这里有坑,sequelize用的是UTC时间,我们在东八区,所以要加8
// https://stackoverflow.com/questions/47367893/sequelize-reads-datetime-in-utc-only
dialectOptions: {
dateStrings: true,
typeCast(field, next) {
if (field.type === 'DATETIME') {
return field.string();
}
return next();
},
},
timezone: '+8:00',
};
创建
model在
app文件夹下创建一个model文件夹,所有的model文件都放在这里,现在我们创建一个user的model,创建以下文件app/model/user.js。module.exports = (app) => {
const { STRING, INTEGER } = app.Sequelize;
const User = app.model.define('user', {
id: {
type: INTEGER,
autoIncrement: true, //自增
primaryKey: true, //设置为主键
},
name: STRING(20),
password: STRING(100),
phone: STRING(11),
email: STRING(30),
});
return User;
};
OK,现在数据库这块好像都处理的差不多了,那接下来就开些写一下代码,快乐地进行CRUD吧~
编写controller
创建
app/controller/user.js文件,写入以下内容:const Controller = require('egg').Controller; class UserController extends Controller {
// 添加user
async createUser() {
const params = this.ctx.request.body;
const user = await this.ctx.model.User.create({
...params
});
if (user) {
this.ctx.body = {
code: 200,
data: user
};
} else {
this.ctx.throw(500, 'internal server error');
}
} // 获取所有的user
async getUsers() {
const users = await this.ctx.model.User.findAll();
this.ctx.body = {
code: 200,
data: users
};
}
} module.exports = UserController;添加路由
在
app/router.js中添加getUsers和createUser的路由,代码如下:module.exports = app => {
const { router, controller } = app;
router.get('/', controller.home.index);
+ router.post('/createUser', controller.user.createUser);
+ router.get('/getUsers', controller.user.getUsers);
};
测试功能
这个时候我们的代码已经基本完成,请求对应的路由就可以看到对应的数据库变化了,但是我们在请求之前不要忘记在数据库创建对应的数据库和user表哦,不然会报错的,现在可以手动的去创建,后面我们可以借助
Sequelize帮我们在项目启动的时候自动创建并更新表。一切准备妥当之后,打开Postman来试试吧,通过get请求
localhost:7001/getUsers得到以下数据:{
"code": 200,
"data": []
}
这个时候,表是空的,所以查不到,那我们来通过post请求来访问
localhost:7001/createUser来创建一条数据:{
"name":"curry",
"password":"test1234",
"phone":"13412341234",
"email":"test@gmai.com"
}
然而,这个时候报错了:
invalid csrf token. See https://eggjs.org/zh-cn/core/security.html#安全威胁csrf的防范
看一下文档怎么说的:
CSRF(Cross-site request forgery跨站请求伪造,也被称为
One Click Attack或者Session Riding,通常缩写为 CSRF 或者 XSRF,是一种对网站的恶意利用。 CSRF 攻击会对网站发起恶意伪造的请求,严重影响网站的安全。因此框架内置了 CSRF 防范方案。这是Eggjs框架的安全策略,我们在开发的时候可以先关掉,在
app/onfig/config.default.js中添加以下代码:config.security = {
csrf: {
enable: false
}
};
改好以后让我们再试一次:
{
"code": 200,
"data": {
"id": 1,
"name": "curry",
"password": "test1234",
"phone": "13412341234",
"email": "test@gmai.com",
"updatedAt": "2020-12-13T07:39:29.990Z",
"createdAt": "2020-12-13T07:39:29.990Z"
}
}
成功了!打开数据库刷新一下user表看看,已经插入了这条数据,再重新通过get请求
localhost:7001/getUsers:{
"code": 200,
"data": [
{
"id": 1,
"name": "curry",
"password": "test1234",
"phone": "13412341234",
"email": "test@gmai.com",
"createdAt": "2020-12-13 15:39:29",
"updatedAt": "2020-12-13 15:39:29",
"deletedAt": null
}
]
}
Well done!一番折腾以后终于看到了成果,但这只是开始,后面我们会继续实现用户的注册、登录功能,涉及到用户注册时密码的处理,用户认证等功能。
如何用Eggjs从零开始开发一个项目(1)的更多相关文章
- 如何用Eggjs从零开始开发一个项目(2)
在上一篇文章,我们已经使用Sequelize连接上了数据库,并能进行简单的数据库操作,在此基础上,我们试着来开发一个完整的项目.这篇文章我们从用户的注册.登录着手,试着开发用户模块的相关的代码. 用户 ...
- 如何用Eggjs从零开始开发一个项目(3)
上一篇中我们编写了用户注册登录.登录的代码,学习了如何进行用户的认证(JWT),如何安全地存储用的密码(hash).这一篇我们有以下2个任务: 获取token中的数据: 通过model来同步数据库. ...
- Cordova之如何用命令行创建一个项目(完整示例)
原文:Cordova之如何用命令行创建一个项目(完整示例) 1. 创建cordova项目 (注意:当第一次创建或编译项目的时候,可能系统会自动下载一些东西,需要一些时间.) 在某个目录下创建cordo ...
- YII框架开发一个项目的通用目录结构
YII框架开发一个项目的通用目录结构: 3 testdrive/ 4 index.php Web 应用入口脚本文件 5 assets/ 包含公开的资源文件 6 css/ 包含 CSS 文件 7 ima ...
- github如何多人开发一个项目
github如何多人开发一个项目 一.总结 一句话总结:a.点项目里面的Settings->Collaborators,来添加参与者(比如github用户名), b.向他发送项目的link,让他 ...
- 从零开始, 开发一个 Web Office 套件 (2): 富文本编辑器
书接前文: 从零开始, 开发一个 Web Office 套件 (1): 富文本编辑器 这是一个系列博客, 最终目的是要做一个基于HTML Canvas 的, 类似于微软 Office 的 Web Of ...
- 从零开始, 开发一个 Web Office 套件 (3): 鼠标事件
这是一个系列博客, 最终目的是要做一个基于HTML Canvas 的, 类似于微软 Office 的 Web Office 套件, 包括: 文档, 表格, 幻灯片... 等等. 对应的Github r ...
- 从零开始, 开发一个 Web Office 套件(4):新的问题—— z-index
<从零开始, 开发一个 Web Office 套件>系列博客目录 这是一个系列博客, 最终目的是要做一个基于HTML Canvas 的, 类似于微软 Office 的 Web Office ...
- 《从零开始, 开发一个 Web Office 套件》系列博客目录
这是一个系列博客, 最终目的是要做一个基于HTML Canvas 的, 类似于微软 Office 的 Web Office 套件, 包括: 文档, 表格, 幻灯片... 等等. 对应的Github r ...
随机推荐
- DoTween动画插件学习
一.简单的变量插值运算 using System.Collections; using System.Collections.Generic; using UnityEngine; using DG. ...
- idea2018 快捷键
Alt+Enter将光标放到缺少包的错误提示处自动导入包Ctrl+Alt+Space光标处会有会出现界面提示需要补全的信息也可以在new完对象后使用.var后将会自动补 Ctrl+O可以选择父类的方法 ...
- P4254 [JSOI2008]Blue Mary开公司 (李超树)
题意:插入一些一次函数线段 每次询问在x = x0处这些线段的最大值 题解:李超树模版题 维护优势线段 注意这题的输入是x=1时的b #include <iostream> #includ ...
- AC自动机——看似KMP在跑,其实fail在跳
先存代码 AC自动机(简单版) #include<bits/stdc++.h> #define maxn 1000007 using namespace std; int n,ans; i ...
- MySQL8.0数据库出现的问题——外码创建方式、外键约束两个引用列不兼容问题、check约束问题、用触发器代替check约束、关键字DELIMITER、删除添加索引、删除添加外键约束、和一些数据库方面的操作
一.首先先说一下我们都需要建立那些表 mysql> CREATE TABLE IF NOT EXISTS `student`( -> `sno` CHAR(8) NOT NULL, -&g ...
- - 迷宫问题 POJ - 3984 bfs记录路径并输出最短路径
定义一个二维数组: int maze[5][5] = { 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, ...
- Codeforces Round #655 (Div. 2) C. Omkar and Baseball (思维)
题意:有一个数组,每次可以修改子数组,但是修改后每个元素的位置都必须变化,求最少修改多少次使得这个数组有序. 题解:假如这个数组本来就有序,我们直接输出0.否则,对于数组两端,假如它们有序,那么我们可 ...
- python常用连接字符串
1.使用占位符% print(('%s%s%s' % ('one','two', 'three'))) 2.'+'号连接 字符串是不可变对象,每次改变会申请一块新的内存,操作符+连接字符串的时候会涉及 ...
- Python3.5 配置MySql数据库连接
#!coding:utf-8 import pymysql ''' Python3之后不再支持MySQLdb的方式进行访问mysql数据库: 可以采用pymysql的方式 连接方式: 1.导包 imp ...
- [Python] Pandas的delete、drop函数的用法
目录 drop函数 Axis(轴)含义 drop用法实验 delete函数 drop函数 DataFrame.drop(labels=None, axis=0, index=None, columns ...