Strapi.service OR strapi.db

System Information
  • Strapi Version: 4

Which one should i use to access data? in term of performance and best practice

const post = await strapi.service("api::post.post").findOne(id, {populate: ['author']});
const post = await strapi.db.query("api::post.post").findOne({ where: { id }, populate: ["author"] });

Out of those none.
Technically the first one is what you want to use but you want to use entityService.
db.query is just a lower end version of this. But overall EntityService is what you are looking for.

Ok i managed to do it
const post = await strapi.entityService.findOne(“api::post.post”, id, {populate: [“author”]});

But what is the difference between these 3 approaches?
or atleast between this and first one

So the first one you had was wrong syntax. So it’s not valid.

Entity Service

From the documentation

🤓 Entity Service API vs. Query Engine API

Strapi v4 offers several layers to interact with the backend and build your queries:

The Entity Service API is the recommended API to interact with your application's database. The Entity Service is the layer that handles Strapi's complex data structures like components and dynamic zones, which the lower-level layers are not aware of.
The Query Engine API interacts with the database layer at a lower level and is used under the hood to execute database queries. It gives unrestricted internal access to the database layer, but should be used only if the Entity Service API does not cover your use case.
If you need direct access to knex functions, use strapi.db.connection.

Hi @Eventyret,
I think that this confusion between strapi.service and strapi.entityService (me also → What is the difference between strapi.service() and strapi.entityService()) is caused by the documentation. In fact in the controllers section when you looking for a replacing of a core action, the documentation refers to strapi.service.

  // Method 3: Replacing a core action
  async findOne(ctx) {
    const { id } = ctx.params;
    const { query } = ctx;

    const entity = await strapi.service('api::restaurant.restaurant').findOne(id, query);
    const sanitizedEntity = await this.sanitizeOutput(entity, ctx);

    return this.transformResponse(sanitizedEntity);
  }

furthermore there is no documentation about transformResponse and sanitizeOutput (or sanitizeInput) so this generate a big confusion.
For what i understood there are 4 method to build a new controller.
super when you want to use an unique function with sanitize and transform functions included (with also meta object)
strapi.service with no documentation (only an example in the backend customization section) that seems to be a entityService API with some more date like meta object
strapi.entityService that is the documented API that

is the layer that handles strapi’s complex data structures

but when you want to expose it to the front-end (if you want to keep the structure with data-attributes) you have to sanitize (??) and transform the response before to expose it.

strapi.db.connection that is a lower level of entityService.

I’m right?

3 Likes

@Shaun_Brown :triangular_flag_on_post: for documentation visibility this is good feedback :upside_down_face: :point_up_2:

2 Likes