Skip to content
This repository was archived by the owner on Sep 24, 2025. It is now read-only.

to decide: functions API #11

@dbarrosop

Description

@dbarrosop

Functions can accept any combination of headers, methods and even content-types so our SDK should be able to accommodate any potential combination of parameters and assume nothing. In the current implementation we have the following:

  const fetch = async (
    path: string,
    options?: RequestInit,
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
  ): Promise<FetchResponse<any>> => {
    const resp = await enhancedFetch(`${baseURL}${path}`, options);

    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    let body: any;
    // Process response based on content type
    if (resp.headers.get("content-type")?.includes("application/json")) {
      body = await resp.json();
    } else if (resp.headers.get("content-type")?.startsWith("text/")) {
      body = await resp.text();
    } else {
      body = await resp.blob();
    }

    // Create response payload with status, body and headers
    const payload = {
      status: resp.status,
      body: body,
      headers: resp.headers,
    };

    // Throw error for non-OK responses
    if (!resp.ok) {
      throw payload;
    }

    return payload;
  };

so the only processing we do is check for the response type and return an appropiate value for it but I am wondering if we should do no such thing and always return the blob in all cases so the user can process as/if needed.

The only issue is that using this involves passing all the parameters and all headers that fetch needs:

const resp = await nhost.functions.fetch("/myfunction", {
   method: "POST",
   body: JSON.stringify({...}),
   headers: {
      "Content-type": "application/json",
   },
})
// with the implementation above
const payload = resp.body as MyCustomType;
// or if we decide to always return a blob, which might be more efficient in cases where the
// payload doesn't need to be consumed
// const payload = JSON.parse(await resp.body.text()) as MyCustomType;

However, this is a bit cumbersome for the typical case; POST and application/json in the request so we could potentially add an invoke(...) method that:

  1. assumes POST, always, otherwise use fetch
  2. assumes Content-type: application/json
  3. processes the response like in the example above

so it could be used as:

const resp = await nhost.functions.fetch("/myfunction", {
   body: {...},
})
const payload = resp.body as MyCustomType;

thoughts?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions