diff --git a/api/package-lock.json b/api/package-lock.json
index 39f229d231389f7912f2ead8aa189b0fb27a9b3e..74d865159a05949fc6f0951cf37a5f60a21ee877 100644
--- a/api/package-lock.json
+++ b/api/package-lock.json
@@ -21,6 +21,7 @@
         "@nestjs/typeorm": "^8.0.3",
         "apollo-server-express": "^3.6.3",
         "axios": "^0.21.1",
+        "cache-manager": "^4.0.1",
         "cookie-parser": "^1.4.6",
         "graphql": "^15.5.3",
         "graphql-type-json": "^0.3.2",
@@ -46,6 +47,7 @@
         "@semantic-release/changelog": "^6.0.1",
         "@semantic-release/git": "^10.0.1",
         "@semantic-release/gitlab": "^7.0.4",
+        "@types/cache-manager": "^4.0.0",
         "@types/cookie-parser": "^1.4.2",
         "@types/express": "^4.17.13",
         "@types/jest": "^27.0.1",
@@ -2573,6 +2575,12 @@
         "@types/node": "*"
       }
     },
+    "node_modules/@types/cache-manager": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/@types/cache-manager/-/cache-manager-4.0.0.tgz",
+      "integrity": "sha512-uGnPOCM3PtlqZagds3i8mNyEwKLgZpKgswqmlF2ahmh4D1TN1aLYxYez2PDFDy42IGwLTbuHWSiF62I2jouM7g==",
+      "dev": true
+    },
     "node_modules/@types/cacheable-request": {
       "version": "6.0.2",
       "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz",
@@ -3637,6 +3645,11 @@
         "node": ">=8"
       }
     },
+    "node_modules/async": {
+      "version": "3.2.3",
+      "resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz",
+      "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g=="
+    },
     "node_modules/async-retry": {
       "version": "1.3.3",
       "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz",
@@ -4026,6 +4039,24 @@
         "node": ">= 0.8"
       }
     },
+    "node_modules/cache-manager": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/cache-manager/-/cache-manager-4.0.1.tgz",
+      "integrity": "sha512-JWdtjdX8e0e6eMehAZsdJvBMvHn/pVQGYUjgzc1ILFH0vtcffb9R7XIEAqfYgEeaVJVCOSP4+dxCius+ciW0RA==",
+      "dependencies": {
+        "async": "3.2.3",
+        "lodash.clonedeep": "^4.5.0",
+        "lru-cache": "^7.10.1"
+      }
+    },
+    "node_modules/cache-manager/node_modules/lru-cache": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.10.1.tgz",
+      "integrity": "sha512-BQuhQxPuRl79J5zSXRP+uNzPOyZw2oFI9JLRQ80XswSvg21KMKNtQza9eF42rfI/3Z40RvzBdXgziEkudzjo8A==",
+      "engines": {
+        "node": ">=12"
+      }
+    },
     "node_modules/cacheable-lookup": {
       "version": "5.0.4",
       "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz",
@@ -8593,6 +8624,11 @@
       "integrity": "sha1-+CbJtOKoUR2E46yinbBeGk87cqk=",
       "dev": true
     },
+    "node_modules/lodash.clonedeep": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
+      "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ=="
+    },
     "node_modules/lodash.escaperegexp": {
       "version": "4.1.2",
       "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz",
@@ -17318,6 +17354,12 @@
         "@types/node": "*"
       }
     },
+    "@types/cache-manager": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/@types/cache-manager/-/cache-manager-4.0.0.tgz",
+      "integrity": "sha512-uGnPOCM3PtlqZagds3i8mNyEwKLgZpKgswqmlF2ahmh4D1TN1aLYxYez2PDFDy42IGwLTbuHWSiF62I2jouM7g==",
+      "dev": true
+    },
     "@types/cacheable-request": {
       "version": "6.0.2",
       "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz",
@@ -18200,6 +18242,11 @@
       "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==",
       "dev": true
     },
+    "async": {
+      "version": "3.2.3",
+      "resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz",
+      "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g=="
+    },
     "async-retry": {
       "version": "1.3.3",
       "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz",
@@ -18506,6 +18553,23 @@
       "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
       "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="
     },
+    "cache-manager": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/cache-manager/-/cache-manager-4.0.1.tgz",
+      "integrity": "sha512-JWdtjdX8e0e6eMehAZsdJvBMvHn/pVQGYUjgzc1ILFH0vtcffb9R7XIEAqfYgEeaVJVCOSP4+dxCius+ciW0RA==",
+      "requires": {
+        "async": "3.2.3",
+        "lodash.clonedeep": "^4.5.0",
+        "lru-cache": "^7.10.1"
+      },
+      "dependencies": {
+        "lru-cache": {
+          "version": "7.10.1",
+          "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.10.1.tgz",
+          "integrity": "sha512-BQuhQxPuRl79J5zSXRP+uNzPOyZw2oFI9JLRQ80XswSvg21KMKNtQza9eF42rfI/3Z40RvzBdXgziEkudzjo8A=="
+        }
+      }
+    },
     "cacheable-lookup": {
       "version": "5.0.4",
       "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz",
@@ -22003,6 +22067,11 @@
       "integrity": "sha1-+CbJtOKoUR2E46yinbBeGk87cqk=",
       "dev": true
     },
+    "lodash.clonedeep": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
+      "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ=="
+    },
     "lodash.escaperegexp": {
       "version": "4.1.2",
       "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz",
diff --git a/api/package.json b/api/package.json
index 1e71e563cc9c3fa4fd9c0f1b13328690e937541c..41ac9d65ba74232143c5a2d9db79e93ef7ba5e2d 100644
--- a/api/package.json
+++ b/api/package.json
@@ -38,6 +38,7 @@
     "@nestjs/typeorm": "^8.0.3",
     "apollo-server-express": "^3.6.3",
     "axios": "^0.21.1",
+    "cache-manager": "^4.0.1",
     "cookie-parser": "^1.4.6",
     "graphql": "^15.5.3",
     "graphql-type-json": "^0.3.2",
@@ -63,6 +64,7 @@
     "@semantic-release/changelog": "^6.0.1",
     "@semantic-release/git": "^10.0.1",
     "@semantic-release/gitlab": "^7.0.4",
+    "@types/cache-manager": "^4.0.0",
     "@types/cookie-parser": "^1.4.2",
     "@types/express": "^4.17.13",
     "@types/jest": "^27.0.1",
diff --git a/api/src/auth/auth.resolver.spec.ts b/api/src/auth/auth.resolver.spec.ts
index e545b55cb221ba157e2f5afcf44f86ac6b7fa7c1..7890a9e5bc8f52774599a6a66a14a9a54ee75a04 100644
--- a/api/src/auth/auth.resolver.spec.ts
+++ b/api/src/auth/auth.resolver.spec.ts
@@ -1,11 +1,9 @@
 import { getMockRes } from '@jest-mock/express';
 import { Test, TestingModule } from '@nestjs/testing';
 import { MockFunctionMetadata, ModuleMocker } from 'jest-mock';
-import LocalService from '../engine/connectors/local/main.connector';
-import {
-  ENGINE_MODULE_OPTIONS,
-  ENGINE_SERVICE,
-} from '../engine/engine.constants';
+import EngineService from '../engine/engine.service';
+import LocalService from '../engine/connectors/local/local.connector';
+import { ENGINE_MODULE_OPTIONS } from '../engine/engine.constants';
 import { User } from '../users/models/user.model';
 import { authConstants } from './auth-constants';
 import { AuthResolver } from './auth.resolver';
@@ -40,7 +38,7 @@ describe('AuthResolver', () => {
     const module: TestingModule = await Test.createTestingModule({
       providers: [
         {
-          provide: ENGINE_SERVICE,
+          provide: EngineService,
           useClass: LocalService,
         },
         {
diff --git a/api/src/auth/auth.resolver.ts b/api/src/auth/auth.resolver.ts
index 4742be80f7a9237c6787596412a7618aa3bbb8b4..cf3208a99b76554b383a8dd3c181805f38d9ce06 100644
--- a/api/src/auth/auth.resolver.ts
+++ b/api/src/auth/auth.resolver.ts
@@ -10,11 +10,7 @@ import { Response, Request } from 'express';
 import { CurrentUser } from '../common/decorators/user.decorator';
 import { GQLRequest } from '../common/decorators/gql-request.decoractor';
 import { GQLResponse } from '../common/decorators/gql-response.decoractor';
-import {
-  ENGINE_MODULE_OPTIONS,
-  ENGINE_SERVICE,
-} from '../engine/engine.constants';
-import { IEngineOptions, IEngineService } from '../engine/engine.interfaces';
+import { ENGINE_MODULE_OPTIONS } from '../engine/engine.constants';
 import { User } from '../users/models/user.model';
 import { authConstants } from './auth-constants';
 import { AuthService } from './auth.service';
@@ -23,6 +19,8 @@ import { LocalAuthGuard } from './guards/local-auth.guard';
 import { AuthenticationInput } from './inputs/authentication.input';
 import { AuthenticationOutput } from './outputs/authentication.output';
 import { parseToBoolean } from '../common/utils/shared.utils';
+import EngineOptions from '../engine/interfaces/engine-options.interface';
+import EngineService from '../engine/engine.service';
 
 //Custom defined type because Pick<CookieOptions, 'sameSite'> does not work
 type SameSiteType = boolean | 'lax' | 'strict' | 'none' | undefined;
@@ -32,9 +30,9 @@ export class AuthResolver {
   private readonly logger = new Logger(AuthResolver.name);
 
   constructor(
-    @Inject(ENGINE_SERVICE) private readonly engineService: IEngineService,
+    private readonly engineService: EngineService,
     @Inject(ENGINE_MODULE_OPTIONS)
-    private readonly engineOptions: IEngineOptions,
+    private readonly engineOptions: EngineOptions,
     private readonly authService: AuthService,
     private readonly configService: ConfigService,
   ) {}
@@ -82,7 +80,9 @@ export class AuthResolver {
     if (user) {
       this.logger.verbose(`${user.username} logged out`);
       try {
-        await this.engineService.logout?.(req);
+        if (this.engineService.has('logout')) {
+          await this.engineService.logout(req);
+        }
       } catch (e) {
         this.logger.debug(
           `Service ${this.engineOptions.type} produce an error when logging out ${user.username}`,
diff --git a/api/src/auth/auth.service.spec.ts b/api/src/auth/auth.service.spec.ts
index 454ce9230371e3a5e8bd01d7469ae25252dbd859..ea689bdf469a81b7e8bdc4d9429a87598406d05c 100644
--- a/api/src/auth/auth.service.spec.ts
+++ b/api/src/auth/auth.service.spec.ts
@@ -1,18 +1,23 @@
 import { JwtService } from '@nestjs/jwt';
 import { Test, TestingModule } from '@nestjs/testing';
 import { MockFunctionMetadata, ModuleMocker } from 'jest-mock';
-import LocalService from '../engine/connectors/local/main.connector';
-import {
-  ENGINE_MODULE_OPTIONS,
-  ENGINE_SERVICE,
-} from '../engine/engine.constants';
+import { ENGINE_MODULE_OPTIONS } from '../engine/engine.constants';
 import { AuthService } from './auth.service';
 import { User } from '../users/models/user.model';
+import EngineService from '../engine/engine.service';
 
 const moduleMocker = new ModuleMocker(global);
 
+type MockEngineService = Partial<Record<keyof EngineService, jest.Mock>>;
+
+const createEngineService = (): MockEngineService => ({
+  login: jest.fn(),
+  has: jest.fn(),
+});
+
 describe('AuthService', () => {
-  let service: AuthService;
+  let authService: AuthService;
+  let engineService: MockEngineService;
   const user: User = {
     id: 'dummy',
     username: 'dummy64',
@@ -23,8 +28,8 @@ describe('AuthService', () => {
     const module: TestingModule = await Test.createTestingModule({
       providers: [
         {
-          provide: ENGINE_SERVICE,
-          useClass: LocalService,
+          provide: EngineService,
+          useValue: createEngineService(),
         },
         {
           provide: ENGINE_MODULE_OPTIONS,
@@ -52,17 +57,25 @@ describe('AuthService', () => {
       })
       .compile();
 
-    service = module.get<AuthService>(AuthService);
+    authService = module.get<AuthService>(AuthService);
+    engineService = module.get<EngineService>(
+      EngineService,
+    ) as unknown as MockEngineService;
   });
 
   it('login', async () => {
-    const data = await service.login(user);
+    const data = await authService.login(user);
 
     expect(data.accessToken).toBe(jwtToken);
   });
 
   it('validateUser', async () => {
-    const data = await service.validateUser('guest', 'password123');
+    engineService.has.mockReturnValue(true);
+    engineService.login.mockReturnValue({
+      id: '1',
+      username: 'dummy64',
+    });
+    const data = await authService.validateUser('guest', 'password123');
 
     expect(!!data).toBeTruthy();
   });
diff --git a/api/src/auth/auth.service.ts b/api/src/auth/auth.service.ts
index 402dfc63663a790d20462090114550ace92095b0..8300b9a1649ce7683d0559c2814dbde94fec16bc 100644
--- a/api/src/auth/auth.service.ts
+++ b/api/src/auth/auth.service.ts
@@ -1,20 +1,19 @@
-import { Inject, Injectable, NotImplementedException } from '@nestjs/common';
+import { Injectable, NotImplementedException } from '@nestjs/common';
 import { JwtService } from '@nestjs/jwt';
-import { ENGINE_SERVICE } from '../engine/engine.constants';
-import { IEngineService } from '../engine/engine.interfaces';
+import EngineService from '../engine/engine.service';
 import { User } from '../users/models/user.model';
 import { AuthenticationOutput } from './outputs/authentication.output';
 
 @Injectable()
 export class AuthService {
   constructor(
-    @Inject(ENGINE_SERVICE) private readonly engineService: IEngineService,
+    private readonly engineService: EngineService,
     private jwtService: JwtService,
   ) {}
 
   async validateUser(username: string, password: string): Promise<User> {
-    if (!this.engineService.login) throw new NotImplementedException();
-    return this.engineService.login?.(username, password);
+    if (!this.engineService.has('login')) throw new NotImplementedException();
+    return this.engineService.login(username, password);
   }
 
   /**
diff --git a/api/src/auth/strategies/engine.strategy.ts b/api/src/auth/strategies/engine.strategy.ts
index f98cedecbbdbb0a2b5f05a426a5a15a0172b713a..7bf68c2df41d842645f11ce8bb36891213ec6f84 100644
--- a/api/src/auth/strategies/engine.strategy.ts
+++ b/api/src/auth/strategies/engine.strategy.ts
@@ -1,20 +1,17 @@
-import { Inject, Injectable } from '@nestjs/common';
+import { Injectable } from '@nestjs/common';
 import { PassportStrategy } from '@nestjs/passport';
-import { ENGINE_SERVICE } from 'src/engine/engine.constants';
-import { IEngineService } from 'src/engine/engine.interfaces';
 import { Request } from 'express';
 import { Strategy } from 'passport-custom';
+import EngineService from '../../engine/engine.service';
 
 @Injectable()
 export class EngineStrategy extends PassportStrategy(Strategy, 'engine') {
-  constructor(
-    @Inject(ENGINE_SERVICE) private readonly engineService: IEngineService,
-  ) {
+  constructor(private readonly engineService: EngineService) {
     super();
   }
 
   async validate(req: Request) {
-    if (!this.engineService.getActiveUser) return false;
+    if (!this.engineService.has('getActiveUser')) return false;
     const user = this.engineService.getActiveUser(req);
 
     return user ?? false;
diff --git a/api/src/config/cache.config.ts b/api/src/config/cache.config.ts
new file mode 100644
index 0000000000000000000000000000000000000000..763d7d5b3bcc73dbdfeabdebdba94f4837b1f8ed
--- /dev/null
+++ b/api/src/config/cache.config.ts
@@ -0,0 +1,12 @@
+import { registerAs } from '@nestjs/config';
+import { parseToBoolean } from '../common/utils/shared.utils';
+
+export default registerAs('cache', () => {
+  const max = process.env.CACHE_MAX_ITEMS;
+  const ttl = process.env.CACHE_TTL;
+  return {
+    enabled: parseToBoolean(process.env.CACHE_ENABLED, false),
+    ttl: ttl ? parseInt(ttl) : undefined,
+    max: max ? parseInt(max) : undefined,
+  };
+});
diff --git a/api/src/engine/connectors/csv/main.connector.ts b/api/src/engine/connectors/csv/csv.connector.ts
similarity index 92%
rename from api/src/engine/connectors/csv/main.connector.ts
rename to api/src/engine/connectors/csv/csv.connector.ts
index ebb2ee15b229eea60e6e75c3f70160f6a3fae249..2d3a80cce5935712fdb5663ce50f8239d45bddb7 100644
--- a/api/src/engine/connectors/csv/main.connector.ts
+++ b/api/src/engine/connectors/csv/csv.connector.ts
@@ -5,15 +5,16 @@ import {
   Dictionary,
   ExperimentResult,
 } from 'src/common/interfaces/utilities.interface';
-import { IEngineOptions, IEngineService } from 'src/engine/engine.interfaces';
+import Connector from 'src/engine/interfaces/connector.interface';
+import EngineOptions from 'src/engine/interfaces/engine-options.interface';
 import { Domain } from 'src/engine/models/domain.model';
 import { Algorithm } from 'src/engine/models/experiment/algorithm.model';
 import { Group } from 'src/engine/models/group.model';
 import { User } from 'src/users/models/user.model';
 
-export default class CSVService implements IEngineService {
+export default class CSVConnector implements Connector {
   constructor(
-    private readonly options: IEngineOptions,
+    private readonly options: EngineOptions,
     private readonly httpService: HttpService,
   ) {}
 
diff --git a/api/src/engine/connectors/datashield/main.connector.ts b/api/src/engine/connectors/datashield/datashield.connector.ts
similarity index 91%
rename from api/src/engine/connectors/datashield/main.connector.ts
rename to api/src/engine/connectors/datashield/datashield.connector.ts
index ef0a5435be672b66b77822be656f380211b0ba28..e9d325e722b3d3ee3fee0d44597ffabdf2914574 100644
--- a/api/src/engine/connectors/datashield/main.connector.ts
+++ b/api/src/engine/connectors/datashield/datashield.connector.ts
@@ -8,11 +8,9 @@ import {
 } from 'src/common/interfaces/utilities.interface';
 import { errorAxiosHandler } from 'src/common/utils/shared.utils';
 import { ENGINE_MODULE_OPTIONS } from 'src/engine/engine.constants';
-import {
-  IConfiguration,
-  IEngineOptions,
-  IEngineService,
-} from 'src/engine/engine.interfaces';
+import ConnectorConfiguration from 'src/engine/interfaces/connector-configuration.interface';
+import Connector from 'src/engine/interfaces/connector.interface';
+import EngineOptions from 'src/engine/interfaces/engine-options.interface';
 import { Domain } from 'src/engine/models/domain.model';
 import { Algorithm } from 'src/engine/models/experiment/algorithm.model';
 import { Experiment } from 'src/engine/models/experiment/experiment.model';
@@ -31,15 +29,15 @@ import {
   transformToTable,
 } from './transformations';
 
-export default class DataShieldService implements IEngineService {
-  private static readonly logger = new Logger(DataShieldService.name);
+export default class DataShieldConnector implements Connector {
+  private static readonly logger = new Logger(DataShieldConnector.name);
   headers = {};
   constructor(
-    @Inject(ENGINE_MODULE_OPTIONS) private readonly options: IEngineOptions,
+    @Inject(ENGINE_MODULE_OPTIONS) private readonly options: EngineOptions,
     private readonly httpService: HttpService,
   ) {}
 
-  getConfiguration(): IConfiguration {
+  getConfiguration(): ConnectorConfiguration {
     return {
       hasGalaxy: false,
       hasGrouping: false,
@@ -104,8 +102,8 @@ export default class DataShieldService implements IEngineService {
     );
 
     if (response.data['global'] === undefined) {
-      DataShieldService.logger.warn('Cannot parse histogram result');
-      DataShieldService.logger.verbose(path);
+      DataShieldConnector.logger.warn('Cannot parse histogram result');
+      DataShieldConnector.logger.verbose(path);
       return {
         rawdata: {
           data:
diff --git a/api/src/engine/connectors/exareme/converters.ts b/api/src/engine/connectors/exareme/converters.ts
index b25282036fd29e191bf130d7779b8c9fe58f07b6..86b58070bbca5bfcada6303b2ec4806b6df9ced8 100644
--- a/api/src/engine/connectors/exareme/converters.ts
+++ b/api/src/engine/connectors/exareme/converters.ts
@@ -5,8 +5,6 @@ import {
   Experiment,
   ExperimentStatus,
 } from 'src/engine/models/experiment/experiment.model';
-import { AlgorithmParamInput } from 'src/experiments/models/input/algorithm-parameter.input';
-import { ExperimentCreateInput } from 'src/experiments/models/input/experiment-create.input';
 import { Group } from 'src/engine/models/group.model';
 import { ResultUnion } from 'src/engine/models/result/common/result-union.model';
 import {
@@ -17,6 +15,8 @@ import { HeatMapResult } from 'src/engine/models/result/heat-map-result.model';
 import { LineChartResult } from 'src/engine/models/result/line-chart-result.model';
 import { RawResult } from 'src/engine/models/result/raw-result.model';
 import { Variable } from 'src/engine/models/variable.model';
+import { AlgorithmParamInput } from 'src/experiments/models/input/algorithm-parameter.input';
+import { ExperimentCreateInput } from 'src/experiments/models/input/experiment-create.input';
 import { Entity } from './interfaces/entity.interface';
 import { ExperimentData } from './interfaces/experiment/experiment.interface';
 import { ResultChartExperiment } from './interfaces/experiment/result-chart-experiment.interface';
diff --git a/api/src/engine/connectors/exareme/main.connector.ts b/api/src/engine/connectors/exareme/exareme.connector.ts
similarity index 95%
rename from api/src/engine/connectors/exareme/main.connector.ts
rename to api/src/engine/connectors/exareme/exareme.connector.ts
index a2ca7a392434df5eca124b1167244730dd299160..60acbd5f9042b11f1c3c562d0b95ea18b57ebcc6 100644
--- a/api/src/engine/connectors/exareme/main.connector.ts
+++ b/api/src/engine/connectors/exareme/exareme.connector.ts
@@ -11,11 +11,9 @@ import { AxiosRequestConfig } from 'axios';
 import { Request } from 'express';
 import { firstValueFrom, map, Observable } from 'rxjs';
 import { ENGINE_MODULE_OPTIONS } from 'src/engine/engine.constants';
-import {
-  IConfiguration,
-  IEngineOptions,
-  IEngineService,
-} from 'src/engine/engine.interfaces';
+import ConnectorConfiguration from 'src/engine/interfaces/connector-configuration.interface';
+import Connector from 'src/engine/interfaces/connector.interface';
+import EngineOptions from 'src/engine/interfaces/engine-options.interface';
 import { Domain } from 'src/engine/models/domain.model';
 import { Algorithm } from 'src/engine/models/experiment/algorithm.model';
 import {
@@ -47,9 +45,9 @@ import transformToAlgorithms from './transformations/algorithms';
 type Headers = Record<string, string>;
 
 @Injectable()
-export default class ExaremeService implements IEngineService {
+export default class ExaremeConnector implements Connector {
   constructor(
-    @Inject(ENGINE_MODULE_OPTIONS) private readonly options: IEngineOptions,
+    @Inject(ENGINE_MODULE_OPTIONS) private readonly options: EngineOptions,
     private readonly httpService: HttpService,
   ) {}
 
@@ -66,7 +64,7 @@ export default class ExaremeService implements IEngineService {
     ];
   }
 
-  getConfiguration(): IConfiguration {
+  getConfiguration(): ConnectorConfiguration {
     return {
       contactLink: 'https://ebrains.eu/support/',
       hasGalaxy: true,
diff --git a/api/src/engine/connectors/exareme/handlers/algorithms/PCA.handler.spec.ts b/api/src/engine/connectors/exareme/handlers/algorithms/PCA.handler.spec.ts
index 7b414bda9c4ae870c272c0c1fce525327fb613fa..d2a299b68ae5de8399e3c4116548d2303a04e971 100644
--- a/api/src/engine/connectors/exareme/handlers/algorithms/PCA.handler.spec.ts
+++ b/api/src/engine/connectors/exareme/handlers/algorithms/PCA.handler.spec.ts
@@ -78,7 +78,7 @@ describe('PCA result handler', () => {
 
   it('Test PCA handler with regular data (no edge cases)', () => {
     const exp = createExperiment();
-    handlers(exp, data);
+    handlers(exp, data, null);
     expect(exp.results.length).toBeGreaterThanOrEqual(2);
 
     exp.results.forEach((it) => {
diff --git a/api/src/engine/connectors/exareme/handlers/algorithms/anova-one-way.handler.spec.ts b/api/src/engine/connectors/exareme/handlers/algorithms/anova-one-way.handler.spec.ts
index bc55d0dc7b83b6c92f2ac6ce5ffa4d7831736d07..0de41ca99cd43c14bfb389c58ee28934dcb49f78 100644
--- a/api/src/engine/connectors/exareme/handlers/algorithms/anova-one-way.handler.spec.ts
+++ b/api/src/engine/connectors/exareme/handlers/algorithms/anova-one-way.handler.spec.ts
@@ -140,7 +140,7 @@ describe('Anova oneway result handler', () => {
     const table2 = anovaHandler.getTuckeyTable(data);
     const meanPlot = anovaHandler.getMeanPlot(data);
 
-    handlers(exp, data);
+    handlers(exp, data, null);
 
     expect(exp.results.length).toBeGreaterThanOrEqual(3);
     expect(exp.results).toContainEqual(table1);
diff --git a/api/src/engine/connectors/exareme/handlers/algorithms/anova-one-way.handler.ts b/api/src/engine/connectors/exareme/handlers/algorithms/anova-one-way.handler.ts
index 42ff6da38781827fe8393159aac7c8e35840a8af..d52d088f9234d00d5aa06329b9d7d49e71a002a8 100644
--- a/api/src/engine/connectors/exareme/handlers/algorithms/anova-one-way.handler.ts
+++ b/api/src/engine/connectors/exareme/handlers/algorithms/anova-one-way.handler.ts
@@ -1,4 +1,5 @@
 import * as jsonata from 'jsonata'; // old import style needed due to 'export = jsonata'
+import { Domain } from 'src/engine/models/domain.model';
 import { MeanChartResult } from 'src/engine/models/result/means-chart-result.model';
 import { Experiment } from '../../../../models/experiment/experiment.model';
 import {
@@ -97,8 +98,9 @@ export default class AnovaOneWayHandler extends BaseHandler {
     return AnovaOneWayHandler.meanPlotTransform.evaluate(data);
   }
 
-  handle(exp: Experiment, data: unknown): void {
-    if (!this.canHandle(exp.algorithm.name)) return super.handle(exp, data);
+  handle(exp: Experiment, data: unknown, domain: Domain): void {
+    if (!this.canHandle(exp.algorithm.name))
+      return super.handle(exp, data, domain);
 
     const summaryTable = this.getSummaryTable(data, exp.coVariables[0]);
     if (summaryTable) exp.results.push(summaryTable);
@@ -109,6 +111,6 @@ export default class AnovaOneWayHandler extends BaseHandler {
     const meanPlot = this.getMeanPlot(data);
     if (meanPlot && meanPlot.pointCIs) exp.results.push(meanPlot);
 
-    return super.handle(exp, data); // continue request
+    return super.handle(exp, data, domain); // continue request
   }
 }
diff --git a/api/src/engine/connectors/exareme/handlers/algorithms/area.handler.ts b/api/src/engine/connectors/exareme/handlers/algorithms/area.handler.ts
deleted file mode 100644
index 6e096e31c85d37193089acc4039f2a949c2dfd2e..0000000000000000000000000000000000000000
--- a/api/src/engine/connectors/exareme/handlers/algorithms/area.handler.ts
+++ /dev/null
@@ -1,55 +0,0 @@
-import * as jsonata from 'jsonata'; // old import style needed due to 'export = jsonata'
-import { Experiment } from '../../../../../engine/models/experiment/experiment.model';
-import { ResultChartExperiment } from '../../interfaces/experiment/result-chart-experiment.interface';
-import BaseHandler from '../base.handler';
-
-export default class AreaHandler extends BaseHandler {
-  private static readonly transform = jsonata(`
-  ({
-      "name": data.title.text,
-      "xAxis": {
-          "label": data.xAxis.title.text
-      },
-      "yAxis": {
-          "label": data.yAxis.title.text
-      },
-      "lines": [
-          {
-              "label": "ROC curve",
-              "x": data.series.data.$[0],
-              "y": data.series.data.$[1],
-              "type": 0
-          }
-      ]
-  })
-  `);
-
-  canHandle(input: ResultChartExperiment): boolean {
-    try {
-      return (
-        input.type === 'application/vnd.highcharts+json' &&
-        input.data?.chart?.type === 'area'
-      );
-    } catch (e) {
-      AreaHandler.logger.log('Error when parsing input from experiment');
-      AreaHandler.logger.debug(e);
-      return false;
-    }
-  }
-
-  handle(exp: Experiment, data: unknown): void {
-    let req = data;
-    const inputs = data as ResultChartExperiment[];
-
-    if (inputs && Array.isArray(inputs)) {
-      inputs
-        .filter(this.canHandle)
-        .map((input) => AreaHandler.transform.evaluate(input))
-        .forEach((input) => exp.results.push(input));
-
-      req = JSON.stringify(inputs.filter((input) => !this.canHandle(input)));
-    }
-
-    this.next?.handle(exp, req);
-  }
-}
diff --git a/api/src/engine/connectors/exareme/handlers/algorithms/heat-map.handler.ts b/api/src/engine/connectors/exareme/handlers/algorithms/heat-map.handler.ts
deleted file mode 100644
index 47d937a04a5e0223ba6b636cd5cfe7094076dc8a..0000000000000000000000000000000000000000
--- a/api/src/engine/connectors/exareme/handlers/algorithms/heat-map.handler.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-import * as jsonata from 'jsonata'; // old import style needed due to 'export = jsonata'
-import { Experiment } from '../../../../models/experiment/experiment.model';
-import { ResultChartExperiment } from '../../interfaces/experiment/result-chart-experiment.interface';
-import BaseHandler from '../base.handler';
-
-export default class HeatMapHandler extends BaseHandler {
-  private static readonly transform = jsonata(`
-  (
-      {
-          "name": data.title.text,
-          "xAxis": {
-              "categories": data.xAxis.categories,
-              "label": data.xAxis.label
-          },
-          "yAxis": {
-              "categories": data.yAxis.categories,
-              "label": data.yAxis.label
-          },
-          "matrix": $toMat(data.series.data)
-      }
-  )
-  `);
-
-  canHandle(input: ResultChartExperiment): boolean {
-    return (
-      input.type.toLowerCase() === 'application/vnd.highcharts+json' &&
-      input.data.chart.type.toLowerCase() === 'heatmap'
-    );
-  }
-
-  handle(exp: Experiment, data: unknown): void {
-    let req = data;
-    const inputs = data as ResultChartExperiment[];
-
-    if (inputs && Array.isArray(inputs)) {
-      inputs
-        .filter(this.canHandle)
-        .map((input) => HeatMapHandler.transform.evaluate(input))
-        .forEach((input) => exp.results.push(input));
-
-      req = JSON.stringify(inputs.filter((input) => !this.canHandle(input)));
-    }
-
-    this.next?.handle(exp, req);
-  }
-}
diff --git a/api/src/engine/connectors/exareme/handlers/algorithms/linear-regression.handler.spec.ts b/api/src/engine/connectors/exareme/handlers/algorithms/linear-regression.handler.spec.ts
index 3c29918a110de73ac3b02b7d3a0994ce607efe24..c2d6561e6268d278e3da3eed70a8264c67033ac0 100644
--- a/api/src/engine/connectors/exareme/handlers/algorithms/linear-regression.handler.spec.ts
+++ b/api/src/engine/connectors/exareme/handlers/algorithms/linear-regression.handler.spec.ts
@@ -1,3 +1,4 @@
+import { Domain } from 'src/engine/models/domain.model';
 import { Experiment } from '../../../../models/experiment/experiment.model';
 import LinearRegressionHandler from './linear-regression.handler';
 
@@ -22,6 +23,20 @@ const data = {
   upper_ci: [0.2755544764379397, 0.6451975487993219, 1.132126625132179],
 };
 
+const domain: Domain = {
+  id: 'dummy-id',
+  groups: [],
+  rootGroup: {
+    id: 'dummy-id',
+  },
+  datasets: [{ id: 'desd-synthdata', label: 'Dead Synthdata' }],
+  variables: [
+    { id: 'lefthippocampus', label: 'Left Hippo Campus' },
+    { id: 'righthippocampus', label: 'Right Hippo Campus' },
+    { id: 'leftamygdala', label: 'Left Amygdala' },
+  ],
+};
+
 const createExperiment = (): Experiment => ({
   id: 'dummy-id',
   name: 'Testing purpose',
@@ -30,8 +45,8 @@ const createExperiment = (): Experiment => ({
   },
   datasets: ['desd-synthdata'],
   domain: 'dementia',
-  variables: ['righthippocampus'],
-  coVariables: ['leftamygdala'],
+  variables: ['lefthippocampus'],
+  coVariables: ['righthippocampus', 'leftamygdala'],
   results: [],
 });
 
@@ -46,13 +61,16 @@ describe('Linear regression result handler', () => {
 
   describe('Handle', () => {
     it('with standard linear algo data', () => {
-      linearHandler.handle(experiment, data);
+      linearHandler.handle(experiment, data, domain);
+
+      const json = JSON.stringify(experiment.results);
 
+      expect(json.includes(domain.variables[0].label)).toBeTruthy();
       expect(experiment.results.length === 2);
     });
     it('Should be empty with another algo', () => {
       experiment.algorithm.name = 'dummy_algo';
-      linearHandler.handle(experiment, data);
+      linearHandler.handle(experiment, data, domain);
 
       expect(experiment.results.length === 0);
     });
diff --git a/api/src/engine/connectors/exareme/handlers/algorithms/linear-regression.handler.ts b/api/src/engine/connectors/exareme/handlers/algorithms/linear-regression.handler.ts
index dc9236ff40ee25e7522d629c4cea568e75fa00d5..68266f9376f6523b82de120e333bbb1df17674b4 100644
--- a/api/src/engine/connectors/exareme/handlers/algorithms/linear-regression.handler.ts
+++ b/api/src/engine/connectors/exareme/handlers/algorithms/linear-regression.handler.ts
@@ -1,3 +1,5 @@
+import { Domain } from 'src/engine/models/domain.model';
+import { Variable } from 'src/engine/models/variable.model';
 import { isNumber } from '../../../../../common/utils/shared.utils';
 import { Experiment } from '../../../../models/experiment/experiment.model';
 import {
@@ -7,7 +9,7 @@ import {
 import BaseHandler from '../base.handler';
 
 const NUMBER_PRECISION = 4;
-const ALGO_NANE = 'linear_regression';
+const ALGO_NAME = 'linear_regression';
 const lookupDict = {
   dependent_var: 'Dependent variable',
   n_obs: 'Number of observations',
@@ -88,14 +90,29 @@ export default class LinearRegressionHandler extends BaseHandler {
     return tableCoef;
   }
 
-  handle(experiment: Experiment, data: any): void {
-    if (experiment.algorithm.name.toLowerCase() !== ALGO_NANE)
-      return super.handle(experiment, data);
+  getLabelFromVariableId(id: string, vars: Variable[]): string {
+    const varible = vars.find((v) => v.id === id);
+    return varible.label ?? id;
+  }
+
+  handle(experiment: Experiment, data: any, domain: Domain): void {
+    if (experiment.algorithm.name.toLowerCase() !== ALGO_NAME)
+      return super.handle(experiment, data, domain);
+
+    const varIds = [...experiment.variables, ...(experiment.coVariables ?? [])];
+    const variables = domain.variables.filter((v) => varIds.includes(v.id));
+
+    let jsonData = JSON.stringify(data);
+    variables.forEach((v) => {
+      const regEx = new RegExp(v.id, 'gi');
+      jsonData = jsonData.replaceAll(regEx, v.label);
+    });
+    const improvedData = JSON.parse(jsonData);
 
-    const model = this.getModel(data);
+    const model = this.getModel(improvedData);
     if (model) experiment.results.push(model);
 
-    const coefs = this.getCoefficients(data);
+    const coefs = this.getCoefficients(improvedData);
     if (coefs) experiment.results.push(coefs);
   }
 }
diff --git a/api/src/engine/connectors/exareme/handlers/algorithms/pearson.handler.spec.ts b/api/src/engine/connectors/exareme/handlers/algorithms/pearson.handler.spec.ts
index 36a2759dff39197636dad6efbbaee39d37d2e7ce..17abd4315ce007d48502d9924416720d50b2ba91 100644
--- a/api/src/engine/connectors/exareme/handlers/algorithms/pearson.handler.spec.ts
+++ b/api/src/engine/connectors/exareme/handlers/algorithms/pearson.handler.spec.ts
@@ -423,7 +423,7 @@ describe('Pearson result handler', () => {
       'high_confidence_intervals',
     ];
 
-    handlers(exp, data);
+    handlers(exp, data, null);
     const results = exp.results as HeatMapResult[];
 
     const heatmaps = names.map((name) =>
diff --git a/api/src/engine/connectors/exareme/handlers/base.handler.ts b/api/src/engine/connectors/exareme/handlers/base.handler.ts
index 5934cf82008004b964a52601b2af21c08d9357d3..1aa3d2f6391922b10e1d9b29bf9c9a74fef0d575 100644
--- a/api/src/engine/connectors/exareme/handlers/base.handler.ts
+++ b/api/src/engine/connectors/exareme/handlers/base.handler.ts
@@ -1,4 +1,5 @@
 import { Logger } from '@nestjs/common';
+import { Domain } from 'src/engine/models/domain.model';
 import { Experiment } from '../../../models/experiment/experiment.model';
 import ResultHandler from './result-handler.interface';
 
@@ -12,7 +13,7 @@ export default abstract class BaseHandler implements ResultHandler {
     return h;
   }
 
-  handle(experiment: Experiment, data: unknown): void {
-    this.next?.handle(experiment, data);
+  handle(experiment: Experiment, data: unknown, domain: Domain): void {
+    this.next?.handle(experiment, data, domain);
   }
 }
diff --git a/api/src/engine/connectors/exareme/handlers/index.ts b/api/src/engine/connectors/exareme/handlers/index.ts
index 1dca0fce5e88d570f1f7f754be57a30b766d1045..d45dae7f3e0990ec3fe4255d12b46fa372a8a6ad 100644
--- a/api/src/engine/connectors/exareme/handlers/index.ts
+++ b/api/src/engine/connectors/exareme/handlers/index.ts
@@ -1,8 +1,7 @@
+import { Domain } from 'src/engine/models/domain.model';
 import { Experiment } from '../../../../engine/models/experiment/experiment.model';
 import AnovaOneWayHandler from './algorithms/anova-one-way.handler';
-import AreaHandler from './algorithms/area.handler';
 import DescriptiveHandler from './algorithms/descriptive.handler';
-import HeatMapHandler from './algorithms/heat-map.handler';
 import LinearRegressionHandler from './algorithms/linear-regression.handler';
 import PCAHandler from './algorithms/PCA.handler';
 import PearsonHandler from './algorithms/pearson.handler';
@@ -11,15 +10,13 @@ import RawHandler from './algorithms/raw.handler';
 const start = new PearsonHandler();
 
 start
-  .setNext(new AreaHandler())
   .setNext(new DescriptiveHandler())
-  .setNext(new HeatMapHandler())
   .setNext(new AnovaOneWayHandler())
   .setNext(new PCAHandler())
   .setNext(new LinearRegressionHandler())
   .setNext(new RawHandler()); // should be last handler as it works as a fallback (if other handlers could not process the results)
 
-export default (exp: Experiment, data: unknown): Experiment => {
+export default (exp: Experiment, data: unknown, domain: Domain): Experiment => {
   start.handle(exp, data);
   return exp;
 };
diff --git a/api/src/engine/connectors/exareme/handlers/result-handler.interface.ts b/api/src/engine/connectors/exareme/handlers/result-handler.interface.ts
index 661c2a437015b8a75950394a2f27380602cbb25b..3c82f7d32ca56246281bcb09c996565d77a518eb 100644
--- a/api/src/engine/connectors/exareme/handlers/result-handler.interface.ts
+++ b/api/src/engine/connectors/exareme/handlers/result-handler.interface.ts
@@ -1,7 +1,8 @@
+import { Domain } from 'src/engine/models/domain.model';
 import { Experiment } from '../../../models/experiment/experiment.model';
 
 // produce algo handler
 export default interface ResultHandler {
   setNext(h: ResultHandler): ResultHandler;
-  handle(partialExperiment: Experiment, data: unknown): void;
+  handle(partialExperiment: Experiment, data: unknown, domain?: Domain): void;
 }
diff --git a/api/src/engine/connectors/exareme/interfaces/test-utilities.ts b/api/src/engine/connectors/exareme/interfaces/test-utilities.ts
index 6746a8f2b736a9e9668504e98f5b54aa83563cd9..26596046209d10901b4467ca5c778baa17cca69b 100644
--- a/api/src/engine/connectors/exareme/interfaces/test-utilities.ts
+++ b/api/src/engine/connectors/exareme/interfaces/test-utilities.ts
@@ -1,6 +1,6 @@
-import { IEngineService } from 'src/engine/engine.interfaces';
-import { Experiment } from 'src/engine/models/experiment/experiment.model';
-import { ExperimentCreateInput } from 'src/experiments/models/input/experiment-create.input';
+import EngineService from '../../../engine.service';
+import { Experiment } from '../../../models/experiment/experiment.model';
+import { ExperimentCreateInput } from '../../../../experiments/models/input/experiment-create.input';
 
 const TIMEOUT_DURATION_SECONDS = 60 * 10;
 
@@ -28,14 +28,14 @@ const TEST_PATHOLOGIES = {
 
 const createExperiment = async (
   input: ExperimentCreateInput,
-  service: IEngineService,
+  service: EngineService,
 ): Promise<Experiment | undefined> => {
   return service.createExperiment(input, false);
 };
 
 const waitForResult = (
   id: string,
-  service: IEngineService,
+  service: EngineService,
 ): Promise<Experiment> =>
   new Promise((resolve, reject) => {
     let elapsed = 0;
diff --git a/api/src/engine/connectors/exareme/tests/e2e/3c.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/3c.e2e-spec.ts
index 7b4d577e146933477f7eb5507da49860f2a03463..e64ca3e15f6eb8d66a83ef6baad8628bbf2a642e 100644
--- a/api/src/engine/connectors/exareme/tests/e2e/3c.e2e-spec.ts
+++ b/api/src/engine/connectors/exareme/tests/e2e/3c.e2e-spec.ts
@@ -1,7 +1,5 @@
 import { Test, TestingModule } from '@nestjs/testing';
 import { AppModule } from '../../../../../main/app.module';
-import { ENGINE_SERVICE } from '../../../../engine.constants';
-import { IEngineService } from '../../../../engine.interfaces';
 import { ExperimentCreateInput } from '../../../../../experiments/models/input/experiment-create.input';
 import {
   createExperiment,
@@ -10,18 +8,19 @@ import {
   TIMEOUT_DURATION_SECONDS,
   waitForResult,
 } from '../../interfaces/test-utilities';
+import EngineService from '../../../../../engine/engine.service';
 
 jest.setTimeout(1000 * TIMEOUT_DURATION_SECONDS);
 
 describe('ExaremeService', () => {
-  let exaremeService: IEngineService;
+  let exaremeService: EngineService;
 
   beforeEach(async () => {
     const moduleRef: TestingModule = await Test.createTestingModule({
       imports: [AppModule],
     }).compile();
 
-    exaremeService = await moduleRef.resolve<IEngineService>(ENGINE_SERVICE);
+    exaremeService = await moduleRef.resolve<EngineService>(EngineService);
   });
 
   const modelSlug = `3c-${generateNumber()}`;
diff --git a/api/src/engine/connectors/exareme/tests/e2e/calibration-belt.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/calibration-belt.e2e-spec.ts
index 2e696f066825ade2f7ba74e6fe3d091f8a77d4ca..254e03e012adf6fa8fced8486864034a04830e98 100644
--- a/api/src/engine/connectors/exareme/tests/e2e/calibration-belt.e2e-spec.ts
+++ b/api/src/engine/connectors/exareme/tests/e2e/calibration-belt.e2e-spec.ts
@@ -1,8 +1,7 @@
 import { Test, TestingModule } from '@nestjs/testing';
-import { AppModule } from '../../../../../main/app.module';
-import { ENGINE_SERVICE } from '../../../../engine.constants';
-import { IEngineService } from '../../../../engine.interfaces';
+import EngineService from '../../../../../engine/engine.service';
 import { ExperimentCreateInput } from '../../../../../experiments/models/input/experiment-create.input';
+import { AppModule } from '../../../../../main/app.module';
 import {
   createExperiment,
   generateNumber,
@@ -14,14 +13,14 @@ import {
 jest.setTimeout(1000 * TIMEOUT_DURATION_SECONDS);
 
 describe('ExaremeService', () => {
-  let exaremeService: IEngineService;
+  let exaremeService: EngineService;
 
   beforeEach(async () => {
     const moduleRef: TestingModule = await Test.createTestingModule({
       imports: [AppModule],
     }).compile();
 
-    exaremeService = await moduleRef.resolve<IEngineService>(ENGINE_SERVICE);
+    exaremeService = await moduleRef.resolve<EngineService>(EngineService);
   });
 
   const modelSlug = `calibration-belt-${generateNumber()}`;
diff --git a/api/src/engine/connectors/exareme/tests/e2e/cart.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/cart.e2e-spec.ts
index 550e75c2da6abb999d06b88a72d068d548d3b0e0..639f1d3085b3563e86b32a779559fa221bad41cd 100644
--- a/api/src/engine/connectors/exareme/tests/e2e/cart.e2e-spec.ts
+++ b/api/src/engine/connectors/exareme/tests/e2e/cart.e2e-spec.ts
@@ -1,9 +1,8 @@
 import { Test, TestingModule } from '@nestjs/testing';
-import { RawResult } from 'src/engine/models/result/raw-result.model';
-import { AppModule } from '../../../../../main/app.module';
-import { ENGINE_SERVICE } from '../../../../engine.constants';
-import { IEngineService } from '../../../../engine.interfaces';
+import EngineService from '../../../../../engine/engine.service';
 import { ExperimentCreateInput } from '../../../../../experiments/models/input/experiment-create.input';
+import { AppModule } from '../../../../../main/app.module';
+import { RawResult } from '../../../../models/result/raw-result.model';
 import {
   createExperiment,
   generateNumber,
@@ -15,14 +14,14 @@ import {
 jest.setTimeout(1000 * TIMEOUT_DURATION_SECONDS);
 
 describe('ExaremeService', () => {
-  let exaremeService: IEngineService;
+  let exaremeService: EngineService;
 
   beforeEach(async () => {
     const moduleRef: TestingModule = await Test.createTestingModule({
       imports: [AppModule],
     }).compile();
 
-    exaremeService = await moduleRef.resolve<IEngineService>(ENGINE_SERVICE);
+    exaremeService = await moduleRef.resolve<EngineService>(EngineService);
   });
   const modelSlug = `cart-${generateNumber()}`;
   const algorithmId = 'CART';
diff --git a/api/src/engine/connectors/exareme/tests/e2e/descriptiveStatistics.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/descriptiveStatistics.e2e-spec.ts
index 12737e18d39cf0bfd21dbd5828b36ea687627cbd..3d549536f2e7a6b56f017e8122e4f110cb594db2 100644
--- a/api/src/engine/connectors/exareme/tests/e2e/descriptiveStatistics.e2e-spec.ts
+++ b/api/src/engine/connectors/exareme/tests/e2e/descriptiveStatistics.e2e-spec.ts
@@ -1,10 +1,9 @@
 import { Test, TestingModule } from '@nestjs/testing';
-import { GroupsResult } from 'src/engine/models/result/groups-result.model';
-import { TableResult } from 'src/engine/models/result/table-result.model';
-import { AppModule } from '../../../../../main/app.module';
-import { ENGINE_SERVICE } from '../../../../engine.constants';
-import { IEngineService } from '../../../../engine.interfaces';
+import EngineService from '../../../../../engine/engine.service';
 import { ExperimentCreateInput } from '../../../../../experiments/models/input/experiment-create.input';
+import { AppModule } from '../../../../../main/app.module';
+import { GroupsResult } from '../../../../models/result/groups-result.model';
+import { TableResult } from '../../../../models/result/table-result.model';
 import {
   createExperiment,
   generateNumber,
@@ -16,14 +15,14 @@ import {
 jest.setTimeout(1000 * TIMEOUT_DURATION_SECONDS);
 
 describe('ExaremeService', () => {
-  let exaremeService: IEngineService;
+  let exaremeService: EngineService;
 
   beforeEach(async () => {
     const moduleRef: TestingModule = await Test.createTestingModule({
       imports: [AppModule],
     }).compile();
 
-    exaremeService = await moduleRef.resolve<IEngineService>(ENGINE_SERVICE);
+    exaremeService = await moduleRef.resolve<EngineService>(EngineService);
   });
   const modelSlug = `statistics-${generateNumber()}`;
   const algorithmId = 'DESCRIPTIVE_STATS';
diff --git a/api/src/engine/connectors/exareme/tests/e2e/id3.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/id3.e2e-spec.ts
index 6a34e183b7127d893019b7950c30228965feb417..922734f5fe6d9ab089e181a1c34d5f7e96853a79 100644
--- a/api/src/engine/connectors/exareme/tests/e2e/id3.e2e-spec.ts
+++ b/api/src/engine/connectors/exareme/tests/e2e/id3.e2e-spec.ts
@@ -1,9 +1,8 @@
 import { Test, TestingModule } from '@nestjs/testing';
-import { RawResult } from 'src/engine/models/result/raw-result.model';
-import { AppModule } from '../../../../../main/app.module';
-import { ENGINE_SERVICE } from '../../../../engine.constants';
-import { IEngineService } from '../../../../engine.interfaces';
+import EngineService from '../../../../../engine/engine.service';
 import { ExperimentCreateInput } from '../../../../../experiments/models/input/experiment-create.input';
+import { AppModule } from '../../../../../main/app.module';
+import { RawResult } from '../../../../models/result/raw-result.model';
 import {
   createExperiment,
   generateNumber,
@@ -15,14 +14,14 @@ import {
 jest.setTimeout(1000 * TIMEOUT_DURATION_SECONDS);
 
 describe('ExaremeService', () => {
-  let exaremeService: IEngineService;
+  let exaremeService: EngineService;
 
   beforeEach(async () => {
     const moduleRef: TestingModule = await Test.createTestingModule({
       imports: [AppModule],
     }).compile();
 
-    exaremeService = await moduleRef.resolve<IEngineService>(ENGINE_SERVICE);
+    exaremeService = await moduleRef.resolve<EngineService>(EngineService);
   });
   const modelSlug = `id3-${generateNumber()}`;
   const algorithmId = 'ID3';
diff --git a/api/src/engine/connectors/exareme/tests/e2e/k-means.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/k-means.e2e-spec.ts
index b754a068478c679d04158f4776d14ae041063fd0..7253261295736adce6de2de271ec35f2d2ce936a 100644
--- a/api/src/engine/connectors/exareme/tests/e2e/k-means.e2e-spec.ts
+++ b/api/src/engine/connectors/exareme/tests/e2e/k-means.e2e-spec.ts
@@ -1,9 +1,8 @@
 import { Test, TestingModule } from '@nestjs/testing';
-import { RawResult } from 'src/engine/models/result/raw-result.model';
-import { AppModule } from '../../../../../main/app.module';
-import { ENGINE_SERVICE } from '../../../../engine.constants';
-import { IEngineService } from '../../../../engine.interfaces';
+import EngineService from '../../../../../engine/engine.service';
 import { ExperimentCreateInput } from '../../../../../experiments/models/input/experiment-create.input';
+import { AppModule } from '../../../../../main/app.module';
+import { RawResult } from '../../../../models/result/raw-result.model';
 import {
   createExperiment,
   generateNumber,
@@ -15,14 +14,14 @@ import {
 jest.setTimeout(1000 * TIMEOUT_DURATION_SECONDS);
 
 describe('ExaremeService', () => {
-  let exaremeService: IEngineService;
+  let exaremeService: EngineService;
 
   beforeEach(async () => {
     const moduleRef: TestingModule = await Test.createTestingModule({
       imports: [AppModule],
     }).compile();
 
-    exaremeService = await moduleRef.resolve<IEngineService>(ENGINE_SERVICE);
+    exaremeService = await moduleRef.resolve<EngineService>(EngineService);
   });
   const modelSlug = `kmeans-${generateNumber()}`;
   const algorithmId = 'KMEANS';
diff --git a/api/src/engine/connectors/exareme/tests/e2e/kaplan-meier.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/kaplan-meier.e2e-spec.ts
index 2defac942a734cf22d9bd2c5442d5d13012f2ad5..e0e6e41f33b2308ff1395d9b5553376a27f1472a 100644
--- a/api/src/engine/connectors/exareme/tests/e2e/kaplan-meier.e2e-spec.ts
+++ b/api/src/engine/connectors/exareme/tests/e2e/kaplan-meier.e2e-spec.ts
@@ -1,8 +1,7 @@
 import { Test, TestingModule } from '@nestjs/testing';
-import { AppModule } from '../../../../../main/app.module';
-import { ENGINE_SERVICE } from '../../../../engine.constants';
-import { IEngineService } from '../../../../engine.interfaces';
+import EngineService from '../../../../../engine/engine.service';
 import { ExperimentCreateInput } from '../../../../../experiments/models/input/experiment-create.input';
+import { AppModule } from '../../../../../main/app.module';
 import {
   createExperiment,
   generateNumber,
@@ -14,14 +13,14 @@ import {
 jest.setTimeout(1000 * TIMEOUT_DURATION_SECONDS);
 
 describe('ExaremeService', () => {
-  let exaremeService: IEngineService;
+  let exaremeService: EngineService;
 
   beforeEach(async () => {
     const moduleRef: TestingModule = await Test.createTestingModule({
       imports: [AppModule],
     }).compile();
 
-    exaremeService = await moduleRef.resolve<IEngineService>(ENGINE_SERVICE);
+    exaremeService = await moduleRef.resolve<EngineService>(EngineService);
   });
   const modelSlug = `kaplan-meier-${generateNumber()}`;
   const algorithmId = 'KAPLAN_MEIER';
diff --git a/api/src/engine/connectors/exareme/tests/e2e/linear-regression.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/linear-regression.e2e-spec.ts
index e50a0ad83a18a9dadd2025daa2a06db7abe39b67..928ee3b790586126acdf01b6dfc0461b67a6d975 100644
--- a/api/src/engine/connectors/exareme/tests/e2e/linear-regression.e2e-spec.ts
+++ b/api/src/engine/connectors/exareme/tests/e2e/linear-regression.e2e-spec.ts
@@ -1,9 +1,8 @@
 import { Test, TestingModule } from '@nestjs/testing';
-import { RawResult } from 'src/engine/models/result/raw-result.model';
-import { AppModule } from '../../../../../main/app.module';
-import { ENGINE_SERVICE } from '../../../../engine.constants';
-import { IEngineService } from '../../../../engine.interfaces';
+import EngineService from '../../../../../engine/engine.service';
 import { ExperimentCreateInput } from '../../../../../experiments/models/input/experiment-create.input';
+import { AppModule } from '../../../../../main/app.module';
+import { RawResult } from '../../../../models/result/raw-result.model';
 import {
   createExperiment,
   generateNumber,
@@ -15,14 +14,14 @@ import {
 jest.setTimeout(1000 * TIMEOUT_DURATION_SECONDS);
 
 describe('ExaremeService', () => {
-  let exaremeService: IEngineService;
+  let exaremeService: EngineService;
 
   beforeEach(async () => {
     const moduleRef: TestingModule = await Test.createTestingModule({
       imports: [AppModule],
     }).compile();
 
-    exaremeService = await moduleRef.resolve<IEngineService>(ENGINE_SERVICE);
+    exaremeService = await moduleRef.resolve<EngineService>(EngineService);
   });
   const modelSlug = `linear-${generateNumber()}`;
   const algorithmId = 'LINEAR_REGRESSION';
diff --git a/api/src/engine/connectors/exareme/tests/e2e/logistic-regression.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/logistic-regression.e2e-spec.ts
index 50bc9e66a37b0ed4d66c375690df53890d8a74e5..9ca333a190ae0b4419adc04712bc32f4150de18f 100644
--- a/api/src/engine/connectors/exareme/tests/e2e/logistic-regression.e2e-spec.ts
+++ b/api/src/engine/connectors/exareme/tests/e2e/logistic-regression.e2e-spec.ts
@@ -1,9 +1,8 @@
 import { Test, TestingModule } from '@nestjs/testing';
-import { RawResult } from 'src/engine/models/result/raw-result.model';
-import { AppModule } from '../../../../../main/app.module';
-import { ENGINE_SERVICE } from '../../../../engine.constants';
-import { IEngineService } from '../../../../engine.interfaces';
+import EngineService from '../../../../../engine/engine.service';
 import { ExperimentCreateInput } from '../../../../../experiments/models/input/experiment-create.input';
+import { AppModule } from '../../../../../main/app.module';
+import { RawResult } from '../../../../models/result/raw-result.model';
 import {
   createExperiment,
   generateNumber,
@@ -15,14 +14,14 @@ import {
 jest.setTimeout(1000 * TIMEOUT_DURATION_SECONDS);
 
 describe('ExaremeService', () => {
-  let exaremeService: IEngineService;
+  let exaremeService: EngineService;
 
   beforeEach(async () => {
     const moduleRef: TestingModule = await Test.createTestingModule({
       imports: [AppModule],
     }).compile();
 
-    exaremeService = await moduleRef.resolve<IEngineService>(ENGINE_SERVICE);
+    exaremeService = await moduleRef.resolve<EngineService>(EngineService);
   });
   const modelSlug = `logistic-${generateNumber()}`;
   const algorithmId = 'LOGISTIC_REGRESSION';
diff --git a/api/src/engine/connectors/exareme/tests/e2e/multiple-histograms.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/multiple-histograms.e2e-spec.ts
index 8eba2965e0422dc52ab85785fb8841225d9b8dd0..f1ad948db341733b4892aa95ddbcbfe709381030 100644
--- a/api/src/engine/connectors/exareme/tests/e2e/multiple-histograms.e2e-spec.ts
+++ b/api/src/engine/connectors/exareme/tests/e2e/multiple-histograms.e2e-spec.ts
@@ -1,8 +1,7 @@
 import { Test, TestingModule } from '@nestjs/testing';
-import { AppModule } from '../../../../../main/app.module';
-import { ENGINE_SERVICE } from '../../../../engine.constants';
-import { IEngineService } from '../../../../engine.interfaces';
+import EngineService from '../../../../../engine/engine.service';
 import { ExperimentCreateInput } from '../../../../../experiments/models/input/experiment-create.input';
+import { AppModule } from '../../../../../main/app.module';
 import {
   createExperiment,
   generateNumber,
@@ -14,14 +13,14 @@ import {
 jest.setTimeout(1000 * TIMEOUT_DURATION_SECONDS);
 
 describe('ExaremeService', () => {
-  let exaremeService: IEngineService;
+  let exaremeService: EngineService;
 
   beforeEach(async () => {
     const moduleRef: TestingModule = await Test.createTestingModule({
       imports: [AppModule],
     }).compile();
 
-    exaremeService = await moduleRef.resolve<IEngineService>(ENGINE_SERVICE);
+    exaremeService = await moduleRef.resolve<EngineService>(EngineService);
   });
   const modelSlug = `histograms-${generateNumber()}`;
   const algorithmId = 'MULTIPLE_HISTOGRAMS';
diff --git a/api/src/engine/connectors/exareme/tests/e2e/naive-bayes.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/naive-bayes.e2e-spec.ts
index cefa59cb015af49116d53836e23541e393fbff9f..893a7af2f7cc1ae2e5e36fe932df0fb1ba81a55c 100644
--- a/api/src/engine/connectors/exareme/tests/e2e/naive-bayes.e2e-spec.ts
+++ b/api/src/engine/connectors/exareme/tests/e2e/naive-bayes.e2e-spec.ts
@@ -1,8 +1,7 @@
 import { Test, TestingModule } from '@nestjs/testing';
-import { AppModule } from '../../../../../main/app.module';
-import { ENGINE_SERVICE } from '../../../../engine.constants';
-import { IEngineService } from '../../../../engine.interfaces';
+import EngineService from '../../../../../engine/engine.service';
 import { ExperimentCreateInput } from '../../../../../experiments/models/input/experiment-create.input';
+import { AppModule } from '../../../../../main/app.module';
 import { RawResult } from '../../../../models/result/raw-result.model';
 import {
   createExperiment,
@@ -15,14 +14,14 @@ import {
 jest.setTimeout(1000 * TIMEOUT_DURATION_SECONDS);
 
 describe('ExaremeService', () => {
-  let exaremeService: IEngineService;
+  let exaremeService: EngineService;
 
   beforeEach(async () => {
     const moduleRef: TestingModule = await Test.createTestingModule({
       imports: [AppModule],
     }).compile();
 
-    exaremeService = await moduleRef.resolve<IEngineService>(ENGINE_SERVICE);
+    exaremeService = await moduleRef.resolve<EngineService>(EngineService);
   });
   const modelSlug = `naivebayes-${generateNumber()}`;
   const algorithmId = 'NAIVE_BAYES';
diff --git a/api/src/engine/connectors/exareme/tests/e2e/one-way-anova.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/one-way-anova.e2e-spec.ts
index 3f954f584b4397cf2d0c1e1a40904cde758314bb..54b9b31a10d8f94facd43c1bf8d8a8bffeea1661 100644
--- a/api/src/engine/connectors/exareme/tests/e2e/one-way-anova.e2e-spec.ts
+++ b/api/src/engine/connectors/exareme/tests/e2e/one-way-anova.e2e-spec.ts
@@ -1,9 +1,7 @@
 import { Test, TestingModule } from '@nestjs/testing';
-import { AppModule } from '../../../../../main/app.module';
-import { ENGINE_SERVICE } from '../../../../engine.constants';
-import { IEngineService } from '../../../../engine.interfaces';
+import EngineService from '../../../../../engine/engine.service';
 import { ExperimentCreateInput } from '../../../../../experiments/models/input/experiment-create.input';
-import { RawResult } from '../../../../models/result/raw-result.model';
+import { AppModule } from '../../../../../main/app.module';
 import {
   createExperiment,
   generateNumber,
@@ -15,14 +13,14 @@ import {
 jest.setTimeout(1000 * TIMEOUT_DURATION_SECONDS);
 
 describe('ExaremeService', () => {
-  let exaremeService: IEngineService;
+  let exaremeService: EngineService;
 
   beforeEach(async () => {
     const moduleRef: TestingModule = await Test.createTestingModule({
       imports: [AppModule],
     }).compile();
 
-    exaremeService = await moduleRef.resolve<IEngineService>(ENGINE_SERVICE);
+    exaremeService = await moduleRef.resolve<EngineService>(EngineService);
   });
   const modelSlug = `anova-1way-${generateNumber()}`;
   const algorithmId = 'ANOVA_ONEWAY';
diff --git a/api/src/engine/connectors/exareme/tests/e2e/pca.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/pca.e2e-spec.ts
index 36f78cfd0b876c1e2f42a22775d3fa2a634e0244..9c23cbbb9bf454c55c15c293c41d0adb1ccc36f6 100644
--- a/api/src/engine/connectors/exareme/tests/e2e/pca.e2e-spec.ts
+++ b/api/src/engine/connectors/exareme/tests/e2e/pca.e2e-spec.ts
@@ -1,8 +1,7 @@
 import { Test, TestingModule } from '@nestjs/testing';
-import { AppModule } from '../../../../../main/app.module';
-import { ENGINE_SERVICE } from '../../../../engine.constants';
-import { IEngineService } from '../../../../engine.interfaces';
+import EngineService from '../../../../../engine/engine.service';
 import { ExperimentCreateInput } from '../../../../../experiments/models/input/experiment-create.input';
+import { AppModule } from '../../../../../main/app.module';
 import { RawResult } from '../../../../models/result/raw-result.model';
 import {
   createExperiment,
@@ -15,14 +14,14 @@ import {
 jest.setTimeout(1000 * TIMEOUT_DURATION_SECONDS);
 
 describe('ExaremeService', () => {
-  let exaremeService: IEngineService;
+  let exaremeService: EngineService;
 
   beforeEach(async () => {
     const moduleRef: TestingModule = await Test.createTestingModule({
       imports: [AppModule],
     }).compile();
 
-    exaremeService = await moduleRef.resolve<IEngineService>(ENGINE_SERVICE);
+    exaremeService = await moduleRef.resolve<EngineService>(EngineService);
   });
   const modelSlug = `pca-${generateNumber()}`;
   const algorithmId = 'PCA';
diff --git a/api/src/engine/connectors/exareme/tests/e2e/pearson-correlation.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/pearson-correlation.e2e-spec.ts
index 8bc3f92e4d1bbecdade74e1e71f200851ec37aba..dd36eac8d92b0a60f1e2563c8a1d55e56052eabf 100644
--- a/api/src/engine/connectors/exareme/tests/e2e/pearson-correlation.e2e-spec.ts
+++ b/api/src/engine/connectors/exareme/tests/e2e/pearson-correlation.e2e-spec.ts
@@ -1,8 +1,7 @@
 import { Test, TestingModule } from '@nestjs/testing';
-import { AppModule } from '../../../../../main/app.module';
-import { ENGINE_SERVICE } from '../../../../engine.constants';
-import { IEngineService } from '../../../../engine.interfaces';
+import EngineService from '../../../../../engine/engine.service';
 import { ExperimentCreateInput } from '../../../../../experiments/models/input/experiment-create.input';
+import { AppModule } from '../../../../../main/app.module';
 import { RawResult } from '../../../../models/result/raw-result.model';
 import {
   createExperiment,
@@ -15,14 +14,14 @@ import {
 jest.setTimeout(1000 * TIMEOUT_DURATION_SECONDS);
 
 describe('ExaremeService', () => {
-  let exaremeService: IEngineService;
+  let exaremeService: EngineService;
 
   beforeEach(async () => {
     const moduleRef: TestingModule = await Test.createTestingModule({
       imports: [AppModule],
     }).compile();
 
-    exaremeService = await moduleRef.resolve<IEngineService>(ENGINE_SERVICE);
+    exaremeService = await moduleRef.resolve<EngineService>(EngineService);
   });
   const modelSlug = `pearson-${generateNumber()}`;
   const algorithmId = 'PEARSON_CORRELATION';
diff --git a/api/src/engine/connectors/exareme/tests/e2e/t-test-independant.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/t-test-independant.e2e-spec.ts
index 208516e44e45e53dabce70264c1593981850dc64..a15c9ace53b6292dfab0a02fb59edc20656ff27c 100644
--- a/api/src/engine/connectors/exareme/tests/e2e/t-test-independant.e2e-spec.ts
+++ b/api/src/engine/connectors/exareme/tests/e2e/t-test-independant.e2e-spec.ts
@@ -1,8 +1,7 @@
 import { Test, TestingModule } from '@nestjs/testing';
-import { AppModule } from '../../../../../main/app.module';
-import { ENGINE_SERVICE } from '../../../../engine.constants';
-import { IEngineService } from '../../../../engine.interfaces';
+import EngineService from '../../../../../engine/engine.service';
 import { ExperimentCreateInput } from '../../../../../experiments/models/input/experiment-create.input';
+import { AppModule } from '../../../../../main/app.module';
 import { RawResult } from '../../../../models/result/raw-result.model';
 import {
   createExperiment,
@@ -15,14 +14,14 @@ import {
 jest.setTimeout(1000 * TIMEOUT_DURATION_SECONDS);
 
 describe('ExaremeService', () => {
-  let exaremeService: IEngineService;
+  let exaremeService: EngineService;
 
   beforeEach(async () => {
     const moduleRef: TestingModule = await Test.createTestingModule({
       imports: [AppModule],
     }).compile();
 
-    exaremeService = await moduleRef.resolve<IEngineService>(ENGINE_SERVICE);
+    exaremeService = await moduleRef.resolve<EngineService>(EngineService);
   });
   const modelSlug = `ttest-idp-${generateNumber()}`;
   const algorithmId = 'TTEST_INDEPENDENT';
diff --git a/api/src/engine/connectors/exareme/tests/e2e/t-test-one-sample.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/t-test-one-sample.e2e-spec.ts
index c9cf5af84eaa172671cf173be42e48c156498f9a..c49169d6d3bb08d337fc6b6a1516f18cf6800423 100644
--- a/api/src/engine/connectors/exareme/tests/e2e/t-test-one-sample.e2e-spec.ts
+++ b/api/src/engine/connectors/exareme/tests/e2e/t-test-one-sample.e2e-spec.ts
@@ -1,8 +1,7 @@
 import { Test, TestingModule } from '@nestjs/testing';
-import { AppModule } from '../../../../../main/app.module';
-import { ENGINE_SERVICE } from '../../../../engine.constants';
-import { IEngineService } from '../../../../engine.interfaces';
+import EngineService from '../../../../../engine/engine.service';
 import { ExperimentCreateInput } from '../../../../../experiments/models/input/experiment-create.input';
+import { AppModule } from '../../../../../main/app.module';
 import { RawResult } from '../../../../models/result/raw-result.model';
 import {
   createExperiment,
@@ -15,14 +14,14 @@ import {
 jest.setTimeout(1000 * TIMEOUT_DURATION_SECONDS);
 
 describe('ExaremeService', () => {
-  let exaremeService: IEngineService;
+  let exaremeService: EngineService;
 
   beforeEach(async () => {
     const moduleRef: TestingModule = await Test.createTestingModule({
       imports: [AppModule],
     }).compile();
 
-    exaremeService = await moduleRef.resolve<IEngineService>(ENGINE_SERVICE);
+    exaremeService = await moduleRef.resolve<EngineService>(EngineService);
   });
   const modelSlug = `ttest-1s-${generateNumber()}`;
   const algorithmId = 'TTEST_ONESAMPLE';
diff --git a/api/src/engine/connectors/exareme/tests/e2e/t-test-paired.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/t-test-paired.e2e-spec.ts
index 45d2220683082f9c67656d4751f2990fc74e52d8..95fa4c3fa4d74d9f0904e9f4171fc81e5e2edc32 100644
--- a/api/src/engine/connectors/exareme/tests/e2e/t-test-paired.e2e-spec.ts
+++ b/api/src/engine/connectors/exareme/tests/e2e/t-test-paired.e2e-spec.ts
@@ -1,8 +1,7 @@
 import { Test, TestingModule } from '@nestjs/testing';
-import { AppModule } from '../../../../../main/app.module';
-import { ENGINE_SERVICE } from '../../../../engine.constants';
-import { IEngineService } from '../../../../engine.interfaces';
+import EngineService from '../../../../../engine/engine.service';
 import { ExperimentCreateInput } from '../../../../../experiments/models/input/experiment-create.input';
+import { AppModule } from '../../../../../main/app.module';
 import { RawResult } from '../../../../models/result/raw-result.model';
 import {
   createExperiment,
@@ -15,14 +14,14 @@ import {
 jest.setTimeout(1000 * TIMEOUT_DURATION_SECONDS);
 
 describe('ExaremeService', () => {
-  let exaremeService: IEngineService;
+  let exaremeService: EngineService;
 
   beforeEach(async () => {
     const moduleRef: TestingModule = await Test.createTestingModule({
       imports: [AppModule],
     }).compile();
 
-    exaremeService = await moduleRef.resolve<IEngineService>(ENGINE_SERVICE);
+    exaremeService = await moduleRef.resolve<EngineService>(EngineService);
   });
   const modelSlug = `ttest-paired-${generateNumber()}`;
   const algorithmId = 'TTEST_PAIRED';
diff --git a/api/src/engine/connectors/exareme/tests/e2e/two-way-anova.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/two-way-anova.e2e-spec.ts
index 021723c69dad30ec292b656d128be0bfc34598a1..80c65495461375baf6bca3714778402480aa2b66 100644
--- a/api/src/engine/connectors/exareme/tests/e2e/two-way-anova.e2e-spec.ts
+++ b/api/src/engine/connectors/exareme/tests/e2e/two-way-anova.e2e-spec.ts
@@ -1,7 +1,5 @@
 import { Test, TestingModule } from '@nestjs/testing';
 import { AppModule } from '../../../../../main/app.module';
-import { ENGINE_SERVICE } from '../../../../engine.constants';
-import { IEngineService } from '../../../../engine.interfaces';
 import { ExperimentCreateInput } from '../../../../../experiments/models/input/experiment-create.input';
 import { RawResult } from '../../../../models/result/raw-result.model';
 import {
@@ -11,18 +9,19 @@ import {
   TIMEOUT_DURATION_SECONDS,
   waitForResult,
 } from '../../interfaces/test-utilities';
+import EngineService from '../../../../../engine/engine.service';
 
 jest.setTimeout(1000 * TIMEOUT_DURATION_SECONDS);
 
 describe('ExaremeService', () => {
-  let exaremeService: IEngineService;
+  let exaremeService: EngineService;
 
   beforeEach(async () => {
     const moduleRef: TestingModule = await Test.createTestingModule({
       imports: [AppModule],
     }).compile();
 
-    exaremeService = await moduleRef.resolve<IEngineService>(ENGINE_SERVICE);
+    exaremeService = await moduleRef.resolve<EngineService>(EngineService);
   });
   const modelSlug = `anova-2way-${generateNumber()}`;
   const algorithmId = 'ANOVA';
diff --git a/api/src/engine/connectors/local/main.connector.ts b/api/src/engine/connectors/local/local.connector.ts
similarity index 87%
rename from api/src/engine/connectors/local/main.connector.ts
rename to api/src/engine/connectors/local/local.connector.ts
index ef95f6049d396ec95d6ac4d81269ccad7d0b16b3..e19fb48cf5f7653deac3ac1924bf99183b21df07 100644
--- a/api/src/engine/connectors/local/main.connector.ts
+++ b/api/src/engine/connectors/local/local.connector.ts
@@ -1,10 +1,10 @@
-import { IEngineService } from 'src/engine/engine.interfaces';
+import Connector from 'src/engine/interfaces/connector.interface';
 import { Domain } from 'src/engine/models/domain.model';
 import { Algorithm } from 'src/engine/models/experiment/algorithm.model';
 import { ResultUnion } from 'src/engine/models/result/common/result-union.model';
 import { User } from 'src/users/models/user.model';
 
-export default class LocalService implements IEngineService {
+export default class LocalConnector implements Connector {
   async login(): Promise<User> {
     return {
       id: '1',
@@ -20,7 +20,7 @@ export default class LocalService implements IEngineService {
     throw new Error('Method not implemented.');
   }
 
-  getDomains(): Domain[] {
+  async getDomains(): Promise<Domain[]> {
     return [
       {
         id: 'Dummy',
diff --git a/api/src/engine/engine.constants.ts b/api/src/engine/engine.constants.ts
index 641ceed91bb4a29953fc558479f5b667fd112808..351c3aa3a3258603cf674a090d61da9bd3ab0ba1 100644
--- a/api/src/engine/engine.constants.ts
+++ b/api/src/engine/engine.constants.ts
@@ -1,4 +1,3 @@
 export const ENGINE_MODULE_OPTIONS = 'EngineModuleOption';
-export const ENGINE_SERVICE = 'EngineService';
 export const ENGINE_SKIP_TOS = 'TOS_SKIP';
 export const ENGINE_ONTOLOGY_URL = 'ONTOLOGY_URL';
diff --git a/api/src/engine/engine.controller.ts b/api/src/engine/engine.controller.ts
index fc656aabb1d5d1c9f21e4a14af9cba01a5ee7440..d47b63b20b2851715d8b58e63c90851470547fca 100644
--- a/api/src/engine/engine.controller.ts
+++ b/api/src/engine/engine.controller.ts
@@ -1,19 +1,17 @@
-import { Controller, Get, Inject, Req, UseInterceptors } from '@nestjs/common';
+import { Controller, Get, Req, UseInterceptors } from '@nestjs/common';
 import { Request } from 'express';
 import { Observable } from 'rxjs';
-import { ENGINE_SERVICE } from './engine.constants';
-import { IEngineService } from './engine.interfaces';
+import EngineService from './engine.service';
 import { ErrorsInterceptor } from './interceptors/errors.interceptor';
 
 @UseInterceptors(ErrorsInterceptor)
 @Controller()
 export class EngineController {
-  constructor(
-    @Inject(ENGINE_SERVICE) private readonly engineService: IEngineService,
-  ) {}
+  constructor(private readonly engineService: EngineService) {}
 
   @Get('galaxy')
   galaxy(@Req() request: Request): Observable<string> | string {
-    return this.engineService.getPassthrough?.('galaxy', request);
+    if (this.engineService.has('getPassthrough'))
+      return this.engineService.getPassthrough('galaxy', request);
   }
 }
diff --git a/api/src/engine/engine.module.ts b/api/src/engine/engine.module.ts
index d636740a3a39e2e5901c96d60690ef365ac00b3c..6e359c9d8ba268c199bb606cdce7d7398d03758b 100644
--- a/api/src/engine/engine.module.ts
+++ b/api/src/engine/engine.module.ts
@@ -1,73 +1,44 @@
-import { HttpModule, HttpService } from '@nestjs/axios';
-import {
-  DynamicModule,
-  Global,
-  InternalServerErrorException,
-  Logger,
-  Module,
-} from '@nestjs/common';
-import { ENGINE_MODULE_OPTIONS, ENGINE_SERVICE } from './engine.constants';
+import { HttpModule } from '@nestjs/axios';
+import { CacheModule, DynamicModule, Module } from '@nestjs/common';
+import { ConfigModule, ConfigService } from '@nestjs/config';
+import { ENGINE_MODULE_OPTIONS } from './engine.constants';
 import { EngineController } from './engine.controller';
-import { IEngineOptions, IEngineService } from './engine.interfaces';
 import { EngineResolver } from './engine.resolver';
+import EngineService from './engine.service';
+import EngineOptions from './interfaces/engine-options.interface';
 
-@Global()
 @Module({})
 export class EngineModule {
-  private static readonly logger = new Logger(EngineModule.name);
-
-  static forRoot(options?: Partial<IEngineOptions>): DynamicModule {
+  static forRoot(options?: Partial<EngineOptions>): DynamicModule {
     const optionsProvider = {
       provide: ENGINE_MODULE_OPTIONS,
       useValue: {
-        type: process.env.ENGINE_TYPE,
-        baseurl: process.env.ENGINE_BASE_URL,
-        ...(options ?? {}),
-      },
-    };
-
-    const engineProvider = {
-      provide: ENGINE_SERVICE,
-      useFactory: async (httpService: HttpService) => {
-        return this.createEngineConnection(
-          optionsProvider.useValue,
-          httpService,
-        );
+        ...options,
+        type: options?.type.toLowerCase(),
       },
-      inject: [HttpService],
     };
 
     return {
+      global: true,
       module: EngineModule,
-      imports: [HttpModule],
-      providers: [optionsProvider, engineProvider, EngineResolver],
+      imports: [
+        HttpModule,
+        CacheModule.registerAsync({
+          imports: [ConfigModule],
+          useFactory: async (configService: ConfigService) => {
+            const config = configService.get('cache');
+            return {
+              isGlobal: true,
+              ttl: config.ttl,
+              max: config.max,
+            };
+          },
+          inject: [ConfigService],
+        }),
+      ],
+      providers: [optionsProvider, EngineService, EngineResolver],
       controllers: [EngineController],
-      exports: [optionsProvider, engineProvider],
+      exports: [optionsProvider, EngineService],
     };
   }
-
-  private static async createEngineConnection(
-    opt: IEngineOptions,
-    httpService: HttpService,
-  ): Promise<IEngineService> {
-    const service = await import(`./connectors/${opt.type}/main.connector`);
-    const instance: IEngineService = new service.default(opt, httpService);
-
-    if (instance.createExperiment && instance.runExperiment)
-      throw new InternalServerErrorException(
-        `Connector ${opt.type} should declare either createExperiment or runExperiment not both`,
-      );
-
-    if (
-      instance.createExperiment &&
-      (!instance.getExperiment ||
-        !instance.listExperiments ||
-        !instance.removeExperiment ||
-        !instance.editExperiment)
-    )
-      throw new InternalServerErrorException(
-        `Connector ${opt.type} has 'createExperiment' implemented it implies that getExperiment, listExperiments, removeExperiment and editExperiment methods must also be implemented.`,
-      );
-    return instance;
-  }
 }
diff --git a/api/src/engine/engine.resolver.ts b/api/src/engine/engine.resolver.ts
index 84ff2afbb7f04f97af6072d29fe25fd7d380079c..f6ecef04897d77c9bef9488eabc74bfc484e83e1 100644
--- a/api/src/engine/engine.resolver.ts
+++ b/api/src/engine/engine.resolver.ts
@@ -11,11 +11,11 @@ import { GQLRequest } from '../common/decorators/gql-request.decoractor';
 import {
   ENGINE_MODULE_OPTIONS,
   ENGINE_ONTOLOGY_URL,
-  ENGINE_SERVICE,
   ENGINE_SKIP_TOS,
 } from './engine.constants';
-import { IEngineOptions, IEngineService } from './engine.interfaces';
+import EngineService from './engine.service';
 import { ErrorsInterceptor } from './interceptors/errors.interceptor';
+import EngineOptions from './interfaces/engine-options.interface';
 import { Configuration } from './models/configuration.model';
 import { Domain } from './models/domain.model';
 import { Algorithm } from './models/experiment/algorithm.model';
@@ -27,16 +27,16 @@ import { FormulaOperation } from './models/formula/formula-operation.model';
 @Resolver()
 export class EngineResolver {
   constructor(
-    @Inject(ENGINE_SERVICE) private readonly engineService: IEngineService,
+    private readonly engineService: EngineService,
     @Inject(ENGINE_MODULE_OPTIONS)
-    private readonly engineOptions: IEngineOptions,
+    private readonly engineOptions: EngineOptions,
     private readonly configSerivce: ConfigService,
   ) {}
 
   @Query(() => Configuration)
   @Public()
   configuration(): Configuration {
-    const config = this.engineService.getConfiguration?.();
+    const config = this.engineService.getConfiguration();
     const matomo = this.configSerivce.get('matomo');
 
     const data = {
@@ -78,7 +78,7 @@ export class EngineResolver {
 
   @Query(() => [FormulaOperation])
   async formula() {
-    if (this.engineService.getFormulaConfiguration)
+    if (this.engineService.has('getFormulaConfiguration'))
       return this.engineService.getFormulaConfiguration();
 
     return [];
@@ -86,7 +86,7 @@ export class EngineResolver {
 
   @Query(() => FilterConfiguration)
   async filter() {
-    if (this.engineService.getFilterConfiguration)
+    if (this.engineService.has('getFilterConfiguration'))
       return this.engineService.getFilterConfiguration();
 
     return [];
diff --git a/api/src/engine/engine.service.ts b/api/src/engine/engine.service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..bf6d88275051671bd2f246927f5555ea5c0d728d
--- /dev/null
+++ b/api/src/engine/engine.service.ts
@@ -0,0 +1,213 @@
+import { HttpService } from '@nestjs/axios';
+import {
+  CACHE_MANAGER,
+  Inject,
+  Injectable,
+  InternalServerErrorException,
+  NotImplementedException,
+} from '@nestjs/common';
+import { ConfigType } from '@nestjs/config';
+import { Cache } from 'cache-manager';
+import { Request } from 'express';
+import { Observable } from 'rxjs';
+import { ExperimentResult } from '../common/interfaces/utilities.interface';
+import cacheConfig from '../config/cache.config';
+import { ExperimentCreateInput } from '../experiments/models/input/experiment-create.input';
+import { ExperimentEditInput } from '../experiments/models/input/experiment-edit.input';
+import { UpdateUserInput } from '../users/inputs/update-user.input';
+import { User } from '../users/models/user.model';
+import { ENGINE_MODULE_OPTIONS } from './engine.constants';
+import ConnectorConfiguration from './interfaces/connector-configuration.interface';
+import Connector from './interfaces/connector.interface';
+import EngineOptions from './interfaces/engine-options.interface';
+import { Domain } from './models/domain.model';
+import { Algorithm } from './models/experiment/algorithm.model';
+import {
+  Experiment,
+  PartialExperiment,
+} from './models/experiment/experiment.model';
+import { ListExperiments } from './models/experiment/list-experiments.model';
+import { FilterConfiguration } from './models/filter/filter-configuration';
+import { FormulaOperation } from './models/formula/formula-operation.model';
+
+/**
+ * Engine service.
+ * This class is used as a Proxy to the real Connector.
+ */
+@Injectable()
+export default class EngineService implements Connector {
+  private connector: Connector;
+
+  constructor(
+    @Inject(ENGINE_MODULE_OPTIONS) private readonly options: EngineOptions,
+    private readonly httpService: HttpService,
+    @Inject(CACHE_MANAGER) private cacheManager: Cache,
+    @Inject(cacheConfig.KEY) private cacheConf: ConfigType<typeof cacheConfig>,
+  ) {
+    import(`./connectors/${options.type}/${options.type}.connector`).then(
+      (conn) => {
+        const instance = new conn.default(options, httpService);
+
+        if (instance.createExperiment && instance.runExperiment)
+          throw new InternalServerErrorException(
+            `Connector ${options.type} should declare either createExperiment or runExperiment not both`,
+          );
+
+        if (
+          instance.createExperiment &&
+          (!instance.getExperiment ||
+            !instance.listExperiments ||
+            !instance.removeExperiment ||
+            !instance.editExperiment)
+        )
+          throw new InternalServerErrorException(
+            `Connector ${options.type} has 'createExperiment' implemented it implies that getExperiment, listExperiments, removeExperiment and editExperiment methods must also be implemented.`,
+          );
+
+        this.connector = instance;
+      },
+    );
+  }
+
+  getConfiguration(): ConnectorConfiguration {
+    return this.connector.getConfiguration?.() ?? {};
+  }
+
+  /**
+   * "If the cache is enabled, try to get the value from the cache, otherwise call the function and cache
+   * the result."
+   *
+   * The function takes two arguments:
+   *
+   * * `key`: The key to use for the cache.
+   * * `fn`: The function to call if the value is not in the cache
+   * @param {string} key - The key to use for the cache.
+   * @param fn - () => Promise<T>
+   * @returns The result of the function call.
+   */
+  private async getFromCacheOrCall<T>(
+    key: string,
+    fn: () => Promise<T>,
+  ): Promise<T | undefined> {
+    if (!key || !this.cacheConf.enabled) return fn();
+
+    const cached = await this.cacheManager.get<T>(key);
+    if (cached) return cached;
+
+    const result = await fn();
+
+    this.cacheManager.set(key, result);
+
+    return result;
+  }
+
+  async getDomains(ids: string[], req: Request): Promise<Domain[]> {
+    const user = req?.user as User;
+    const key = user.id ? `domains-${ids.join('-')}-${user.id}` : undefined;
+
+    return this.getFromCacheOrCall<Domain[]>(key, () =>
+      this.connector.getDomains(ids, req),
+    );
+  }
+
+  async getAlgorithms(req: Request): Promise<Algorithm[]> {
+    const key = 'algorithms';
+
+    return this.getFromCacheOrCall<Algorithm[]>(key, () =>
+      this.connector.getAlgorithms(req),
+    );
+  }
+
+  async createExperiment(
+    data: ExperimentCreateInput,
+    isTransient: boolean,
+    req?: Request,
+  ): Promise<Experiment> {
+    if (!this.connector.createExperiment) throw new NotImplementedException();
+    return this.connector.createExperiment(data, isTransient, req);
+  }
+
+  async runExperiment(
+    data: ExperimentCreateInput,
+    req?: Request,
+  ): Promise<ExperimentResult[]> {
+    if (!this.connector.runExperiment) throw new NotImplementedException();
+    return this.connector.runExperiment(data, req);
+  }
+
+  async listExperiments?(
+    page: number,
+    name: string,
+    req?: Request,
+  ): Promise<ListExperiments> {
+    if (!this.connector.listExperiments) throw new NotImplementedException();
+    return this.connector.listExperiments(page, name, req);
+  }
+
+  async getExperiment?(id: string, req?: Request): Promise<Experiment> {
+    if (!this.connector.getExperiment) throw new NotImplementedException();
+    return this.connector.getExperiment(id, req);
+  }
+
+  async removeExperiment?(
+    id: string,
+    req?: Request,
+  ): Promise<PartialExperiment> {
+    if (!this.connector.removeExperiment) throw new NotImplementedException();
+    return this.connector.removeExperiment(id, req);
+  }
+
+  async editExperiment?(
+    id: string,
+    data: ExperimentEditInput,
+    req?: Request,
+  ): Promise<Experiment> {
+    if (!this.connector.editExperiment) throw new NotImplementedException();
+    return this.connector.editExperiment(id, data, req);
+  }
+
+  async getActiveUser?(req?: Request): Promise<User> {
+    if (!this.connector.getActiveUser) throw new NotImplementedException();
+    return this.connector.getActiveUser(req);
+  }
+
+  async updateUser?(
+    req?: Request,
+    userId?: string,
+    data?: UpdateUserInput,
+  ): Promise<User> {
+    if (!this.connector.updateUser) throw new NotImplementedException();
+    return this.connector.updateUser(req, userId, data);
+  }
+
+  async getFormulaConfiguration?(req?: Request): Promise<FormulaOperation[]> {
+    if (!this.connector.getFormulaConfiguration)
+      throw new NotImplementedException();
+    return this.connector.getFormulaConfiguration(req);
+  }
+
+  async getFilterConfiguration?(req?: Request): Promise<FilterConfiguration[]> {
+    if (!this.connector.getFilterConfiguration)
+      throw new NotImplementedException();
+    return this.connector.getFilterConfiguration(req);
+  }
+
+  async logout?(req?: Request): Promise<void> {
+    if (!this.connector.logout) throw new NotImplementedException();
+    return this.connector.logout(req);
+  }
+
+  async login?(username: string, password: string): Promise<User> {
+    if (!this.connector.login) throw new NotImplementedException();
+    return this.connector.login(username, password);
+  }
+
+  getPassthrough?(suffix: string, req?: Request): string | Observable<string> {
+    if (!this.connector.getPassthrough) throw new NotImplementedException();
+    return this.connector.getPassthrough(suffix, req);
+  }
+
+  has(name: keyof Connector): boolean {
+    return this.connector && typeof this.connector[name] !== undefined;
+  }
+}
diff --git a/api/src/engine/interceptors/errors.interceptor.ts b/api/src/engine/interceptors/errors.interceptor.ts
index 17bd2202b5ee03a82ba2c15bb2563da16f57a4ba..fa68a283ca34b0dee868c9c09e143d3c01a0109d 100644
--- a/api/src/engine/interceptors/errors.interceptor.ts
+++ b/api/src/engine/interceptors/errors.interceptor.ts
@@ -9,14 +9,14 @@ import {
 import { GqlExecutionContext } from '@nestjs/graphql';
 import { catchError, Observable } from 'rxjs';
 import { ENGINE_MODULE_OPTIONS } from '../engine.constants';
-import { IEngineOptions } from '../engine.interfaces';
+import EngineOptions from '../interfaces/engine-options.interface';
 
 @Injectable()
 export class ErrorsInterceptor implements NestInterceptor {
   private readonly logger: Logger;
 
   constructor(
-    @Inject(ENGINE_MODULE_OPTIONS) private readonly options: IEngineOptions,
+    @Inject(ENGINE_MODULE_OPTIONS) private readonly options: EngineOptions,
   ) {
     // Logger name is the engine name
     // HttpService will be used mostly by the engine (but it's not always true)
diff --git a/api/src/engine/interfaces/connector-configuration.interface.ts b/api/src/engine/interfaces/connector-configuration.interface.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d327ded434b169bd7c03ceda845198e0bd033cf6
--- /dev/null
+++ b/api/src/engine/interfaces/connector-configuration.interface.ts
@@ -0,0 +1,8 @@
+import { Configuration } from '../models/configuration.model';
+
+type ConnectorConfiguration = Pick<
+  Configuration,
+  'contactLink' | 'hasGalaxy' | 'hasGrouping'
+>;
+
+export default ConnectorConfiguration;
diff --git a/api/src/engine/engine.interfaces.ts b/api/src/engine/interfaces/connector.interface.ts
similarity index 79%
rename from api/src/engine/engine.interfaces.ts
rename to api/src/engine/interfaces/connector.interface.ts
index 5edaca4541165f02ea1d74ae38aa1407c8a2f49a..dc92dc71333914ca62d12a2b38da560848eb99a2 100644
--- a/api/src/engine/engine.interfaces.ts
+++ b/api/src/engine/interfaces/connector.interface.ts
@@ -1,43 +1,33 @@
 import { Request } from 'express';
 import { Observable } from 'rxjs';
+import { ExperimentResult } from 'src/common/interfaces/utilities.interface';
 import { UpdateUserInput } from 'src/users/inputs/update-user.input';
-import { User } from '../users/models/user.model';
-import { Configuration } from './models/configuration.model';
-import { Domain } from './models/domain.model';
-import { Algorithm } from './models/experiment/algorithm.model';
+import { ExperimentCreateInput } from '../../experiments/models/input/experiment-create.input';
+import { ExperimentEditInput } from '../../experiments/models/input/experiment-edit.input';
+import { User } from '../../users/models/user.model';
+import { Domain } from '../models/domain.model';
+import { Algorithm } from '../models/experiment/algorithm.model';
 import {
   Experiment,
   PartialExperiment,
-} from './models/experiment/experiment.model';
-import { ExperimentCreateInput } from '../experiments/models/input/experiment-create.input';
-import { ExperimentEditInput } from '../experiments/models/input/experiment-edit.input';
-import { ListExperiments } from './models/experiment/list-experiments.model';
-import { ResultUnion } from './models/result/common/result-union.model';
-import { FormulaOperation } from './models/formula/formula-operation.model';
-import { FilterConfiguration } from './models/filter/filter-configuration';
-
-export interface IEngineOptions {
-  type: string;
-  baseurl: string;
-}
-
-export type IConfiguration = Pick<
-  Configuration,
-  'contactLink' | 'hasGalaxy' | 'hasGrouping'
->;
+} from '../models/experiment/experiment.model';
+import { ListExperiments } from '../models/experiment/list-experiments.model';
+import { FilterConfiguration } from '../models/filter/filter-configuration';
+import { FormulaOperation } from '../models/formula/formula-operation.model';
+import ConnectorConfiguration from './connector-configuration.interface';
 
-export interface IEngineService {
+export default interface Connector {
   /**
    * Allow specific configuration for the engine
    */
-  getConfiguration?(): IConfiguration;
+  getConfiguration?(): ConnectorConfiguration;
 
   /**
    * Get the list of domains along with a list of variables
    * @param ids - Ids to filter the domain needed
    * @param req - Request - this is the request object from the HTTP request.
    */
-  getDomains(ids: string[], req?: Request): Domain[] | Promise<Domain[]>;
+  getDomains(ids: string[], req?: Request): Promise<Domain[]>;
 
   /**
    * Create and return a full detailed experiment
@@ -62,7 +52,7 @@ export interface IEngineService {
   runExperiment?(
     data: ExperimentCreateInput,
     req?: Request,
-  ): Promise<Array<typeof ResultUnion>>;
+  ): Promise<ExperimentResult[]>;
 
   /**
    * Get a list of experiment (limited to 10 per page)
diff --git a/api/src/engine/interfaces/engine-options.interface.ts b/api/src/engine/interfaces/engine-options.interface.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c05d4a0c3fe4bab5f9e9777cfba48ab928675edf
--- /dev/null
+++ b/api/src/engine/interfaces/engine-options.interface.ts
@@ -0,0 +1,4 @@
+export default interface EngineOptions {
+  type: string;
+  baseurl: string;
+}
diff --git a/api/src/engine/test/core.e2e-spec.ts b/api/src/engine/test/core.e2e-spec.ts
index bb35467dd1911ea2f88c8af9f0268218ddfdb8a5..f76bd806049be71cb7d78e6f53ca915e0b0bac52 100644
--- a/api/src/engine/test/core.e2e-spec.ts
+++ b/api/src/engine/test/core.e2e-spec.ts
@@ -1,14 +1,13 @@
 import { Test, TestingModule } from '@nestjs/testing';
-import { Domain } from 'src/engine/models/domain.model';
+import { Domain } from '../models/domain.model';
 import { AppModule } from '../../main/app.module';
 import { TIMEOUT_DURATION_SECONDS } from '../connectors/exareme/interfaces/test-utilities';
-import { ENGINE_SERVICE } from '../engine.constants';
-import { IEngineService } from '../engine.interfaces';
+import EngineService from '../engine.service';
 
 jest.setTimeout(1000 * TIMEOUT_DURATION_SECONDS);
 
 describe('Engine service', () => {
-  let engineService: IEngineService;
+  let engineService: EngineService;
   let domains: Domain[];
 
   beforeAll(async () => {
@@ -16,7 +15,7 @@ describe('Engine service', () => {
       imports: [AppModule],
     }).compile();
 
-    engineService = await moduleRef.resolve<IEngineService>(ENGINE_SERVICE);
+    engineService = await moduleRef.resolve<EngineService>(EngineService);
 
     domains = await engineService.getDomains([]);
   });
diff --git a/api/src/experiments/experiments.resolver.spec.ts b/api/src/experiments/experiments.resolver.spec.ts
index 0ff1cb091669713156af236d4b504706a29074a1..68907635d623d9a6b49026d5c8387490670143ba 100644
--- a/api/src/experiments/experiments.resolver.spec.ts
+++ b/api/src/experiments/experiments.resolver.spec.ts
@@ -1,14 +1,13 @@
 import { Test, TestingModule } from '@nestjs/testing';
+import EngineService from '../engine/engine.service';
 import { ExperimentStatus } from '../engine/models/experiment/experiment.model';
 import { User } from '../users/models/user.model';
-import { ENGINE_SERVICE } from '../engine/engine.constants';
-import { IEngineService } from '../engine/engine.interfaces';
 import { ExperimentsResolver } from './experiments.resolver';
 import { ExperimentsService } from './experiments.service';
 import { ExperimentCreateInput } from './models/input/experiment-create.input';
 import { ExperimentEditInput } from './models/input/experiment-edit.input';
 
-type MockEngineService = Partial<Record<keyof IEngineService, jest.Mock>>;
+type MockEngineService = Partial<Record<keyof EngineService, jest.Mock>>;
 type MockExperimentService = Partial<
   Record<keyof ExperimentsService, jest.Mock>
 >;
@@ -22,6 +21,7 @@ const createEngineService = (): MockEngineService => ({
   editExperiment: jest.fn(),
   listExperiments: jest.fn(),
   removeExperiment: jest.fn(),
+  has: jest.fn().mockReturnValue(true),
 });
 
 const createExperimentsService = (): MockExperimentService => ({
@@ -44,13 +44,15 @@ describe('ExperimentsResolver', () => {
         ExperimentsResolver,
         { provide: ExperimentsService, useValue: createExperimentsService() },
         {
-          provide: ENGINE_SERVICE,
+          provide: EngineService,
           useValue: createEngineService(),
         },
       ],
     }).compile();
 
-    engineService = module.get<MockEngineService>(ENGINE_SERVICE);
+    engineService = module.get<EngineService>(
+      EngineService,
+    ) as unknown as MockEngineService;
     experimentsService = module.get<ExperimentsService>(
       ExperimentsService,
     ) as unknown as MockExperimentService;
@@ -77,7 +79,7 @@ describe('ExperimentsResolver', () => {
     describe('when engine method does not exist', () => {
       it('should call service method', async () => {
         const request: any = jest.fn();
-        engineService.listExperiments = undefined;
+        engineService.has.mockReturnValue(false);
         experimentsService.findAll.mockReturnValue([[], 9]);
         await resolver.experimentList(0, '', request);
 
@@ -110,7 +112,7 @@ describe('ExperimentsResolver', () => {
           id: 'dummyUser',
           username: 'test',
         };
-        engineService.getExperiment = undefined;
+        engineService.has.mockReturnValue(false);
         await resolver.experiment('test', request, user);
 
         expect(experimentsService.findOne.mock.calls.length).toBeGreaterThan(0);
@@ -146,7 +148,7 @@ describe('ExperimentsResolver', () => {
           id: 'dummyUser',
           username: 'test',
         };
-        engineService.createExperiment = undefined;
+        engineService.has.mockReturnValue(false);
         engineService.runExperiment.mockResolvedValue([]);
         experimentsService.create.mockReturnValue({ id: 'test' });
         await resolver.createExperiment(request, user, data, false);
@@ -162,7 +164,7 @@ describe('ExperimentsResolver', () => {
           id: 'dummyUser',
           username: 'test',
         };
-        engineService.createExperiment = undefined;
+        engineService.has.mockReturnValue(false);
         engineService.runExperiment.mockResolvedValue([]);
         experimentsService.create.mockReturnValue({ id: 'test' });
         const result = await resolver.createExperiment(
@@ -206,7 +208,7 @@ describe('ExperimentsResolver', () => {
           id: 'dummyUser',
           username: 'test',
         };
-        engineService.editExperiment = undefined;
+        engineService.has.mockReturnValue(false);
         await resolver.editExperiment(request, 'test', data, user);
 
         expect(experimentsService.update.mock.calls.length).toBeGreaterThan(0);
@@ -238,7 +240,7 @@ describe('ExperimentsResolver', () => {
           id: 'dummyUser',
           username: 'test',
         };
-        engineService.removeExperiment = undefined;
+        engineService.has.mockReturnValue(false);
         await resolver.removeExperiment('test', request, user);
 
         expect(experimentsService.remove.mock.calls.length).toBeGreaterThan(0);
diff --git a/api/src/experiments/experiments.resolver.ts b/api/src/experiments/experiments.resolver.ts
index 29b15fbe6aad521b235f5e7076caa6d2e9b17303..3739933dfa2c2b736f4851375afc0f272e456b3c 100644
--- a/api/src/experiments/experiments.resolver.ts
+++ b/api/src/experiments/experiments.resolver.ts
@@ -1,11 +1,10 @@
-import { Inject, Logger, UseGuards } from '@nestjs/common';
+import { Logger, UseGuards } from '@nestjs/common';
 import { Args, Mutation, Query, Resolver } from '@nestjs/graphql';
 import { Request } from 'express';
+import EngineService from '../engine/engine.service';
 import { GlobalAuthGuard } from '../auth/guards/global-auth.guard';
 import { GQLRequest } from '../common/decorators/gql-request.decoractor';
 import { CurrentUser } from '../common/decorators/user.decorator';
-import { ENGINE_SERVICE } from '../engine/engine.constants';
-import { IEngineService } from '../engine/engine.interfaces';
 import {
   Experiment,
   ExperimentStatus,
@@ -25,7 +24,7 @@ export class ExperimentsResolver {
   private readonly logger = new Logger(ExperimentsResolver.name);
 
   constructor(
-    @Inject(ENGINE_SERVICE) private readonly engineService: IEngineService,
+    private readonly engineService: EngineService,
     private readonly experimentService: ExperimentsService,
   ) {}
 
@@ -35,7 +34,7 @@ export class ExperimentsResolver {
     @Args('name', { nullable: true, defaultValue: '' }) name: string,
     @GQLRequest() req: Request,
   ): Promise<ListExperiments> {
-    if (this.engineService.listExperiments) {
+    if (this.engineService.has('listExperiments')) {
       return this.engineService.listExperiments(page, name, req);
     }
 
@@ -60,7 +59,7 @@ export class ExperimentsResolver {
     @GQLRequest() req: Request,
     @CurrentUser() user: User,
   ) {
-    if (this.engineService.getExperiment)
+    if (this.engineService.has('getExperiment'))
       return this.engineService.getExperiment(id, req);
 
     return this.experimentService.findOne(id, user);
@@ -74,7 +73,7 @@ export class ExperimentsResolver {
     @Args('isTransient', { nullable: true, defaultValue: false })
     isTransient: boolean,
   ) {
-    if (this.engineService.createExperiment) {
+    if (this.engineService.has('createExperiment')) {
       return this.engineService.createExperiment(data, isTransient, req);
     }
 
@@ -116,7 +115,7 @@ export class ExperimentsResolver {
     @Args('data') experiment: ExperimentEditInput,
     @CurrentUser() user: User,
   ) {
-    if (this.engineService.editExperiment)
+    if (this.engineService.has('editExperiment'))
       return this.engineService.editExperiment(id, experiment, req);
 
     return this.experimentService.update(id, experiment, user);
@@ -128,7 +127,7 @@ export class ExperimentsResolver {
     @GQLRequest() req: Request,
     @CurrentUser() user: User,
   ): Promise<PartialExperiment> {
-    if (this.engineService.removeExperiment)
+    if (this.engineService.has('removeExperiment'))
       return this.engineService.removeExperiment(id, req);
 
     return this.experimentService.remove(id, user);
diff --git a/api/src/files/files.service.ts b/api/src/files/files.service.ts
index 685ab86da64b8f1ecf1ead4f11a4e8fe5701ff5d..88638a18e416889b83cb251dbd7c2ddeed31b16c 100644
--- a/api/src/files/files.service.ts
+++ b/api/src/files/files.service.ts
@@ -1,14 +1,14 @@
 import { Inject, Injectable } from '@nestjs/common';
 import * as fs from 'fs';
 import { join } from 'path/posix';
+import EngineOptions from '../engine/interfaces/engine-options.interface';
 import { ENGINE_MODULE_OPTIONS } from '../engine/engine.constants';
-import { IEngineOptions } from '../engine/engine.interfaces';
 
 @Injectable()
 export class FilesService {
   constructor(
     @Inject(ENGINE_MODULE_OPTIONS)
-    private readonly engineOptions: IEngineOptions,
+    private readonly engineOptions: EngineOptions,
   ) {}
 
   /**
diff --git a/api/src/main/app.module.ts b/api/src/main/app.module.ts
index dd03343d458c661bc3aacd67615c17bcda10beab..5c113466f7233d9ff30419b48c9c495e60ae9f66 100644
--- a/api/src/main/app.module.ts
+++ b/api/src/main/app.module.ts
@@ -6,6 +6,7 @@ import { TypeOrmModule } from '@nestjs/typeorm';
 import { GraphQLError } from 'graphql';
 import { join } from 'path';
 import { AuthModule } from 'src/auth/auth.module';
+import cacheConfig from 'src/config/cache.config';
 import dbConfig from 'src/config/db.config';
 import matomoConfig from 'src/config/matomo.config';
 import { EngineModule } from 'src/engine/engine.module';
@@ -20,7 +21,7 @@ import { AppService } from './app.service';
     ConfigModule.forRoot({
       isGlobal: true,
       envFilePath: ['.env', '.env.defaults'],
-      load: [dbConfig, matomoConfig],
+      load: [dbConfig, matomoConfig, cacheConfig],
     }),
     GraphQLModule.forRoot<ApolloDriverConfig>({
       driver: ApolloDriver,
diff --git a/api/src/users/users.resolver.spec.ts b/api/src/users/users.resolver.spec.ts
index ad93fc2b885aaf71979c02a0f9a70cb6d6635d17..6f8fe9d584c1ea856cbc22c2090d899161c0a65a 100644
--- a/api/src/users/users.resolver.spec.ts
+++ b/api/src/users/users.resolver.spec.ts
@@ -1,18 +1,18 @@
 import { getMockReq } from '@jest-mock/express';
 import { InternalServerErrorException } from '@nestjs/common';
 import { Test, TestingModule } from '@nestjs/testing';
-import { ENGINE_SERVICE } from '../engine/engine.constants';
-import { IEngineService } from '../engine/engine.interfaces';
+import EngineService from '../engine/engine.service';
 import { UpdateUserInput } from './inputs/update-user.input';
 import { User } from './models/user.model';
 import { UsersResolver } from './users.resolver';
 import { UsersService } from './users.service';
 
-type MockEngineService = Partial<Record<keyof IEngineService, jest.Mock>>;
+type MockEngineService = Partial<Record<keyof EngineService, jest.Mock>>;
 type MockUsersService = Partial<Record<keyof UsersService, jest.Mock>>;
 
 const createEngineService = (): MockEngineService => ({
   updateUser: jest.fn(),
+  has: jest.fn().mockReturnValue(true),
 });
 
 const createUsersService = (): MockUsersService => ({
@@ -37,14 +37,16 @@ describe('UsersResolver', () => {
         UsersResolver,
         { provide: UsersService, useValue: createUsersService() },
         {
-          provide: ENGINE_SERVICE,
+          provide: EngineService,
           useValue: createEngineService(),
         },
       ],
     }).compile();
 
     resolver = module.get<UsersResolver>(UsersResolver);
-    engineService = module.get<MockEngineService>(ENGINE_SERVICE);
+    engineService = module.get<EngineService>(
+      EngineService,
+    ) as unknown as MockEngineService;
     usersService = module.get<UsersService>(
       UsersService,
     ) as unknown as MockUsersService;
@@ -95,7 +97,7 @@ describe('UsersResolver', () => {
         ...updateData,
       };
 
-      engineService.updateUser = undefined;
+      engineService.has.mockReturnValue(false);
       usersService.update.mockReturnValue(expectedUser);
       const result = await resolver.updateUser(req, updateData, user);
 
diff --git a/api/src/users/users.resolver.ts b/api/src/users/users.resolver.ts
index 5d54d88d854d5e34787dd893ee36987bf348f5ea..d13ae670e9499d07b768cd3706ff1173f3de4135 100644
--- a/api/src/users/users.resolver.ts
+++ b/api/src/users/users.resolver.ts
@@ -1,19 +1,17 @@
 import {
-  Inject,
   InternalServerErrorException,
   Logger,
   UseGuards,
 } from '@nestjs/common';
 import { Args, Mutation, Query, Resolver } from '@nestjs/graphql';
-import { ENGINE_SERVICE } from '../engine/engine.constants';
-import { IEngineService } from '../engine/engine.interfaces';
+import { Request } from 'express';
+import { GlobalAuthGuard } from '../auth/guards/global-auth.guard';
+import { GQLRequest } from '../common/decorators/gql-request.decoractor';
+import { CurrentUser } from '../common/decorators/user.decorator';
+import EngineService from '../engine/engine.service';
 import { UpdateUserInput } from './inputs/update-user.input';
 import { User } from './models/user.model';
 import { UsersService } from './users.service';
-import { GQLRequest } from '../common/decorators/gql-request.decoractor';
-import { Request } from 'express';
-import { CurrentUser } from '../common/decorators/user.decorator';
-import { GlobalAuthGuard } from '../auth/guards/global-auth.guard';
 
 @UseGuards(GlobalAuthGuard)
 @Resolver()
@@ -22,7 +20,7 @@ export class UsersResolver {
 
   constructor(
     private readonly usersService: UsersService,
-    @Inject(ENGINE_SERVICE) private readonly engineService: IEngineService,
+    private readonly engineService: EngineService,
   ) {}
 
   @Query(() => User, { name: 'user' })
@@ -56,7 +54,7 @@ export class UsersResolver {
 
     let updatedInfo: Partial<User>;
 
-    if (this.engineService.updateUser) {
+    if (this.engineService.has('updateUser')) {
       updatedInfo = await this.engineService.updateUser(
         request,
         user?.id,
diff --git a/api/tsconfig.json b/api/tsconfig.json
index adb614cab7d04d6f2391c7663b833b296ed334e1..0903174b9e77d1331521c7bc2db68acfd4217691 100644
--- a/api/tsconfig.json
+++ b/api/tsconfig.json
@@ -6,7 +6,7 @@
     "emitDecoratorMetadata": true,
     "experimentalDecorators": true,
     "allowSyntheticDefaultImports": true,
-    "target": "es2017",
+    "target": "es2021",
     "sourceMap": true,
     "outDir": "./dist",
     "baseUrl": "./",