How to Count in REST API in v4?

System Information
  • Strapi Version: 4.0.5
  • Database: Postgres

Hi All,
I’ve manually migrated my content into v4 and am now working through updating my queries with the new API structure.
v3 had a /count route that would return the total number of entries.
I can’t seem to find this in v4. I used this for a stat counter that was visible on the front end.

Can someone please confirm if that is correct, where the new location might be or what I’d need to adjust to re-add ?

1 Like

Hi @gorlaz,

You are right that this is not an enabled route by default (I think).

But you can create a custom route easily, by creating/modifying two files:

First, create a custom route file for in your api/content-type folder (assuming you have a content type named product and want the total count of them):

module.exports = {
    routes: [
        { // Path defined with a URL parameter
            method: 'GET',
            path: '/products/count',
            handler: 'product.count',
        },
    ]
}

Then customize your content type’s controller, and use the query engine to get the UID count.

'use strict';

/**
 *  product controller
 */

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

module.exports = createCoreController('api::product.product', {
    count(ctx) {
        var { query } = ctx.request
        return strapi.query('api::product.product').count({ where: query });
    }
});

Enable route permissions and test:
image
With parameters:
image

I have provided the code in this github repo if you’d like to fork:

1 Like

Hey nextrapi,

Thanks for that - that looks like it will do what I need.

That said, it appears there is now also a ‘meta’ section at the bottom of every response.

In my case it looks like;

"meta":
    {
        "pagination":
        {
            "page": 1,
            "pageSize": 25,
            "pageCount": 7,
            "total": 161
        }
    }

And it appears ‘total’ is what I’m after.

Do you know if it’s possible to request just the meta portion? (as it appears filter/sort etc only apply to the attributes fields.

hey @nextrapi , I’m just working through this now and I’m getting and error.
I’ve added the controller, the route and enabled permissions but it seems the database isn’t quite the same?

error: select "t0".* from "public"."blends" as "t0" where ("t0"."id" = $1) limit $2 - invalid input syntax for type integer: "count"

Hi @gorlaz,

I actually changed the code and used the entityServices api instead in the github.

Can you try the following controller instead?

src/api/product/controllers/product.js
'use strict';

/**
 *  product controller
 */

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

module.exports = createCoreController('api::product.product', {
    count(ctx) {
        var { query } = ctx.request
        return strapi.entityService.count('api::product.product', query);
    }
});

Also, what database are you using?

Hey @nextrapi, I have the same error and I tried using entityService, and it still isn’t working. I’m using postgresql.

@nextrapi I am also getting the same error as @vkygil.

error: select "t0".* from "comapnies"."blends" as "t0" where ("t0"."id" = $1) limit $2 - invalid input syntax for type integer: "count"

Were you guys able to find a solution?

I have the same error but in an update.
I have tried with in engine and entity service and the error persists

It’s about route naming problem try to follow the document on CAUTION section https://docs.strapi.io/developer-docs/latest/development/backend-customization/routes.html#creating-custom-routers

It’s about route naming problem try to follow the document on CAUTION section Routes - Strapi Developer Docs

just change your path and handler name…

module.exports = {
    routes: [
        { 
            method: 'GET',
            path: '/academies/count/view',
            handler: 'academy.getCount',
        },
    ]
}

I would suggest not having a separate endpoint that simply counts the number of results. In v4, you will receive additional metadata for paginated results that will include a total attribute.

If this isn’t suitable for whatever reason, you should create an endpoint that returns the data and the total count in a single response. Otherwise, you’re doubling up on queries to the database and creating double the workload on all resources between the user and the data source.

Hello there. I have followed your code. However, there is only one single count route. I want all the default routes and the count route. How should I modify the code?

I am not sure why you are creating a separate Endpoint just to get count :thinking:
But nvm, in strapi you can get the count of the records by using those methods.
Check the documents: Bulk Operations | Strapi Documentation ,
Bulk Operations | Strapi Documentation
OR
by using raw query too.

1 Like

@Harisankar_Sahoo why is it working for me like this
module.exports = {
routes: [
{
// Path defined with a URL parameter
method: “GET”,
path: “/articles/count/view”,
handler: “article.count”,
},
],
};

and not working when i give
module.exports = {
routes: [
{
// Path defined with a URL parameter
method: “GET”,
path: “/articles/count”,
handler: “article.count”,
},
],
};

I have the same problem!
Is this already solved? :roll_eyes: