How to set common api response structure for all APIs

How can I set common API response body structure for all APIs at one place ?
Like I want all APIs to return success response in this structure:
{ status: "success", data: strapi_api_response_here}

while error response in this structure:
{ status: "error", error: strapi_api_error_here}

Currently we don’t have a method for overwriting the core-api (which comes from here: strapi/packages/strapi/lib/core-api at master · strapi/strapi · GitHub ) without forking the strapi package and maintaining your own fork.

You could potentially write a middleware that intercepts the default ctx.response and rebuilds it with your structure :thinking:

Hi @DMehaffy can you please elaborate your solution a little more ?

I don’t have example code other than the basic middleware template you can find here: https://strapi.io/documentation/developer-docs/latest/concepts/middlewares.html#example

Basically try console.log(ctx.response) after the await next() in which you can then modify the ctx.response with your own structure.

Middlewares run on the request chain (every request, including the admin) so you will have to be careful not to modify the requests for the Admin panel as these can throw errors since the Admin isn’t expecting that format.

Hi @DMehaffy thanks for your response. I tried achieving this using middleware but as you mentioned its also modifying request for Admin panel. Can you please suggest how can I avoid middleware to execute for Admin panel requests.
My middleware:

    return {
        initialize() {
            strapi.app.use(async (ctx, next) => {
                let response = {};
                await next();
                if (ctx.response.status === 200) {
                    response.status = 'success';
                    response.data = ctx.response.body;
                }
                else {
                    response.status = 'error';
                }
                ctx.response.body = response;
            });
        },
    };
};
1 Like

You could check the ctx.request.route which I think would allow you exclude common Admin routes or you could go the whitelist method if you have a limited number of models and only perform the logic on your own models

(Keep in mind while do this, you will break any potential SDKs we or an external provider build by fundamentally changing the response)