Why does user permissions plugin not transform the response?

Hi,
I’ve recognized that the user-permissions plugin does not transform the response data which is leading to the very confusing state that the api responses have a different format depending on if I retrieve the data from the user object or another object that relates to the user object.

Is there a specific reason why this is happening? It just creates inconsistency in the data models and confuses the heck out of me.

For example:

2 entities, user and school.
If I fetch a user and populate the school field I get this response:

{ 
  id: 1
  name: "Peter"
  school: {
     id: 1
     name: "Test"
  }
}

But when I fetch a school and populate the user field then I get this response:

{ 
  id: 2
  attributes: {
    name: "Test",
    user: {
      data: {
        id: 1
        attributes: {
          name: "Peter"
        }
      }
    }
  }
}

The annoying thing is that now in my frontend (using Typescript) I have to create different types depending on from where I fetch the data and have to adjust the data so that it always fits to my frontend.

Following.

It is because route (user) you are requesting is from plugin where you dont get data->attributes, and if its “native” route then you have data->attributes structure

Note: I have same situation with my plugin and its annoying that responses dont have same structure.

Yes I am aware of that but I’m asking what is the reasoning behind this decision and is this open to change? Because I’m seriously considering patching this locally so I get consistent responses which is a nightmare to maintain locally.

They did not think of doing it when releasing v4 and they can’t change it since that would be a breaking change. I recomand the Transformer | Strapi Market plugin since that should make everyting 1 format.

1 Like

Any chance of incremental adoption, example to have option in config:

  1. to allow data->attributes,
  2. later to allow without data->attributes
  3. to have default data->attributes

they could technically add an opt in feature to do that but that chance will be realty small. since that will not really change much but it will increase the complexity and the amount of code to maintain

Still I recommend the transform plugin Transformer | Strapi Market
since this will handle it for all endpoints

My idea was to change for plugin api part, not to change native api. That way it would be unified.

I just tried the Transformer plugin but now the data and meta information on the first level is missing in all the user routes :confused:

So I still have different output depending on the route.

Best way to patch this is by adding a middleware dynamically on the route where in you tranform the data manualy.

if you want a better explenation I would recomand joining the discord since it depends on your needs how you would do this.

I tried transform plugin but then the dilema of working on data response moved to custom controllers (or services, I dont remember) in backend. So finally removed transformer and implemented the transform myself in the frontend.

Same problem here. We faced this problem while we handled restricted field outputs inside populated API responses. The populated collection types structure in user permissions plugin is different, too.

Isn’t it rather advisable to change the native structure of the Strapi API and change the plugin response structure instead?
Or is it to be expected that the Strapi API adapts to the plugin API? After all, the recommended plugin currently has 4k weekly downloads. I think this shows that a unification of the APIs is desired here!

We decided at least to transform the response object inside extensions/user-permissions/strapi-server.js
Here an example how the code can look like for “find”:

module.exports = (plugin) => {
  plugin.controllers.user.find = async (ctx) => {
    data = await strapi.plugins["users-permissions"].services.user.fetchAll(
      ctx.query
    );

    return yourTransformFunction(data); // transform object here
  };

  return plugin;
};
1 Like

users-permissions is maintained by the strapi team. only thing is it is a plugin ported from v3 to v4 and they forgot to change the API responce and now they could not fix it until v5. since no breaking changes

Are they any updates/workaround? It seems an awful choice to me to return a different response from a core plugin like that.

We can’t event instantiate a new core controller with same entity (to allow for same transformResponse fn to be called).
Other solution I tried is to call transformResponse directly but it is not exposed, beside creating a new coreController.

What if we need to return a list of users from a related controller? Using the source entity controller as the transformer does not work because the list of attributes is not the same as the user plugins, so the response does not get transformed.

Needs fix for sure, forgetting to port something like this seems stupid.