handleRoute method Null safety

Function handleRoute()

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

Implementation

Function handleRoute() {
  return (final Request request, [final Object? extras]) async {
    try {
      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 methodParams = [];
      for (final parameter in _methodMirror.parameters) {
        final paramName = MirrorSystem.getName(parameter.simpleName);
        if (allParamsWithValue.containsKey(paramName)) {
          methodParams.add(allParamsWithValue[paramName]);
        }
        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]);
            },
          );
          methodParams.add(deserialized.reflectee);
        }
      }

      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,
      );

      final response =
          _clazzMirror.invoke(_methodMirror.simpleName, methodParams);

      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,
      );
    } catch (e, stack) {
      _logger.e('Error handling route', e, stack);
      return Response.internalServerError(body: e.toString());
    }
  };
}