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


    前提:此篇文章是基于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 拿到数据:

    1. // GET /posts?category=egg&language=node
    2. class PostController extends Controller {
    3. async listPosts() {
    4. const query = this.ctx.query;
    5. // {
    6. // category: 'egg',
    7. // language: 'node',
    8. // }
    9. }
    10. }

     Router params(get)

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

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

    body(post)

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

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

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

    1. module.exports = {
    2. bodyParser: {
    3. jsonLimit: '1mb',
    4. formLimit: '1mb',
    5. },
    6. };

    egg的file模式

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

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

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

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

    后端:

    1. // app/controller/upload.js
    2. const Controller = require('egg').Controller;
    3. const fs = require('mz/fs');
    4. module.exports = class extends Controller {
    5. async upload() {
    6. const { ctx } = this;
    7. const file = ctx.request.files[0];
    8. const name = 'egg-multipart-test/' + path.basename(file.filename);
    9. let result;
    10. try {
    11. // 处理文件,比如上传到云端
    12. result = await ctx.oss.put(name, file.filepath);
    13. } finally {
    14. // 需要删除临时文件
    15. await fs.unlink(file.filepath);
    16. }
    17. ctx.body = {
    18. url: result.url,
    19. // 获取所有的字段值
    20. requestBody: ctx.request.body,
    21. };
    22. }
    23. };

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

    stream模式获取file

    1. const path = require('path');
    2. const sendToWormhole = require('stream-wormhole');
    3. const Controller = require('egg').Controller;
    4. class UploaderController extends Controller {
    5. async upload() {
    6. const ctx = this.ctx;
    7. const stream = await ctx.getFileStream();
    8. const name = 'egg-multipart-test/' + path.basename(stream.filename);
    9. // 文件处理,上传到云存储等等
    10. let result;
    11. try {
    12. result = await ctx.oss.put(name, stream);
    13. } catch (err) {
    14. // 必须将上传的文件流消费掉,要不然浏览器响应会卡死
    15. await sendToWormhole(stream);
    16. throw err;
    17. }
    18. ctx.body = {
    19. url: result.url,
    20. // 所有表单字段都能通过 `stream.fields` 获取到
    21. fields: stream.fields,
    22. };
    23. }
    24. }
    25. 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你就算能访问了,有需要就扣使用文档的可以私聊或者留言,有需要人需要处使用文档,没有就不出了

  • 相关阅读:
    进程间通信
    【2023联发科提前批笔试题】~ 题目及参考答案
    Ai作图可控性演进——从SD到MJ
    页面转变为灰色,如此简单
    596. 超过5名学生的课
    【2022】【论文笔记】太赫兹波段纳米颗粒表面增强拉曼——
    Docker容器相关命令
    09.Tornado_获取请求参数
    【JDBC笔记】向数据表中插入Blob类型数据
    C语言双链表,循环链表,静态链表讲解(王道版)
  • 原文地址:https://blog.csdn.net/LUZENG_SA/article/details/126575415