strapi系列--超详细教你如何建表并在原有官方自动生成的api基础上重写原有查询,修改等接口逻辑,覆盖官方原有默认返回逻辑

为什么要进行后端定制呢?

在使用strapi过程中,项目中大部分需求我们都可以使用官方文档规定的方式来建表,查表,但是有的时候需要我们定制化自己的业务逻辑,那么我们该如何处理这个需求呢?本文以图文并茂的形式,覆盖掉官方的 find, findOne等方法,定制一个我们自己的业务逻辑接口。

Strapi后端的每个部分都可以定制

  • Strapi服务器收到的请求
  • 处理请求并触发控制器处理程序执行的路由
  • 可以阻止访问路由的策略
  • 中间件可以在向前移动之前控制请求流和请求
  • 一旦到达路由就执行代码的控制器
  • 用于构建控制器可重用的自定义逻辑的服务
  • 模型是内容数据结构的表示
  • 发送给应用程序的响应

数据准备,快速上手

新建一个表 cake-info

新建三个字段

插入几条数据

设置权限(暂时设置为公共接口)

测试接口

Request URL:
http://localhost:1337/api/cake-infos
Request Method:
GET
默认数据格式:

重写原有find,findOne

目前我们访问接口,使用的是工厂函数默认返回数据结构,如果我们想要添加自定义逻辑,需要我们重写src/api/cake-info/controllers/cake-info.js

重写/api/cake-infos

  • 官方文档
  • 这个接口对应的是默认的 find方法,我们需要修改src/api/cake-info/controllers/cake-info.js文件,如下:

原始文件:

'use strict';

/**
 * cake-info controller
 */

const { createCoreController } = require('@strapi/strapi').factories;

module.exports = createCoreController('api::cake-info.cake-info');

使用await super.find(ctx)重写src/api/cake-info/controllers/cake-info.js find方法

"use strict";

/**
 * cake-info controller
 */

const { createCoreController } = require("@strapi/strapi").factories;

module.exports = createCoreController(
  "api::cake-info.cake-info",
  ({ strapi }) => ({
    async find(ctx) {
      const { data, meta } = await super.find(ctx);

      return { statuss: "success", code: 1, data, meta };
    },
  })
);


测试重写逻辑

工厂api重写-保留核心逻辑

find

async find(ctx) {
  // some logic here
  const { data, meta } = await super.find(ctx);
  // some more logic

  return { data, meta };
}

findOne

包装核心动作(保留核心逻辑)

async findOne(ctx) {
  // some logic here
  const response = await super.findOne(ctx);
  // some more logic

  return response;
}

还可以调用自定义service, 完全自定义逻辑,像这样:


const { createCoreController } = require('@strapi/strapi').factories;

module.exports = createCoreController('api::restaurant.restaurant', ({ strapi }) =>  ({
  async findOne(ctx) {
    const sanitizedQueryParams = await this.sanitizeQuery(ctx);
    const { results, pagination } = await strapi.service('api::restaurant.restaurant').find(sanitizedQueryParams);
    const sanitizedResults = await this.sanitizeOutput(results, ctx);

    return this.transformResponse(sanitizedResults, { pagination });
  }
}));

create

async create(ctx) {
  // some logic here
  const response = await super.create(ctx);
  // some more logic

  return response;
}

直接重写find等并调用自定义service

举个栗子
src/api/test-type/controllers/test-type.js

'use strict';

/**
 * test-type controller
 */

const { createCoreController } = require('@strapi/strapi').factories;

module.exports = createCoreController('api::test-type.test-type', ({ strapi }) => ({
  async findOne(ctx) {
    try {
      const { data } = await super.findOne(ctx);
      const result = await strapi.services['api::test-type.test-type']['testInfo'](
        data,
        ctx.query,
      );
      ctx.success(result);
    } catch (err) {
      strapi.log.error(err.message);
      ctx.fail(err.message);
    }
  },
  async find(ctx) {
    try {
      const result = await strapi.services['api::test-type.test-type']['testCatagory'](
        ctx.query.lang,
      );
      ctx.success(result);
    } catch (err) {
      strapi.log.error(err.message);
      ctx.fail(err.message);
    }
  },
}));

直接调用strapi封装的方法去读取数据库

举个栗子

const data = await strapi.db.query('api::test-type.test-type').findOne({
  where: {
    id: query.id,
  },
  populate: {
    relation: true,
    tests: {
      populate: ['test_tags', 'test_detail', 'test_types'],
    },
  },
});
大功告成~~
  • 今天就写到这里啦~小伙伴们,( ̄ω ̄( ̄ω ̄〃 ( ̄ω ̄〃)ゝ我们明天再见啦~~
  • 大家要天天开心哦

欢迎大家指出文章需要改正之处~
学无止境,合作共赢

在这里插入图片描述

欢迎路过的小哥哥小姐姐们提出更好的意见哇~~

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
非常抱歉,我的回答有误。Element Plus 文件上传组件并没有提供 `custom-response` 属性。实现你的需求可以通过以下两种方式: 1. 在上传组件中使用 `on-success` 事件,将服务端返回的 `id` 放置在 `file` 对象上。例如: ```html <template> <el-upload class="upload-demo" action="/upload" :on-success="handleUploadSuccess" > <el-button size="small" type="primary">点击上传</el-button> </el-upload> </template> <script> export default { methods: { handleUploadSuccess(response, file, fileList) { const { id } = response.data; // 假设服务端返回的数据中有 id 字段 file.id = id; // 将服务端返回的 id 放置在 file 对象上 } } } </script> ``` 在上面的例子中,通过解构赋值获取服务端返回的 `id` 字段,然后将其放置在 `file` 对象上。这样就可以直接通过 `file.id` 访问服务端返回的 `id` 了。 2. 继承 `el-upload` 组件,重写 `handleProgress` 和 `handleSuccess` 方法,在这两个方法中将服务端返回的数据放置在 `file` 对象上。例如: ```html <template> <my-upload class="upload-demo" action="/upload" > <el-button size="small" type="primary">点击上传</el-button> </my-upload> </template> <script> import ElUpload from 'element-plus/lib/el-upload'; export default { components: { MyUpload: { extends: ElUpload, methods: { handleProgress(event, file, fileList) { // 调用父类方法 this.$emit('progress', event, file, fileList); // 将服务端返回的 progress 字段放置在 file 对象上 const { progress } = JSON.parse(event.currentTarget.responseText); file.progress = progress; }, handleSuccess(response, file, fileList) { // 调用父类方法 this.$emit('success', response, file, fileList); // 将服务端返回的 id 字段放置在 file 对象上 const { id } = response.data; file.id = id; } } } } } </script> ``` 在上面的例子中,继承了 `el-upload` 组件,并重写了 `handleProgress` 和 `handleSuccess` 方法,在这两个方法中将服务端返回的数据放置在 `file` 对象上。然后在模板中使用自定义的 `my-upload` 组件。 希望这些解决方案能够帮助到你,如果还有其他问题,请继续提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值