Dart Documentationclean_ajax.serverMultiRequestHandler

MultiRequestHandler class

Class which can process multiple ClientRequest send in one HttpRequest. Is responsible for unpacking HttpRequest and calling aproriate handler which has been registered inside it.

class MultiRequestHandler {

 final _createLoopBackConnection;

 MultiRequestHandler([this._createLoopBackConnection = createLoopBackConnection]) {
   this.registerHandler("ping", (_) => new Future.value("pong"));
 }

 /**
  * List of handlers for [ClientRequest]. Index is matching with
  * [ClientRequest.type]
  */
 final Map<String, ServerRequestHandler> _registeredExecutors = new Map();
 /**
  * Default handler form [ClientRequest]
  */
 ServerRequestHandler _defaultExecutor = null;

 /**
  * Process [HttpRequest] extract from it [HttpBody]
  * then extract [PackedRequest]s process them and generate proper
  * [HttpResponse]
  */
 void handleHttpRequest(Request request) {
   if (request.type != 'json') {
     throw new Exception('Request type is ${request.type}, '
                         'json was expected!');
   }
   List<PackedRequest> packedRequests =
//        packedRequestsFromJson(JSON.decode(request.body));
       packedRequestsFromJson(request.body);
   // decorate individual clientRequests with authenticatedUserId property

   _splitAndProcessRequests(packedRequests, request.authenticatedUserId)
     .then((response) {
       request.response
         ..headers.contentType = JSON_CONTENT_TYPE
         ..statusCode = HttpStatus.OK
         ..write(JSON.encode({'responses': response, 'authenticatedUserId': request.authenticatedUserId}))
         ..close();
     }).catchError((e) {
       request.response
         ..headers.contentType = JSON_CONTENT_TYPE
         ..statusCode = HttpStatus.BAD_REQUEST
         ..close();
     }, test: (e) => e is UnknownHandlerException);
 }

 Future<List> handleLoopBackRequest(String requests,
                                    authenticatedUserId) {
   return _splitAndProcessRequests(packedRequestsFromJson(JSON.decode(requests)), authenticatedUserId);
 }

 /**
  * Run asynchroniusly [PackedRequest]s in order as they are presented in [requests]
  * and return list of processed results from each request.
  */
 Future<List> _splitAndProcessRequests(List<PackedRequest> requests,
                                       authenticatedUserId) {

   final List responses = new List();
   //now you need to call on each element of requests function _handleClientRequest
   //this calls are asynchronous but must run in sequencial order
   //results from calls are collected inside response
   //if you encounter error during execution of any fuction run you end
   //execution of all next functions and complete future result with error
   return Future.forEach(
            requests,
            (PackedRequest request) {
              // Create new server request from packed request and add
              // authenticatedUserId to it
                ServerRequest serverRequest = new ServerRequest(
                    request.clientRequest.type,
                    request.clientRequest.args,
                    authenticatedUserId,
                    _createLoopBackConnection(this, authenticatedUserId)
                 );

                return _handleServerRequest(serverRequest).then(
                    (response) {
                      responses.add({'id': request.id, 'response': response});
                });
            }
          ).then((_) => new Future.value(responses)).
            catchError((e, s) {
              logger.shout('Exception during request processing: $e \n $s');
              throw e;
          });
 }

 /**
  * Try to find which handler should execute [ServerRequest].
  * If for [ServerRequest.type] is not not registered any executor than will
  * try to run default executor if presented. In other cases throws
  * exception [UnknownHandlerException].
  */
  Future _handleServerRequest(ServerRequest request){
    if(_registeredExecutors.containsKey(request.type)){
      return _registeredExecutors[request.type](request);
    } else if(_defaultExecutor != null) {
      return _defaultExecutor(request);
    } else {
      return new Future.error(new UnknownHandlerException(request.type));
    }
  }

  /**
   * Register default [ClientRequestHandler] for incomming [ClientRequest]
   * Default executor is called only if executor for [ClientRequest.type] is
   * not registerd.
   * Multiple registration cause exception [AlreadyRegisteredHandlerException].
   */
  void registerDefaultHandler(ServerRequestHandler requestExecutor)
  {
    if (_defaultExecutor == null) {
      _defaultExecutor = requestExecutor;
    } else {
      throw new AlreadyRegisteredHandlerException("");
    }
  }

  /**
   * Register [ClientRequestHandler] for incomming [ClientRequest] with
   * [ClientRequest.type] setted to [name]. Multiple registration for
   * same [name] cause exception [AlreadyRegisteredHandlerException].
   */
  void registerHandler(String name, ServerRequestHandler requestExecutor){
    if(_registeredExecutors.containsKey(name)){
      throw new AlreadyRegisteredHandlerException(name);
    } else {
      _registeredExecutors[name] = requestExecutor;
    }
  }
}

Constructors

new MultiRequestHandler([_createLoopBackConnection = createLoopBackConnection]) #

Creates a new Object instance.

Object instances have no meaningful state, and are only useful through their identity. An Object instance is equal to itself only.

docs inherited from Object
MultiRequestHandler([this._createLoopBackConnection = createLoopBackConnection]) {
 this.registerHandler("ping", (_) => new Future.value("pong"));
}

Methods

void handleHttpRequest(Request request) #

Process HttpRequest extract from it HttpBody then extract PackedRequests process them and generate proper HttpResponse

void handleHttpRequest(Request request) {
 if (request.type != 'json') {
   throw new Exception('Request type is ${request.type}, '
                       'json was expected!');
 }
 List<PackedRequest> packedRequests =
//        packedRequestsFromJson(JSON.decode(request.body));
     packedRequestsFromJson(request.body);
 // decorate individual clientRequests with authenticatedUserId property

 _splitAndProcessRequests(packedRequests, request.authenticatedUserId)
   .then((response) {
     request.response
       ..headers.contentType = JSON_CONTENT_TYPE
       ..statusCode = HttpStatus.OK
       ..write(JSON.encode({'responses': response, 'authenticatedUserId': request.authenticatedUserId}))
       ..close();
   }).catchError((e) {
     request.response
       ..headers.contentType = JSON_CONTENT_TYPE
       ..statusCode = HttpStatus.BAD_REQUEST
       ..close();
   }, test: (e) => e is UnknownHandlerException);
}

Future<List> handleLoopBackRequest(String requests, authenticatedUserId) #

Future<List> handleLoopBackRequest(String requests,
                                  authenticatedUserId) {
 return _splitAndProcessRequests(packedRequestsFromJson(JSON.decode(requests)), authenticatedUserId);
}

void registerDefaultHandler(ServerRequestHandler requestExecutor) #

Register default ClientRequestHandler for incomming ClientRequest Default executor is called only if executor for ClientRequest.type is not registerd. Multiple registration cause exception AlreadyRegisteredHandlerException.

void registerDefaultHandler(ServerRequestHandler requestExecutor)
{
 if (_defaultExecutor == null) {
   _defaultExecutor = requestExecutor;
 } else {
   throw new AlreadyRegisteredHandlerException("");
 }
}

void registerHandler(String name, ServerRequestHandler requestExecutor) #

Register ClientRequestHandler for incomming ClientRequest with ClientRequest.type setted to name. Multiple registration for same name cause exception AlreadyRegisteredHandlerException.

void registerHandler(String name, ServerRequestHandler requestExecutor){
 if(_registeredExecutors.containsKey(name)){
   throw new AlreadyRegisteredHandlerException(name);
 } else {
   _registeredExecutors[name] = requestExecutor;
 }
}