I don't understand how to create a route with Strapi 4

Hi everyone,

I am trying to create a new route. I’d like something like this : /api/posts/:id/comments

I have been searching here and I’ve tried many things but I can’t find the right solution :

post.js in routes folder

'use strict';

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

module.exports = createCoreRouter('api::post.post');

post.js in controllers folder

'use strict';

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

module.exports = createCoreController('api::post.post', ({strapi}) => ({
    comments: async (ctx) => {
        return "Hello"
    }
}));

Thank you very much for sharing your ideas.

change post.js in routes folder

const { createCoreRouter } = require('@strapi/strapi').factories;
const defaultRouter = createCoreRouter('api::post.post');

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: 'POST',
    path: '/api/posts/:id/comments',
    handler: 'api::post.post.comments',
  },
];

module.exports = customRouter(defaultRouter, myExtraRoutes);

above code adds new route to your existing post api .

change post.js in controllers folder

'use strict';

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

module.exports = createCoreController('api::post.post', ({strapi}) => ({
    comments: async (ctx) => {
       // following variable will get url `id` param value.
        const id = ctx.params['id']
    }
}));

One Important thing : If you are interacting with this api then please generate api token or give permission to existing api token with token type (access) as Full access otherwise you will get Forbidden Error .

Thank you nitin_tejuja. I feel I am moving forwards… I just replaced POST with GET, because I am trying to get comments from my post. Still, I have a 404 error :

    "data": null,
    "error": {
        "status": 404,
        "name": "NotFoundError",
        "message": "Not Found",
        "details": {}
    }
}

@Mimitip probably your are not returning anything from controller side . please try to returning something it will work .

Hi nitin_tejuja ! I returned Comment ${id}, but I have same result.

Did you mean returning something like this ?

'use strict';

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

module.exports = createCoreController('api::post.post', ({strapi}) => ({
    comments: async (ctx) => {
        const id = ctx.params['id']
        return `Comment ${id}`
    }
}));

@Mimitip yes and since strapi is giving by default /api to api requests means
default http://localhost:1337/api and since you defined route url is /api/posts/:id/comments so now to work ,actual url should be http://localhost:1337/api/api/posts/3/comments

So if you delete /api from route url and put route url as /posts/:id/comments then it will work as you are expecting .

Ok. I replaced path: ‘/api/posts/:id/comments’ with path: ‘/posts/:id/comments’ in post.js existing in routes folder. I tested GET http://localhost:1337/api/posts/:id/comments with Postman. I have the same error… but I feel I am not far to have the right result. :slight_smile:

Where could be the problem ?

Thank you very much for your help so far. :pray:

I noticed that “strapi” is not used in post.js in controller folder.

can you please send the code for post.js in routes folder

‘use strict’;

const { createCoreRouter } = require(‘@strapi/strapi’).factories;
const defaultRouter = createCoreRouter(‘api::post.post’);

const customRouter = (innerRouter, extraRoutes = ) => {
let routes;
return {
get prefix() {
return innerRouter.prefix;
},
get router() {
if (!routes) routes = innerRouter.routes.concat(extraRoutes);
return routes
},
};
};

const myExtraRoutes = [
{
method: ‘GET’,
path: ‘/posts/:id/comments’,
handler: ‘api::post.post.comments’,
}
]

module.exports = customRouter(defaultRouter, myExtraRoutes);

well i think there is one mistake replace get router() with get routes() in your post.js in routes folder ,as default router will not able to find method get router() .

Ok, I just corrected. I still have the same issue.

Here is the picture (in case, I am not testing the right way) :

thats strange . which version of strapi you are using ?

I have Strapi v4.1.11.

same scenario i was able to accomplish in my machine . are you using api token for authentication for api requests ? or have you changed any prefix url configuration in config/server.js ?

No, not at all.

This is the code in my config/server.js file :

module.exports = ({ env }) => ({
  host: env('HOST', '0.0.0.0'),
  port: env.int('PORT', 1337),
  app: {
    keys: env.array('APP_KEYS'),
  },
});

can you try this for one last time
can you replace myExtraRoutes variable data first element in routes folder with below

  {
    method: "GET",
    path: "/posts/:id/comments",
    handler: "api::post.post.comments",
    config: {
      auth: false,
    },
  },

Yes, it worked !! Thank you.

1 Like