Skip to content

Order of route files prevents custom routes from working #20887

@frontBOI

Description

@frontBOI

Bug report

Required System information

  • Node.js version: 18.19.0
  • NPM version: 10.8.2
  • Strapi version: 5.0.0-rc.7
  • Database: mysql
  • Operating system: darwin-arm64
  • Is your project Javascript or Typescript: Typescript

Describe the bug

I described this bug in this ticket. Still, here is what this is about:

I want to create custom API routes for an object, so I create a new file named custom-routes.ts like this:

/routes
    command.ts
    custom-routes.ts

With these files content:
command.ts

import { factories } from '@strapi/strapi'

export default factories.createCoreRouter('api::command.command')

custom-routes.ts:

export default {
  routes: [
    {
      method: 'GET',
      path: '/commands/test',
      handler: 'command.test',
    },
  ],
}

My controller code (command.ts):

import { factories } from '@strapi/strapi'

export default factories.createCoreController('api::command.command', ({ strapi }) => ({
  async test() {
    return 'true'
  },
}))

Then the problem arises like so:

  1. When I don't enable permissions for my custom route, I get a 403 (which is expected).
  2. When I enable permission for my /commands/test endpoint on public role in the Strapi admin panel, I still get 403: not expected.
  3. I need to allow findOne to finally get 404, which should not happen (it should get true instead of a not found error).

The route files in the /route folder for a particular collection type seem to be loaded in an alphabetical order. Then, my custom GET route enters in conflict with the classic findOne route. I don’t understand why, but my GET route defined in custom-routes.ts is replaced by the findOne route.

Describe the fix (yes I found a way to fix this behaviour)

When I reorder the route files so my custom route is in the first file:

/routes
    a-custom-routes.ts
    command.ts

Then my custom route is recognized and works. I can’t explain why this is behaving like this, but here it is. So it seems that the general rule would be to always have one’s custom routes file before the core file ones.

Steps to reproduce the behavior

  1. Create a new Strapi project
  2. Create a new collection type named command
  3. Create a new file in /src/api/command/routes named custom-routes.ts. Here should be its content:
export default {
  routes: [
    {
      method: 'GET',
      path: '/commands/test',
      handler: 'command.test',
    },
  ],
}
  1. In the command controller (/src/api/command/controller/command.ts), enter the following content:
import { factories } from '@strapi/strapi'

export default factories.createCoreController('api::command.command', ({ strapi }) => ({
  async test() {
    return 'test'
  },
}))

Expected behavior

  1. Request the endpoints /src/api/command/controller/command.ts with a GET request at http://localhost:1337/api/commands/test and get a 403. Expected behaviour.

  2. In the admin panel, under Settings > Users & permissions plugin > Roles > Public > Command, tick test. Try again the previous request and still get a 403.

  3. In the admin panel, under Settings > Users & permissions plugin > Roles > Public > Command, untick test and tick findOne. Try again the previous request and get a 404 this time, although you did not allow the test endpoint !

Screenshots

Description Image
How the command permissions should be for the second expected behaviour bullet point. Screenshot 2024-07-27 at 10 17 00
How the command permissions should be for the third expected behaviour bullet point. Screenshot 2024-07-27 at 10 10 35

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions