handleRoute method Null safety

Future<Response> handleRoute(
  1. Request request,
  2. [Object? extras]
)

Handles the route's response and invoke the _methodMirror in _clazzMirror

Implementation

Future<Response> handleRoute(final Request request,
    [final Object? extras]) async {
  final Map<String, String> pathParams = Map.of(request.params)
    ..removeWhere((key, value) {
      return request.url.queryParameters.containsKey(key);
    });

  final Map<String, Object> allParamsWithValue = {};
  if (pathParams.isNotEmpty) {
    final pathParamValues = _getPathParamsValues(_methodMirror, pathParams);
    allParamsWithValue.addAll(pathParamValues);
  }
  if (request.url.queryParameters.isNotEmpty) {
    final queryParamValues =
        _getQueryParamsValues(_methodMirror, request.url.queryParameters);
    allParamsWithValue.addAll(queryParamValues);
  }

  final List<dynamic> positionalArguments = [];
  final Map<Symbol, dynamic> namedArguments = {};
  for (final parameter in _methodMirror.parameters) {
    final paramName = MirrorSystem.getName(parameter.simpleName);

    if (allParamsWithValue.containsKey(paramName)) {
      if (parameter.isNamed) {
        namedArguments[parameter.simpleName] = allParamsWithValue[paramName];
      } else {
        positionalArguments.add(allParamsWithValue[paramName]);
      }
    } else {
      if (parameter.isOptional) {
        positionalArguments.add(null);
      }

      if (parameter.isNamed) {
        if (parameter.hasDefaultValue) {
          namedArguments[parameter.simpleName] =
              parameter.defaultValue?.reflectee;
        } else {
          namedArguments[parameter.simpleName] = null;
        }
      }
    }
    final containsBodyAnnotation = parameter.metadata.any((metadata) {
      return metadata.reflectee is Body;
    });
    if (containsBodyAnnotation) {
      final bodyReflectedClass = reflectClass(parameter.type.reflectedType);
      // Deserialize the body to the correct type and create an instance of it.
      final deserialized = await request.body.as(
        (reviver) {
          return bodyReflectedClass
              .newInstance(Symbol('fromJson'), [reviver]);
        },
      );
      positionalArguments.add(deserialized.reflectee);
    }

    final containsRequestClass = parameter.type.reflectedType == Request;
    if (containsRequestClass) {
      positionalArguments.add(request);
    }
  }

  final HttpCode? httpStatus = _methodMirror.metadata
      .firstWhereOrNull((meta) => meta.reflectee is HttpCode)
      ?.reflectee;

  final responseStatusCode = httpStatus?.code ?? HttpStatus.ok;

  final Iterable<Header> responseHeaders = _methodMirror.metadata
      .where((meta) => meta.reflectee is Header)
      .map((e) => e.reflectee);

  final Map<String, Object> headers = Map.fromIterable(
    responseHeaders,
    key: (e) => e.key,
    value: (e) => e.value,
  );

  try {
    final response = _clazzMirror.invoke(
      _methodMirror.simpleName,
      positionalArguments,
      namedArguments,
    );

    final result = response.reflectee;
    final dynamic body;
    if (result is Response) {
      return result;
    } else if (result is Future) {
      body = await result;
    } else if (result is Iterable || result is Map || result is Object) {
      body = jsonEncode(result);
    } else {
      body = result;
    }

    return Response(
      responseStatusCode,
      body: body,
      headers: headers,
    );
  } on HttpStatusException catch (e) {
    return Response(
      e.statusCode,
      body: e.message,
    );
  }
}