System Information
- Strapi Version:
- Operating System:
- Database:
- Node Version:
- NPM Version:
- Yarn Version:
I’m new to strapi and still struggling with mostly everything.
I have a collection type with following fields:
- title
- excerpt
- content (component)
- category (relation)
- premium (boolean)
There are premium articles (for premium users) and public articles (for all users). But, I want non premium users to still have limited access to the articles: all fields except content.
I was able to implement this by writing 2 custom controllers: find and findOne.(/src/api/articles/controllers/articles.js
). In the custom controller find
I check ctx.query.populate and remove ‘content’ from it. (“content” is never needed on find)
In the custom findOne
controller I check the user’s role. If the role is premium I just call return await super.findOne(ctx);
. For non premium roles (authenticated or public) I make the same call, then check the premium field on the result. If this is true, I delete the content field from the result and then return said result:
if (!data.attributes.public) {
delete data.attributes.content;
}
This works but I have a question and a problem with this.
The question: is this an optimal pattern? Is this how it’s best done or are there better solutions?
The problem: when I call the category api and populate articles and again content on articles:
route: /api/categories
query:
{
fields: ['name'],
populate: {
articles: {
fields: ['title', 'excerpt', 'premium'],
populate: {
content: true
}
}
},
}
The content fields on articles gets populated and I don’t want that. I kinda expected that strapi would reuse my custom controllers to query but it does not. How do I solve this? The route api/categories
should return articles with title, excerpt, … but not the content field.
I could again filter out the results or remove the populate content query using custom category controllers but that feels wrong. Is there a better way of doing this?