十分钟带你上手egg,写自己的后端接口

2 篇文章 0 订阅

前提:此篇文章是基于node.js—基于Egg框架的简单后端搭建(包含传参数据库操作)_北木南-的博客-CSDN博客_egg node.js的基础上写的,安装简单的接口你看一看这篇文章。

Gitee仓库地址Moon Painting后端_egg: 自己第一次用egg,写后端接口

这是自己写基于egg框架写的一个后台服务,有需要练习的小伙伴可以自行下载参考,注释都是很详细的,自己结合官网看是没有什么问题egg - 为企业级框架和应用而生 - Egg

 先给看看成品实例:

 

 体会:

这是第二次使用node写后端接口,也是第一次使用egg,我发现这个后端写起来其实也不难,首先你先得吧框架结构以及基础对象搞清楚,这样写的接口你自己项目的用完全是没有问题的。

项目结构:

router.js:毫无疑问就是路由,就是前台请求的URL和请求方法在这里写

controller:控制层,接收前端参数,处理参数,通过调用service对象调用service层方法进行下一步操作

service:进行数据库交互的(增删查改)

public:里面放的是一些静态资源,如图片

utils:这里面是自己后来加的,配置的是Response 

config:是项目参数插架配置的,如jwt(登录鉴权,签发token)一系列

package.json:就是项目依赖名单

常用的也就是这几个。

基础对象:

 Application:Application 是全局应用对象,在一个应用中,只会实例化一个,它继承自 Koa.Application,在它上面我们可以挂载一些全局的方法和对象。我们可以轻松的在插件或者应用中扩展 Application 对象。在框架运行时,会在 Application 实例上触发一些事件,应用开发者或者插件开发者可以监听这些事件做一些操作。作为应用开发者,我们一般会在启动自定义脚本中进行监听。

Context:Context 是一个请求级别的对象,继承自 Koa.Context。在每一次收到用户请求时,框架会实例化一个 Context 对象,这个对象封装了这次用户请求的信息,并提供了许多便捷的方法来获取请求参数或者设置响应信息。框架会将所有的 Service 挂载到 Context 实例上,一些插件也会将一些其他的方法和对象挂载到它上面(egg-sequelize 会将所有的 model 挂载在 Context 上)。

Request:Request 是一个请求级别的对象,继承自 Koa.Request。封装了 Node.js 原生的 HTTP Request 对象,提供了一系列辅助方法获取 HTTP 请求常用参数。

Response:Response 是一个请求级别的对象,继承自 Koa.Response。封装了 Node.js 原生的 HTTP Response 对象,提供了一系列辅助方法设置 HTTP 响应。

项目开始常遇到问题:

跨域:这种问题本就是后端来处理的,可以使用cors中间件配置白名单解决,这个去官网搜直接就有教程

jwt登录鉴权:jwt干啥的呢?给大家将一个流程,在你登录时jwt会给你签发一个token,你将拿到的token存储到客户端本地,下次再请求后端的时候带着token,token验证通过你才能进行登录之后的一系列操作,等你退出浏览器token就会失效。

这个自己配置不太好配置,这里记录一下我的配置:

1、npm 下载 

2、plugin.js中

3、config.defaults.js中

4、登录验证成功后,expiresIn设置的是token过期时间,我这里设置的是1200s不操作就失效,失效你就只能登录后才能访问其他接口

 获取参数

一般前端请求分为很多类别,比如最基础的post、get请求,post请求是将请求参数放在请求体里面,不会跟在接口后面的,这样参数不是明文传输就比较安全。

get请求则是明文请求,就是将参数放在请求接口后面,用户直接在url后面就能看到,这样数据是比较危险的。所以一般隐私信息就用post请求比较好,相对安全,get请求就放一些不重要的参数请求。还有一些删除等等一系列请求方式,对应不同功能,但是初学者用的比较少,感兴趣可以自己去查查。

当然不同请求后端就会有不同接受参数的方式,这里给大家整理一下常用的:

query(get)

获取 url 的 ?后面的数据,通过 ctx.query 拿到数据:

// GET /posts?category=egg&language=node
class PostController extends Controller {
  async listPosts() {
    const query = this.ctx.query;
    // {
    //   category: 'egg',
    //   language: 'node',
    // }
  }
}

 Router params(get)

获取 Router 上也可以申明参数,通过 ctx.params 拿到数据:

// app.get('/projects/:projectId/app/:appId', 'app.listApp');
// GET /projects/1/app/2
class AppController extends Controller {
  async listApp() {
  	// assert.equal 相当于 ==
    assert.equal(this.ctx.params.projectId, '1');
    assert.equal(this.ctx.params.appId, '2');
    // 或用解构赋值
    const { projectId, appId } = this.ctx.params
  }
}

body(post)

也就是 post、put、delete 等方法,框架内置了 bodyParser 中间件来对这两类格式的请求 body 解析成 object 挂载到 ctx.request.body 上。

// POST /api/posts HTTP/1.1
// Host: localhost:3000
// Content-Type: application/json; charset=UTF-8
//
// {"title": "controller", "content": "what is controller"}
class PostController extends Controller {
  async listPosts() {
    assert.equal(this.ctx.request.body.title, 'controller');
    assert.equal(this.ctx.request.body.content, 'what is controller');
  }
}

可以在 config/config.default.js 配置解析请求的大小,会覆盖框架默认值 100kb:

module.exports = {
  bodyParser: {
    jsonLimit: '1mb',
    formLimit: '1mb',
  },
};

egg的file模式

1、在 config 文件中启用 file 模式:

// config/config.default.js
exports.multipart = {
  mode: 'file',
};

2、上传 / 接收文件:
前端:

<form method="POST" action="/upload?_csrf={{ ctx.csrf | safe }}" enctype="multipart/form-data">
  title: <input name="title" />
  file: <input name="file" type="file" />
  <button type="submit">Upload</button>
</form>

后端:

// app/controller/upload.js
const Controller = require('egg').Controller;
const fs = require('mz/fs');

module.exports = class extends Controller {
  async upload() {
    const { ctx } = this;
    const file = ctx.request.files[0];
    const name = 'egg-multipart-test/' + path.basename(file.filename);
    let result;
    try {
      // 处理文件,比如上传到云端
      result = await ctx.oss.put(name, file.filepath);
    } finally {
      // 需要删除临时文件
      await fs.unlink(file.filepath);
    }

    ctx.body = {
      url: result.url,
      // 获取所有的字段值
      requestBody: ctx.request.body,
    };
  }
};

上传多个文件可以看 egg 官网 传送门

stream模式获取file

const path = require('path');
const sendToWormhole = require('stream-wormhole');
const Controller = require('egg').Controller;

class UploaderController extends Controller {
  async upload() {
    const ctx = this.ctx;
    const stream = await ctx.getFileStream();
    const name = 'egg-multipart-test/' + path.basename(stream.filename);
    // 文件处理,上传到云存储等等
    let result;
    try {
      result = await ctx.oss.put(name, stream);
    } catch (err) {
      // 必须将上传的文件流消费掉,要不然浏览器响应会卡死
      await sendToWormhole(stream);
      throw err;
    }

    ctx.body = {
      url: result.url,
      // 所有表单字段都能通过 `stream.fields` 获取到
      fields: stream.fields,
    };
  }
}

module.exports = UploaderController;

通过 ctx.getFileStream 获取文件的前提:

  1. 只支持上传一个文件。
  2. 上传文件必须在所有其他的 fields 后面,否则在拿到文件流时可能还获取不到 fields。

stream 模式上传多个文件使用 ctx.multipart()

获取header值

  1. ctx.headersctx.headerctx.request.headersctx.request.header 等价
  2. ctx.get(name)ctx.request.get(name) 获取 header 某一个字段

service层

数据库操作官网很详细 ,自己看非常简单Mygg

基于上一篇文章你就能写自己需要的接口了

上线接口地址:

我的这个接口已经上线,部署在服务器了,服务器接口地址:39.108.229.103:7001

出现hi,egg你就算能访问了,有需要就扣使用文档的可以私聊或者留言,有需要人需要处使用文档,没有就不出了

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

北木南-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值