iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >egg.js的基本使用实例
  • 769
分享到

egg.js的基本使用实例

2024-04-02 19:04:59 769人浏览 安东尼
摘要

目录安装egg.js写第一个api接口创建控制器编写路由关闭csrf开启跨域数据库配置和创建迁移文件创建数据迁移表模型创建模型错误和异常处理中间件参数验证安装egg.js 全局切换镜

安装egg.js

全局切换镜像: 
npm config set reGIStry https://registry.npm.taobao.org

我们推荐直接使用脚手架,只需几条简单指令,即可快速生成项目npm >=6.1.0):

mkdir egg-example && cd egg-example
npm init egg --type=simple --registry Https://registry.npm.taobao.org
npm i

启动项目:

npm run dev
open http://localhost:7001

写第一个api接口

安装vscode扩展

创建控制器

async index() {
    const { ctx } = this;
    // 获取路由get传值参数(路由:id)
    ctx.params;
    // 获取url的问号get传值参数
    ctx.query;
    // 响应
    ctx.body = '响应';
    // 状态码
	ctx.status = 201;
}

编写路由

基础用法

// router.js
router.get('/admin/:id', controller.admin.index);

// controller
async index() {
    const { ctx } = this;
    // 获取路由get传值参数(路由:id)
    ctx.params;
    // 获取url的问号get传值参数
    ctx.query;
}

资源路由

// app/router.js
module.exports = app => {
  const { router, controller } = app;
  router.resources('posts', '/api/posts', controller.posts);
  // app/controller/v1/users.js
  router.resources('users', '/api/v1/users', controller.v1.users); 
};

上面代码就在 /posts 路径上部署了一组 CRUD 路径结构,对应的 Controller 为 app/controller/posts.js 接下来, 你只需要在 posts.js 里面实现对应的函数就可以了。

MethodPathRoute NameController.Action
GET/postspostsapp.controllers.posts.index
GET/posts/newnew_postapp.controllers.posts.new
GET/posts/:idpostapp.controllers.posts.show
GET/posts/:id/editedit_postapp.controllers.posts.edit
POST/postspostsapp.controllers.posts.create
PUT/posts/:idpostapp.controllers.posts.update
DELETE/posts/:idpostapp.controllers.posts.destroy
// app/controller/posts.js

// 列表页
exports.index = async () => {};
// 新增表单页
exports.new = async () => {};
// 新增逻辑
exports.create = async () => {};
// 详情页
exports.show = async () => {};
// 编辑表单页
exports.edit = async () => {};
// 更新逻辑
exports.update = async () => {};
// 删除逻辑
exports.destroy = async () => {};

路由分组

// app/router.js
module.exports = app => {
  require('./router/news')(app);
  require('./router/admin')(app);
};

// app/router/news.js
module.exports = app => {
  app.router.get('/news/list', app.controller.news.list);
  app.router.get('/news/detail', app.controller.news.detail);
};

// app/router/admin.js
module.exports = app => {
  app.router.get('/admin/user', app.controller.admin.user);
  app.router.get('/admin/log', app.controller.admin.log);
};

关闭csrf开启跨域

文档:https://www.npmjs.com/package/egg-cors

安装npm i egg-cors --save

配置插件

// {app_root}/config/plugin.js
exports.cors = {
  enable: true,
  package: 'egg-cors',
};

config / config.default.js 目录下配置

  config.security = {
    // 关闭 csrf
    csrf: {
      enable: false,
    },
     // 跨域白名单
    domainWhiteList: [ 'http://localhost:3000' ],
  };
  // 允许跨域的方法
  config.cors = {
    origin: '*',
    allowMethods: 'GET, PUT, POST, DELETE, PATCH'
  };

数据库

配置和创建迁移文件

配置 安装并配置egg-sequelize插件(它会辅助我们将定义好的 Model 对象加载到 app 和 ctx 上)和Mysql2模块:

npm install --save egg-sequelize mysql2

config/plugin.js中引入 egg-sequelize 插件

exports.sequelize = {
  enable: true,
  package: 'egg-sequelize',
};

config/config.default.js

config.sequelize = {
    dialect:  'mysql',
    host:  '127.0.0.1',
    username: 'root',
    passWord:  'root',
    port:  3306,
    database:  'eggapi',
    // 中国时区
    timezone:  '+08:00',
    define: {
        // 取消数据表名复数
        freezeTableName: true,
        // 自动写入时间戳 created_at updated_at
        timestamps: true,
        // 字段生成软删除时间戳 deleted_at
        paranoid: true,
        createdAt: 'created_at',
        updatedAt: 'updated_at',
        deletedAt: 'deleted_at',
        // 所有驼峰命名格式化
        underscored: true
    }
};

sequelize 提供了sequelize-cli工具来实现Migrations,我们也可以在 egg 项目中引入 sequelize-cli。

npm install --save-dev sequelize-cli

egg 项目中,我们希望将所有数据库 Migrations 相关的内容都放在database目录下,所以我们在项目根目录下新建一个.sequelizerc配置文件:

'use strict';

const path = require('path');

module.exports = {
  config: path.join(__dirname, 'database/config.JSON'),
  'migrations-path': path.join(__dirname, 'database/migrations'),
  'seeders-path': path.join(__dirname, 'database/seeders'),
  'models-path': path.join(__dirname, 'app/model'),
};

初始化 Migrations 配置文件和目录

npx sequelize init:config
npx sequelize init:migrations
// npx sequelize init:models

行完后会生成database/config.json文件和database/migrations目录,我们修改一下database/config.json中的内容,将其改成我们项目中使用的数据库配置:

{
  "development": {
    "username": "root",
    "password": null,
    "database": "eggapi",
    "host": "127.0.0.1",
    "dialect": "mysql",
    "timezone": "+08:00"
  }
}

创建数据库

npx sequelize db:create

创建数据迁移表

npx sequelize migration:generate --name=init-user

1.执行完命令后,会在database / migrations / 目录下生成数据表迁移文件,然后定义

'use strict';

module.exports = {
    up: async (queryInterface, Sequelize) => {
        const { INTEGER, STRING, DATE, ENUM } = Sequelize;
        // 创建表
        await queryInterface.createTable('user', {
            id: { type: INTEGER(20).UNSIGNED, primaryKey: true, autoIncrement: true },
            username: { type: STRING(30), allowNull: false, defaultValue: '', comment: '用户名称', unique: true},
            password: { type: STRING(200), allowNull: false, defaultValue: '' },
            avatar_url: { type: STRING(200), allowNull: true, defaultValue: '' },
            sex: { type: ENUM, values: ['男','女','保密'], allowNull: true, defaultValue: '男', comment: '用户性别'},
            created_at: DATE,
            updated_at: DATE
        });
    },

    down: async queryInterface => {
        await queryInterface.dropTable('user')
    }
};

执行 migrate 进行数据库变更

# 升级数据库
npx sequelize db:migrate
# 如果有问题需要回滚,可以通过 `db:migrate:undo` 回退一个变更
# npx sequelize db:migrate:undo
# 可以通过 `db:migrate:undo:all` 回退到初始状态
# npx sequelize db:migrate:undo:all

模型

创建模型

// app / model / user.js

'use strict';
module.exports = app => {
  const { STRING, INTEGER, DATE } = app.Sequelize;
  // 配置(重要:一定要配置详细,一定要!!!)
  const User = app.model.define('user', {
    id: { type: INTEGER(20).UNSIGNED, primaryKey: true, autoIncrement: true },
      username: { type: STRING(30), allowNull: false, defaultValue: '', comment: '用户名称', unique: true},
      password: { type: STRING(200), allowNull: false, defaultValue: '' },
      avatar_url: { type: STRING(200), allowNull: true, defaultValue: '' },
      sex: { type: ENUM, values: ['男','女','保密'], allowNull: true, defaultValue: '男', comment: '用户性别'},
      created_at: DATE,
      updated_at: DATE
  },{
    timestamps: true, // 是否自动写入时间戳
    tableName: 'user', // 自定义数据表名称
 });

  return User;
};

这个 Model 就可以在 Controller 和 Service 中通过 app.model.User 或者 ctx.model.User 访问到了,例如我们编写 app/controller/user.js

// app/controller/user.js
const Controller = require('egg').Controller;

function toInt(str) {
  if (typeof str === 'number') return str;
  if (!str) return str;
  return parseInt(str, 10) || 0;
}

class UserController extends Controller {
  async index() {
    const ctx = this.ctx;
    let keyword = this.ctx.params.keyword;
    let Op = this.app.Sequelize.Op;
    ctx.body = await ctx.model.User.findAll({ 
        where:{
            id:{
                [Op.gt]:6
            },
            username: {
              	[Op.like]:'%'+keyword+'%'
            }
        },
        attributes:['id','username','sex'],
        order:[
            ['id','DESC']
        ],
        limit: toInt(ctx.query.limit), 
        offset: toInt(ctx.query.offset) 
    });
  }

  async show() {
    let id = parseInt(this.ctx.params.id);
      // 通过主键查询单个数据
      // let detail = await this.app.model.User.findByPk(id);
      // if (!detail) {
      //     return this.ctx.body = {
      //         msg: "fail",
      //         data: "用户不存在"
      //     }
      // }

      // 查询单个
      let detail = await this.app.model.User.findOne({
          where: {
              id,
              sex: "女"
          }
      });

      this.ctx.body = {
          msg: 'ok',
          data: detail
      };
  }

  async create() {
    const ctx = this.ctx;
    const { name, age } = ctx.request.body;
    // 创建单条记录
    const user = await ctx.model.User.create({ name, age });
    // 批量创建
    await ctx.model.User.bulkCreate([{
        name: "第一个",
        age: 15
    },
    {
        name: "第二个",
        age: 15
    },
    {
        name: "第三个",
        age: 15
    }]);
    ctx.status = 201;
    ctx.body = user;
  }

  async update() {
    const ctx = this.ctx;
    const id = toInt(ctx.params.id);
    const user = await ctx.model.User.findByPk(id);
    if (!user) {
      ctx.status = 404;
      return;
    }

    const { name, age } = ctx.request.body;
    await user.update({ name, age });
    ctx.body = user;
  }

  async destroy() {
    const ctx = this.ctx;
    const id = toInt(ctx.params.id);
    const user = await ctx.model.User.findByPk(id);
    if (!user) {
      ctx.status = 404;
      return;
    }

    await user.destroy();
    ctx.status = 200;
  }
}

module.exports = UserController;

最后我们将这个 controller 挂载到路由上:

// app/router.js
module.exports = app => {
  const { router, controller } = app;
  router.resources('user', '/user', controller.user);
};

针对 users 表的 CURD 操作的接口就开发完了

错误和异常处理

// app/middleware/error_handler.js
module.exports = (option, app) => {
    return async function errorHandler(ctx, next) {
      try {
        await next();
      } catch (err) {
        // 所有的异常都在 app 上触发一个 error 事件,框架会记录一条错误日志
        ctx.app.emit('error', err, ctx);
  
        const status = err.status || 500;
        // 生产环境时 500 错误的详细错误内容不返回给客户端,因为可能包含敏感信息
        const error = status === 500 && ctx.app.config.env === 'prod'
          ? 'Internal Server Error'
          : err.message;
  
        // 从 error 对象上读出各个属性,设置到响应中
        ctx.body = { error };
        if (status === 422) {
          ctx.body.detail = err.errors;
        }
        ctx.status = status;
      }
    };
  };

中间件

config.middleware = ['errorHandler'];

config.errorHandler = {
    ceshi: 123,
    // 通用配置(以下是重点)
    enable:true, // 控制中间件是否开启。
    match:'/news', // 设置只有符合某些规则的请求才会经过这个中间件(匹配路由)
    ignore:'/shop' // 设置符合某些规则的请求不经过这个中间件。

    

    // match 和 ignore 支持多种类型的配置方式:字符串、正则、函数(推荐)
    match(ctx) {
        // 只有 iOS 设备才开启
        const reg = /iphone|ipad|ipod/i;
        return reg.test(ctx.get('user-agent'));
    },
};

参数验证

https://www.npmjs.com/package/egg-valparams

npm i egg-valparams --save
// config/plugin.js
valparams : {
  enable : true,
  package: 'egg-valparams'
},
// config/config.default.js
config.valparams = {
    locale    : 'zh-cn',
    throwError: false
};
class XXXController extends app.Controller {
  // ...
  async XXX() {
    const {ctx} = this;
    ctx.validate({
      system  : {type: 'string', required: false, defValue: 'account', desc: '系统名称'},
      token   : {type: 'string', required: true, desc: 'token 验证'},
      redirect: {type: 'string', required: false, desc: '登录跳转'}
    });
    // if (config.throwError === false)
    if(ctx.paramErrors) {
      // get error infos from `ctx.paramErrors`;
    }
    let params = ctx.params;
    let {query, body} = ctx.request;
    // ctx.params        = validater.ret.params;
    // ctx.request.query = validater.ret.query;
    // ctx.request.body  = validater.ret.body;
    // ...
    ctx.body = query;
  }
  // ...
}

 到此这篇关于egg.js的基本使用实例的文章就介绍到这了,更多相关egg.js基本使用内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: egg.js的基本使用实例

本文链接: https://www.lsjlt.com/news/146298.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • egg.js的基本使用实例
    目录安装egg.js写第一个api接口创建控制器编写路由关闭csrf开启跨域数据库配置和创建迁移文件创建数据迁移表模型创建模型错误和异常处理中间件参数验证安装egg.js 全局切换镜...
    99+
    2022-11-13
  • Java NIO的基本使用实例
    这篇文章主要介绍“Java NIO的基本使用实例”,在日常操作中,相信很多人在Java NIO的基本使用实例问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java NIO的基本使用实例”的疑惑有所帮助!接下来...
    99+
    2023-06-17
  • 轻松搭建基于 Serverless 的 Egg.js Web 应用
    首先介绍下在本文出现的几个比较重要的概念:函数计算(Function Compute): 函数计算是一个事件驱动的服务,通过函数计算,用户无需管理服务器等运行情况,只需编写代码并上传。函数计算准备计算资源,并以弹性伸缩的方式运行用户代码,而...
    99+
    2023-06-04
  • ES6中常见基本知识点的基本使用实例汇总
    目录前言1、字面量的增强2、解构Destructuring3、let和const4、作用域5、模板子符串6、函数7、展开语法8、数值表示9、Symbol的基本使用10、Set11、W...
    99+
    2022-11-13
  • vue具名插槽的基本使用实例
    前言 具有名字的插槽slot使用 中的 "name" 属性绑定元素 注意: 1,如果没有匹配到 则放到匿名的插槽中 2,具名插槽的渲染顺序,完全取决于模板,而不是取决于父组件中...
    99+
    2022-11-12
  • Vue3中vuex的基本使用方法实例
    目录一、基本结构二、基本使用三、将store中的数据模块化后的使用1.模块化2.使用补充:如何改变vuex中的属性总结 一、基本结构 src/store/index.js中...
    99+
    2022-11-13
  • SQL中游标(cursor)的基本使用实例
    目录 类型:1.普通游标2.滚动游标具体FETCH用法:Arguments总结 类型:   1.普通游标   只有NEXT操作   2.滚动游标 有多种操作 1.普通游标 DEC...
    99+
    2022-11-12
  • JavaScript中Set基本使用方法实例
    目录介绍基本API1. 创建Set实例2. Set实例转数组3. size属性4. add()5. has()6. delete()7. clear()8. 迭代补充:JS...
    99+
    2022-11-16
    js set使用 js中set用法 javascript set
  • sass在react中的基本使用(实例详解)
    目录1. 安装sass2. 编写App.tsx中的基本DOM3. sass变量4. sass中的选择器嵌套和属性嵌套5. sass中的@import和Partials6. Sass中...
    99+
    2022-11-13
  • JavaWeb之Ajax的基本使用与实战案例
    目录一、Ajax是什么?二、为什么使用Ajax?三、Ajax基本使用1、$.ajax()2、$.post() 3.$.get() 四、案例无刷新登录(ajax、g...
    99+
    2022-11-13
    java web ajax javaweb ajax使用 Ajax的使用
  • 关于SpringSecurity的基本使用示例
    目录一、使用1、直接引入依赖使用(不连接数据库)1.1 引入依赖1.2 启动项目随机访问controller的一个接口2、结合数据库使用2.1 编写类实现UserDetailsSer...
    99+
    2023-05-19
    SpringSecurity SpringSecurity 示例
  • docker基本命令及使用实例详解
    目录docker基本命令docker文件系统commit镜像容器数据卷具名和匿名挂载初识Dockerfile commitDockerfile 构建过程发布自己的镜像docker网络...
    99+
    2022-11-13
  • Javascript基本语法实例用法
    本篇内容介绍了“Javascript基本语法实例用法”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!代码&l...
    99+
    2022-10-19
  • vue3.x中emits的基本用法实例
    这是官方的文字介绍。emits重要用于组件之间的通信,触发自定义事件,传递参数。 下面演示一个子组件把事件传递到父组件,组件间通信的例子。 <template> ...
    99+
    2022-11-13
  • GoJs基本使用示例详解
    目录使用gojs背景gojs的引入去除水印使用gojs背景 因为公司业务需要,需要完成一个树形的关系图,并且在后续过程中会对树形关系图进行很多的交互来拓展树形图的展示。因此在研究了D...
    99+
    2023-05-16
    GoJs基本使用 GoJs 使用
  • AndroidWebView控件基本使用示例
    Android WebView用于在 android 中显示网页。可以从相同的应用程序或 URL 加载网页。它用于在 android 活动中显示在线内容。 Android WebVi...
    99+
    2022-11-12
  • Vue webpack的基本使用示例教程
    目录前端工程化 小白眼中的前端开发 vs 实际的前端开发 什么是前端工程化 前端工程化的解决方案webpack的基本使用  什么是webpac...
    99+
    2022-12-22
    Vue webpack的基本使用 Vue webpack使用
  • 使用egg.js实现手机、验证码注册的项目实践
    目录手机号注册、验证码校验app/contrpoller/pass.jsmode/user.jsrouter.js 路由配置service.js获取验证码 sendmsg....
    99+
    2022-11-13
  • MySQL中JOIN连接的基本用法实例
    目录join流程详解一、笛卡尔积:CROSS JOIN二、内连接:INNER JOIN三、左连接:LEFT JOIN四、右连接:RIGHT JOIN五、全连接:O...
    99+
    2022-11-13
  • HTML基本语法和语义使用实例分析
    本文小编为大家详细介绍“HTML基本语法和语义使用实例分析”,内容详细,步骤清晰,细节处理妥当,希望这篇“HTML基本语法和语义使用实例分析”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新...
    99+
    2022-10-19
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作