diff --git a/.changeset/short-rivers-fly.md b/.changeset/short-rivers-fly.md new file mode 100644 index 00000000..09b1e37e --- /dev/null +++ b/.changeset/short-rivers-fly.md @@ -0,0 +1,6 @@ +--- +"strapi-plugin-webtools": minor +"docs": minor +--- + +feat: new configuration option called 'router_use_controllers' diff --git a/packages/core/server/config.ts b/packages/core/server/config.ts index f98761aa..d2fb660e 100644 --- a/packages/core/server/config.ts +++ b/packages/core/server/config.ts @@ -6,6 +6,7 @@ export interface Config { website_url: string; default_pattern: string, unique_per_locale: boolean, + router_use_controllers: boolean, slugify: (fieldValue: string) => string, } @@ -14,6 +15,7 @@ const config: { validator: () => void } = { default: { + router_use_controllers: false, website_url: null, default_pattern: '/[pluralName]/[documentId]', slugify: (fieldValue) => kebabCase(deburr(toLower(fieldValue))), diff --git a/packages/core/server/controllers/core.ts b/packages/core/server/controllers/core.ts index e92472aa..68f34419 100644 --- a/packages/core/server/controllers/core.ts +++ b/packages/core/server/controllers/core.ts @@ -5,6 +5,56 @@ import { Schema } from '@strapi/strapi'; import { getPluginService } from '../util/getPluginService'; import { sanitizeOutput } from '../util/sanitizeOutput'; +type EntityResponse = { data: {}, meta: {} }; + +const routerWithControllers = async (ctx: Context) => { + const { path, ...searchQuery } = ctx.query; + + // Find related entity by path. + const { entity, contentType } = await getPluginService('url-alias').findRelatedEntity(path as string, { + ...searchQuery, + fields: ['documentId'], + }); + + const isSingleType = strapi.contentTypes[contentType].kind === 'singleType'; + let controllerEntity: EntityResponse = null; + + // Query the full entity using the content type controller. + if (isSingleType) { + controllerEntity = await strapi.controllers[contentType].find(ctx, async () => {}) as + EntityResponse; + } else { + controllerEntity = await strapi.controllers[contentType].findOne({ + ...ctx, + query: { + ...ctx.query, + }, + params: { + ...ctx.params as {}, + id: entity.documentId, + }, + }, async () => {}) as EntityResponse; + } + + if (!controllerEntity) { + ctx.notFound(); + return null; + } + + // Add content type to response. + const responseEntity = { + data: { + ...controllerEntity.data, + contentType, + }, + meta: { + ...controllerEntity.meta, + }, + }; + + return responseEntity; +}; + /** * Router controller */ @@ -14,6 +64,15 @@ export default { const { path, ...searchQuery } = ctx.query; const { auth } = ctx.state; + const routerUseControllers = strapi.config.get('plugin::webtools.router_use_controllers', false); + + if (routerUseControllers) { + const entity = await routerWithControllers(ctx); + ctx.body = entity; + return; + } + + // Find related entity by path. const { entity, contentType } = await getPluginService('url-alias').findRelatedEntity(path as string, searchQuery); if (!entity) { diff --git a/packages/docs/docs/configuration/router-use-controllers.md b/packages/docs/docs/configuration/router-use-controllers.md new file mode 100644 index 00000000..96525d30 --- /dev/null +++ b/packages/docs/docs/configuration/router-use-controllers.md @@ -0,0 +1,22 @@ +--- +sidebar_label: 'Router use controllers' +displayed_sidebar: webtoolsSidebar +slug: /configuration/router-use-controllers +--- + +# Router use controllers + +The [Webtools Router](/api/rest#router) endpoint has an option to make use of the core controllers of your content types. That means that you can extend your controllers as you're used to and the result will be returned by the Router endpoint by of Webtools. + +:::note +To make use of this feature you will need to enable the `findOne` permission of the specific content type. +::: + +In the future this might become the default behavior but that will cause a breaking change in the current behavior. + +| Name | Details | +| ---- | ------- | +| Key | `router_use_controllers` | +| Required | false | +| Type | boolean | +| Default | false | diff --git a/packages/docs/sidebars.ts b/packages/docs/sidebars.ts index 5cd725e5..23814748 100644 --- a/packages/docs/sidebars.ts +++ b/packages/docs/sidebars.ts @@ -80,6 +80,7 @@ const sidebars = { items: [ "configuration/introduction", "configuration/default-pattern", + "configuration/router-use-controllers", "configuration/website-url", "configuration/slugify", "configuration/unique-per-locale",