handleRoute method Null safety
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,
);
}
}