Custom endpoint to return user data with additional fields via relation

System Information
  • Strapi Version: v4.0.0
  • Operating System: macOS Monterey 12.0.1
  • Database: Postgresql
  • Node Version: v14.15.5
  • NPM Version: n/a
  • Yarn Version: 1.22.10

Good morning,

I’ve created a new content type called “profile” - I use it to store additional data for my users. I linked it to the “user” content type via a relation field (one-to-one - User has and belongs to one Profile) and initially I was trying to populate the “profile” fields to retrieve them via /users/me endpoint, but now I know that this is not working due to the limitations of default installation.

So I crated a new controller called “account” and created a new “index” function, which shows fine in the API response, now I am trying to populate it with the correct data.

The endpoint should retrieve the currently authenticated user ID and retrieve their USER and details along with the associated PROFILE.

New endpoint URL: /api/account

Here’s my controller code:

module.exports = {
    async index(ctx, next) {
        const id = ctx.state?.user?.id

        const user = await strapi
        .query("admin::user", "api::profile.profile")
        .findOne({ id });

        ctx.body = user;
    },
};

This works partially, as it returns me the user data, but not the PROFILE data:

{
	"id": 1,
	"firstname": "John",
	"lastname": "Doe",
	"username": null,
	"email": "admin@localhost.com",
	"password": "",
	"resetPasswordToken": null,
	"registrationToken": null,
	"isActive": true,
	"blocked": false,
	"preferedLanguage": null,
	"createdAt": "2021-12-13T10:43:17.728Z",
	"updatedAt": "2021-12-13T10:43:17.728Z"
}

How can I achieve what I want?

Also, as a side note - it might be entirely my fault, but I find the Strapi documentation very confusing. For example, I was trying to find out what properties does ctx have, and I was unable to see a comprehensive list. I was only able to find out by inspecting the Object.keys(ctx).

Similarly, the query API documentation is also very confusing. Some examples show this syntax:

await strapi.db.query("user").findOne({ id })

And some others this:

await strapi.query("admin::user").findOne({ id })

Can someone please explain what’s the difference?

Generally speaking, I am very happy with how Strapi works out of the box - it enables me to build simple apps very quickly, but when it comes to customisation, the docs are really lacking in detail :frowning:

Thank you for the time to read my post and looking forward to any suggestions.

1 Like

UPDATE: I was able to get it working by doing this:

module.exports = {
    async index(ctx, next) {
        const id = ctx.state?.user?.id

        const account = await strapi
            .query("api::profile.profile")
            .findOne({
                where: { user: id },
                populate: {
                    billing: true,
                    shipping: true,
                    user: true
                }
            })

        ctx.body = account
    },
};

But please note that the syntax for the .findOne() params is VERY different from the one I found in the docs. The documentation is really all over the place :frowning:

Anyway, is what I am doing the correct way to achieve this or does anyone have suggestions on how to improve it?

3 Likes