handleUriCall method

Future<Result> handleUriCall(
  1. Server server,
  2. String path,
  3. Uri uri,
  4. String body,
  5. HttpRequest request,
)
inherited

Dispatches a call to the Server to the correct Endpoint method. If successful, it returns the object from the method. If unsuccessful it will return a Result object.

Implementation

Future<Result> handleUriCall(
  Server server,
  String path,
  Uri uri,
  String body,
  HttpRequest request,
) async {
  var endpointComponents = path.split('.');
  if (endpointComponents.isEmpty || endpointComponents.length > 2) {
    return ResultInvalidParams('Endpoint $path is not a valid endpoint name');
  }

  // Find correct connector
  var connector = getConnectorByName(path);
  if (connector == null) {
    return ResultInvalidParams('Endpoint $path does not exist');
  }

  MethodCallSession session;

  try {
    session = MethodCallSession(
      server: server,
      uri: uri,
      body: body,
      path: path,
      httpRequest: request,
      enableLogging: connector.endpoint.logSessions,
    );
  } catch (e) {
    return ResultInvalidParams('Malformed call: $uri');
  }

  var methodName = session.methodName;
  var inputParams = session.queryParameters;

  try {
    var authFailed = await canUserAccessEndpoint(session, connector.endpoint);
    if (authFailed != null) {
      return authFailed;
    }

    var method = connector.methodConnectors[methodName];
    if (method == null) {
      await session.close();
      return ResultInvalidParams(
          'Method $methodName not found in call: $uri');
    }

    // TODO: Check parameters and check null safety

    var paramMap = <String, dynamic>{};
    for (var paramName in inputParams.keys) {
      var type = method.params[paramName]?.type;
      if (type == null) continue;
      var formatted = _formatArg(
          inputParams[paramName], type, server.serializationManager);
      paramMap[paramName] = formatted;
    }

    var result = await method.call(session, paramMap);

    return ResultSuccess(
      result,
      sendByteDataAsRaw: connector.endpoint.sendByteDataAsRaw,
    );
  } on SerializableException catch (exception) {
    return ExceptionResult(model: exception);
  } on Exception catch (e, stackTrace) {
    var sessionLogId = await session.close(error: e, stackTrace: stackTrace);
    return ResultInternalServerError(
        e.toString(), stackTrace, sessionLogId ?? 0);
  } catch (e, stackTrace) {
    // Something did not work out
    var sessionLogId = await session.close(error: e, stackTrace: stackTrace);
    return ResultInternalServerError(
        e.toString(), stackTrace, sessionLogId ?? 0);
  } finally {
    await session.close();
  }
}