Plugin server cannot accept body with get request from plugin ui

Hi,

I am developing a custom external plugin in React, on Kibana 8.8.1.

When I give a GET request from plugin ui to server, with a body; the body is still always undefined, even if I validate it with the basic schema. I do get params and query params.

Reference: External Kibana Server Plugin Get Route request.body is Always An Empty Object (similar post)

Thanks

cc @afharo could we please get some eyes on this?

Thanks,
Bhavya

1 Like

Hi,

Can anyone give some input on this?

Apologies for the delay.

It is a current limitation in Kibana: HEAD and GET requests don't support body payloads: https://github.com/elastic/kibana/blob/e4816c66abab94ee47d026781a94dcfa57021554/packages/core/http/core-http-router-server-internal/src/router.ts#L107-L117

As explained here, it goes against the HTTP specs. If you are designing an API that needs a body, you should use any of the other methods available POST, PUT, PATCH.

1 Like

Hi Alejandro,

Hope you are doing well.

Thanks for the clarification.

Actually, I have another Backend server. So the flow of api call/data is from PLUGIN UI -> PLUGIN SERVER -> BACKEND SERVER -> DB and vice versa.

So for some get requests, I need to pass a body from UI to server, and that's the reason I asked for the clarification. As you said, Body is not accepted from PLUGIN UI -> PLUGIN SEFVER GET request, but from PLUGIN SERVER -> Backend, I am able to pass body with GET request.

Now that I know by default, Kibana doesn't allow body with GET requests from plugin ui to server; I was thinking of the below flow.

PLUGIN UI -> PLUGIN SRRVER (all requests will be a POST request, within the body, I will pass method (which can be get, post, put, delete, ...) and the data .

{
    method: 'GET',
    data: {...}
}

So in PLUGIN SERVER, all routes will be post, within which it will check the method attribute passed within the body, and then accordingly makes that request to Backend server.

Eg: We want to GET the list of book, returning only the fields id and name.

PLUGIN UI -> PLUGIN SERVER

const body = {
    method: 'GET',
    data: {
        fields: ['id', 'name']
    }
};
axios.post(url, body);

PLUGIN SERVER -> BACKEND SERVER

router.post(
    {
        path: .....,
        validate: {
            body: {
                method: schema.string(),
                data: schema.maybe(schema.any())
            }
        }
    }
),
async(context, request, response) => {
    const backend_url = '.....';
    const resp = await axios({
        method: request.body.method,
        backend_url,
        data: request.body.data
    }
    .......
}

Is this way of api calling fine?

Thanks

If I'm understanding correctly, you're building something similar to a proxy from the Kibana UI to another backend.

In that case, I think your approach is correct.

In general, servers should not expose the underlying backend implementations and a proper restful API should be designed without passing the complexity of the underlying backend to the UI logic.

Like, assuming the backend service handles students, you could expose the GET methods GET /api/students and GET /api/students/:id, and internally do any other type of calls to the backend if needed.

However, for a quick prototype, I think it's fine to initially have the backend "know-how" in the UI.

TL;DR, your solution should work.

1 Like

Thanks a lot for you response Alejandro :grinning:

1 Like

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.