Как добавить новый маршрут конечной точки API в strapi?

Я новичок в strapi и backend в целом.

Я создал тип контента под названием post, и он доступен по этому маршруту /posts/:id по умолчанию. Однако я также хочу, чтобы этот пост был доступен по этому маршруту /posts/:slug. Я попытался добавить новый маршрут в файл routes.json, но когда я посещаю маршрут, он возвращает ошибку 404.

Как мне этого добиться?

РЕДАКТИРОВАТЬ:

Мой routes.json файл выглядит так:

{
  "routes": [{
      "method": "GET",
      "path": "/posts",
      "handler": "Post.find",
      "config": {
        "policies": []
      }
    },
    {
      "method": "GET",
      "path": "/posts/count",
      "handler": "Post.count",
      "config": {
        "policies": []
      }
    },
    {
      "method": "GET",
      "path": "/posts/:id",
      "handler": "Post.findOne",
      "config": {
        "policies": []
      }
    },
    {
      "method": "GET",
      "path": "/posts/:slug",
      "handler": "Post.findOne",
      "config": {
        "policies": []
      }
    },
    {
      "method": "POST",
      "path": "/posts",
      "handler": "Post.create",
      "config": {
        "policies": []
      }
    },
    {
      "method": "PUT",
      "path": "/posts/:id",
      "handler": "Post.update",
      "config": {
        "policies": []
      }
    },
    {
      "method": "DELETE",
      "path": "/posts/:id",
      "handler": "Post.delete",
      "config": {
        "policies": []
      }
    }
  ]
}

person aycebrent    schedule 14.01.2020    source источник
comment
Как выглядит ваш routes.json?   -  person nopassport1    schedule 14.01.2020
comment
Я просто продублировал маршрут для id и вставил slug pastebin.com/xYfQPKkH   -  person aycebrent    schedule 14.01.2020
comment
Как вы «посещаете» маршрут? Что вы набираете, чтобы получить к нему доступ? Вероятно, ваш обработчик не знает, что означает slug. Вам нужно будет создать еще один обработчик. Кроме того, зачем вам копировать функциональность существующего маршрута? Какой у вас вариант использования для этого?   -  person nopassport1    schedule 14.01.2020
comment
Я посещаю этот URL - http://localhost:1337/posts/perfect-simplicity perfect-simplicity - это слаг определенного сообщения. Я могу получить тот же пост, когда обращусь к нему с URL-адресом идентификатора, подобным этому - http://localhost:1337/posts/2   -  person aycebrent    schedule 14.01.2020
comment
Логика обработчика Post.findOne не понимает, что означает perfect-simplicity, поскольку он пытается найти сообщение с помощью уникального идентификатора, предоставленного strapi при его создании. Тем не менее, даже если вы создали новый обработчик для удовлетворения своих требований, это не будет лучшей практикой, поскольку (я предполагаю) ваш slug не является уникальным идентификатором (многие сообщения могут быть созданы с одним и тем же slug). Если вы хотите создать новую конечную точку, вам также необходимо создать для нее обработчик.   -  person nopassport1    schedule 14.01.2020
comment
strapi.io/ документация / 3.0.0-alpha.x / guides /   -  person nopassport1    schedule 14.01.2020


Ответы (2)


Проблема в том, что ваша новая конечная точка slug использует тот же обработчик, что и тот, который находит сообщения по их уникальному идентификатору (каждому сообщению присваивается увеличивающийся номер). Таким образом, он не имеет понятия о perfect-simplicity, поскольку ожидает числового значения.

Чтобы решить вашу проблему, вам необходимо создать новый обработчик / контроллер для вашей конечной точки.

Вот ссылка на документацию Strapi:
https://strapi.io/documentation/3.0.0-alpha.x/guides/controllers.html#adding-endpoints.

Вы правильно составили свой маршрут:

Путь - ./api/hello/config/routes.json

{
  "routes": [
    {
      "method": "GET",
      "path": "/hello",
      "handler": "Hello.index"
    }
  ]
}

Просто нужно изменить ваш обработчик.

Путь - ./api/hello/controllers/Hello.js

module.exports = {
  // GET /hello
  index: async ctx => {
    ctx.send('Hello World!');
  },
};

В качестве примечания, как указано в документации:

Обработчик маршрута может обращаться только к контроллерам, определенным в папках ./api/**/controllers.


Кроме того, вам не следует использовать slug, поскольку я не думаю, что это уникальный идентификатор в ваших сообщениях (если только вы не запрещаете пользователям создавать сообщения с тем же perfect-simplicity slug). Это не лучшая практика. Вы, вероятно, столкнетесь с множеством проблем в будущем, если разрешите доступ к сообщениям через их slug значения.

person nopassport1    schedule 14.01.2020

если вам нужно найти статью от slug, я предлагаю вам обновить функцию контроллера findOne, используя эту документацию - https://strapi.io/documentation/3.0.0-beta.x/concepts/controllers.html#core-controllers

Вот кастомная функция

Путь - ./api/article/controllers/Article.js

const { sanitizeEntity } = require('strapi-utils');

module.exports = {
  async findOne(ctx) {
    //check if the params id is an id or a slug
    const {id} = ctx.params;

    // if you use MongoDB database
    // we are validating that the id match ObjectID format
    if (id.match(/^[0-9a-fA-F]{24}$/)) {
      const entity = await strapi.services.article.findOne(ctx.params);
      return sanitizeEntity(entity, { model: strapi.models.article });
    }

    // if you use SQL database
    // we check if the id is a valid number
    if (parseInt(id) == id) {
      const entity = await strapi.services.article.findOne(ctx.params);
      return sanitizeEntity(entity, { model: strapi.models.article });
    }

    // findOne function works only with IDs
    // so we find all and get first entry by using slug
    const [entity] = await strapi.services.article.find({slug: id});
    return sanitizeEntity(entity, { model: strapi.models.article });
  }
};
person Jim LAURIE    schedule 18.01.2020