Discussion regarding default population of REST

I’ve opened a GitHub issue, where you can add your voice/context.

1 Like

Already fixed this one in v4.0.2 :slight_smile:

Well for populating you own data without having a lot of query in every call you could just modify the find content-type controller like this:

// PATH: ./src/api/[content-type]/controllers/[content-type].js

"use strict";

 
/**
 *  event controller
 */
 
const { createCoreController } = require("@strapi/strapi").factories;
 
module.exports = createCoreController("api::event.event", ({ strapi }) => ({
    async find(ctx) {
      ctx.query = { ...ctx.query, populate: '*' }
    
      // Calling the default core action
      const { data, meta } = await super.find(ctx);
  
      // some more custom logic
  
      return { data, meta };
    }
}));

Strapi: 4.0.4

2 Likes

I’m using the @nuxtjs/strapi plugin for Nuxtjs v2 and this method is not working for me. I am thinking why should I use Dynamic Zones and Components if I cannot query them properly and I have to use work-arounds. The concept of Dynamic Zone is great of itself but they way it is used it makes it look crippled.

1 Like

Not sure if this is the best way but I’ve managed to set some default population logic for specific collection types using middleware.

For example. If i wanted every request for books to return the author relation without having to worry about providing it in the query string:
Books Router config: /api/book/routes/book.js

module.exports = {
  routes: [
    {
      method: "GET",
      path: "/books",
      handler: "book.find",
      middlewares: ["populate-books"]
    },
    // ... more routes (with the same middleware if you want)
  ]
}

And then in /api/book/middlewares/populate-books.js:

const populateList = ["author"];

const enrichCtx = (ctx) => {
  if (!ctx.query) {
    ctx.query = {};
  }
  const currentPopulateList = ctx.query.populate || [];
  ctx.query.populate = [...currentPopulateList, ...populateList];
  return ctx;
};

module.exports = (config, { strapi }) => {
  return async (context, next) => {
    const newCtx = enrichCtx(context);
    context = newCtx;
    await next();
  };
};

This means that any find request for books will return the author, whether the populate query param has been passed or not. If it has been passed in, it will retain the query that’s been asked for as well as enriching it with authors.

I suppose if you wanted to “reverse” the default populate logic you could change the enrichCtx function only use the query from the request if it’s present, and if not, use the default one you defined?

Not sure if middlewares or policies is the best place for this kind of logic. (Or even if it’s not a good idea in general) :thinking:

Hope that helps someone though!

1 Like

Excelente amigo :+1::+1::+1:
Estuve atascado por esto 15 dias.


Translated by @DMehaffy

Excellent friend :+1::+1::+1:
I was stuck on this for 15 days.

Hey there,

I know this is already an old topic, but I have to express, that I am deeply unhappy with the way this is handled right now.

populate=* should populate everything the way Strapi V3 did it. That means up to 3 levels including dynamic zones, media, relations and nested components.

The new API-Features are great but we definitely need a fast track to get all the data we need (including the 3rd level).
Being able to be selective and giving the REST API almost GraphQL like abilities is nice, but complicating the way to get all data is not a good choice.

1 Like

I have to agree with @pix3l, this is an incredibly annoying default. The security and performance reasons pointed to by @roelbeerens are true but you shouldn’t have to rewrite a controller to get such basically functionality. We built out website from one of your templates using dynamic zones and as pointed out by @Georg this breaks those without either putting in a redundant populate=* in every page query or rewriting the controller. Surely having some property on a relation field that allows users to choose from within the content type whether that relation populates by default would be much more user friendly and intuitive, though I can’t speak for the difficulty of implementing it. I really hope you alter this and at the very least make it clear in the migration guide that this is a change from v3

3 Likes