invoke method

Future<FunctionResponse> invoke(
  1. String functionName, {
  2. Map<String, String>? headers,
  3. Map<String, dynamic>? body,
  4. Map<String, dynamic>? queryParameters,
  5. HttpMethod method = HttpMethod.post,
})

Invokes a function

functionName - the name of the function to invoke

headers: object representing the headers to send with the request

body: the body of the request

// Call a standard function
final response = await supabase.functions.invoke('hello-world');
print(response.data);

// Listen to Server Sent Events
final response = await supabase.functions.invoke('sse-function');
response.data
    .transform(const Utf8Decoder())
    .listen((val) {
      print(val);
    });

To stream SSE on the web, you can use a custom HTTP client that is able to handle SSE such as fetch_client.

final fetchClient = FetchClient(mode: RequestMode.cors);
await Supabase.initialize(
  url: supabaseUrl,
  anonKey: supabaseKey,
  httpClient: fetchClient,
);

Implementation

Future<FunctionResponse> invoke(
  String functionName, {
  Map<String, String>? headers,
  Map<String, dynamic>? body,
  Map<String, dynamic>? queryParameters,
  HttpMethod method = HttpMethod.post,
}) async {
  final bodyStr = body == null ? null : await _isolate.encode(body);

  final uri = Uri.parse('$_url/$functionName')
      .replace(queryParameters: queryParameters);

  final finalHeaders = <String, String>{
    ..._headers,
    if (headers != null) ...headers
  };

  final request = http.Request(method.name, uri);

  finalHeaders.forEach((key, value) {
    request.headers[key] = value;
  });
  if (bodyStr != null) request.body = bodyStr;
  final response = await (_httpClient?.send(request) ?? request.send());
  final responseType = (response.headers['Content-Type'] ??
          response.headers['content-type'] ??
          'text/plain')
      .split(';')[0]
      .trim();

  final dynamic data;

  if (responseType == 'application/json') {
    final bodyBytes = await response.stream.toBytes();
    data = bodyBytes.isEmpty
        ? ""
        : await _isolate.decode(utf8.decode(bodyBytes));
  } else if (responseType == 'application/octet-stream') {
    data = await response.stream.toBytes();
  } else if (responseType == 'text/event-stream') {
    data = response.stream;
  } else {
    final bodyBytes = await response.stream.toBytes();
    data = utf8.decode(bodyBytes);
  }

  if (200 <= response.statusCode && response.statusCode < 300) {
    return FunctionResponse(data: data, status: response.statusCode);
  } else {
    throw FunctionException(
      status: response.statusCode,
      details: data,
      reasonPhrase: response.reasonPhrase,
    );
  }
}