Сегодня я расскажу о пользовательских маршрутах и slug. Конечная цель - разработать несколько конечных точек API, которые будут выдавать мне контент по slug, а не по id.
У меня есть модель, которая может быть Page, Products или любой другой моделью. Моя модель имеет:
В классическом Stapi API для получения одного содержимого мне нужно использовать конечную точку finedOne, которая принимает id в качестве параметра:
http://localhost:1337/api/pages/1
Существует обходной путь для получения содержимого по slug без специального кодирования. Использование конечных точек findAll и фильтрация по slug:
http://localhost:1337/api/pages?filters[slug][$eq]=my-slug
Мне не нравится это решение, поскольку оно создает запутанный URL, учитывая необходимость добавления параметра populate. И я также подозреваю, что это решение медленнее, чем пользовательское кодирование. Никаких доказательств относительно скорости, просто подозрение.
Я создал отдельный тип для лучшей организации моей пользовательской конечной точки, я назвал его "v1", полезно для версионирования пользовательских конечных точек в будущем. (Вы можете создать v2 и так далее...)
Затем в коде вашего проекта откройте "api/v1/controllers/v1.js" и вставьте этот код:
const { createCoreController } = require('@strapi/strapi').factories; module.exports = createCoreController('api::v1.v1', ({strapi}) => ({ page: async (ctx) => { const slug = ctx.params['slug']; const entry = await strapi.db.query('api::page.page').findOne({ // uid syntax: 'api::api-name.content-type-name' where: { slug }, populate: { seo: true, }, }); console.info(entry); return entry } }));
После этого откройте api/v1/routes/v1.js и вставьте его:
const { createCoreRouter } = require('@strapi/strapi').factories; const defaultRouter = createCoreRouter('api::v1.v1'); const customRouter = (innerRouter, extraRoutes = []) => { let routes; return { get prefix() { return innerRouter.prefix; }, get routes() { if (!routes) routes = innerRouter.routes.concat(extraRoutes); return routes; }, }; }; const myExtraRoutes = [ { method: 'GET', path: '/v1/page/:slug', handler: 'api::v1.v1.page', config: { auth: false, }, } ]; module.exports = customRouter(defaultRouter, myExtraRoutes);
В маршруте я определил путь и связанный с ним контроллер. В контроллере я определил пользовательскую функцию, которая использует Strapi Query Engine для получения моего контента, а также заполняет его тем, что я хочу.
Вот и все.
Теперь, если вы хотите добавить пользовательский маршрут в кэш, проверьте мою предыдущую статью , и просто добавьте в конфигурацию кэширования такие строки:
{ contentType: "api::v1.v1", routes: [ { path: '/api/v1/page/:slug+', method: 'GET' } ] }
Если вы потеряли предыдущие статьи Strapi, вот список читателей:
Strapi
20.08.2023 18:21
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в 2023-2024 годах? Или это полная лажа?".
20.08.2023 17:46
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
19.08.2023 18:39
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в частности, магию поплавков и гибкость flexbox.
19.08.2023 17:22
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для чтения благодаря своей простоте. Кроме того, мы всегда хотим проверить самые последние возможности в наших проектах!
18.08.2023 20:33
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий их языку и культуре.
14.08.2023 14:49
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип предназначен для представления неделимого значения.