diff --git a/ExpressAPI/src/middlewares/ParamsCallbackManager.ts b/ExpressAPI/src/middlewares/ParamsCallbackManager.ts
new file mode 100644
index 0000000000000000000000000000000000000000..0c5f6b19720296cd8fc35d838c15849ec53e7b73
--- /dev/null
+++ b/ExpressAPI/src/middlewares/ParamsCallbackManager.ts
@@ -0,0 +1,46 @@
+import { Express }     from 'express-serve-static-core';
+import ApiRequest      from '../models/ApiRequest';
+import express         from 'express';
+import { StatusCodes } from 'http-status-codes';
+
+
+class ParamsCallbackManager {
+    private static _instance: ParamsCallbackManager;
+
+    private constructor() { }
+
+    public static get instance(): ParamsCallbackManager {
+        if ( !ParamsCallbackManager._instance ) {
+            ParamsCallbackManager._instance = new ParamsCallbackManager();
+        }
+
+        return ParamsCallbackManager._instance;
+    }
+
+    protected listenParam(paramName: string, backend: Express, context: any, functionName: string, indexName: string) {
+        backend.param(paramName, (req: ApiRequest, res: express.Response, next: express.NextFunction, id: number | string) => {
+            (context[functionName] as (id: number | Array<number>) => Promise<any>)(typeof id === 'string' ? JSON.parse(id) as Array<number> : id).then(result => {
+                if ( result ) {
+                    this.initBoundParams(req);
+                    (req.boundParams as any)[indexName] = result;
+
+                    next();
+                } else {
+                    req.session.sendResponse(res, StatusCodes.NOT_FOUND, {}, 'Param bounding failed: ' + paramName);
+                }
+            });
+        });
+    }
+
+    initBoundParams(req: ApiRequest) {
+        if ( !req.boundParams ) {
+            req.boundParams = {};
+        }
+    }
+
+    register(backend: Express) {
+    }
+}
+
+
+export default ParamsCallbackManager.instance;