diff --git a/config.js b/config.js
index c29eefe1350c3a8a0175fef466db2d780dec1f01..fedfc4800657f3a6c50c2fdc480369458740e474 100644
--- a/config.js
+++ b/config.js
@@ -1,5 +1,9 @@
 const config = {
-  port: 9000
+  port: 9000,
+  storage: {
+    type: "JSON",
+    path: "./assets/assets.json"
+  }
 }
 
 module.exports = config;
\ No newline at end of file
diff --git a/routes/assets.js b/routes/assets.js
index 0170d939a66f5fe69971d714c936f8bab3288905..e4381caf9dfc5a6ecd40ef606e8213478a04c7ca 100644
--- a/routes/assets.js
+++ b/routes/assets.js
@@ -1,6 +1,8 @@
 const express = require("express");
 const path = require("path");
-const assets = require("../src/assets");
+const BaseStorage = require('../src/baseStorage');
+
+const storage = new BaseStorage().getInstance();
 
 let router = express.Router();
 
@@ -8,7 +10,7 @@ router.route("/*")
   .get((req, res, next) => {
 
     let fullUrl = `${req.protocol}://${req.get("host")}${req.originalUrl}`;
-    assets.isPublic(fullUrl).then(result => {
+    storage.isPublic(fullUrl).then(result => {
       if (result) {
         next();
       } else {
diff --git a/src/assets.js b/src/assets.js
deleted file mode 100644
index 1e2da84cf4c129f46ade846bd469a5b2b4bbe6da..0000000000000000000000000000000000000000
--- a/src/assets.js
+++ /dev/null
@@ -1,120 +0,0 @@
-const fs = require("fs");
-const boxIntersect = require("box-intersect");
-const path = require('path');
-
-const getLayers = (layers, boundingbox) => {
-  if (boundingbox === undefined) {
-
-    return new Promise((resolve, reject) => {
-      fs.readFile("./assets/assets.json", (err, data) => {
-        if (err) {
-          reject();
-        }
-        let assets = JSON.parse(data);
-        let requestedLayers = layers.split(",");
-        assets = assets.filter(asset => requestedLayers.includes(asset.id));
-        assets = assets.filter(asset => asset.scope == "public");
-        resolve(assets);
-      });
-    });
-
-  } else {
-
-    return getIntersectingLayers(layers, boundingbox);
-
-  }
-
-}
-
-const getIntersectingLayers = (layers,bb) => {
-
-  return new Promise((resolve, reject) => {
-    fs.readFile("./assets/assets.json", (err, data) => {
-      if (err) {
-        reject();
-      }
-      let assets = JSON.parse(data);
-      let requestedBB = bb.split(",").map(token => parseFloat(token));
-      let requestedLayers = layers.split(",");
-
-      assets = assets.filter(asset => requestedLayers.includes(asset.id));
-      assets = assets.filter(asset => asset.scope == "public");
-
-      assets = assets.filter(asset => {
-
-        let overlaps = boxIntersect([
-          [...asset.boundingbox],
-          [...requestedBB]
-        ]);
-
-        if (overlaps.length > 0) {
-          return true;
-        }
-        return false;
-      });
-
-      resolve(assets);
-
-    });
-  });
-
-}
-
-const allLayersExist = (layers) => {
-
-  if (!layers) return Promise.reject();
-
-  return new Promise((resolve, reject) => {
-    fs.readFile("./assets/assets.json", (err, data) => {
-      if (err) {
-        reject();
-      }
-      let assets = JSON.parse(data);
-      layers = layers.split(",");
-      layers.forEach(layer => {
-        if (assets.findIndex(asset => asset.id == layer) == -1) {
-          reject();
-        }
-      });
-      resolve();
-    });
-  });
-
-}
-
-const getPublicLayers = () => {
-
-  return new Promise((resolve, reject) => {
-    fs.readFile("./assets/assets.json", (err, data) => {
-      let assets = JSON.parse(data);
-      assets = assets.filter(asset => asset.scope == "public");
-      resolve(assets);
-    });
-  });
-
-}
-
-const isPublic = (url) => {
-
-  return new Promise((resolve, reject) => {
-    fs.readFile("./assets/assets.json", (err, data) => {
-      let assets = JSON.parse(data);
-      assets = assets.filter(asset => {
-        let parentDir = path.dirname(asset.url);
-        return !path.relative(parentDir, url).startsWith("..");
-      });
-      if (assets.length == 0) {
-        resolve(false);
-        return;
-      }
-      if (!assets[0].scope == "public") {
-        resolve(false);
-        return;
-      }
-      resolve(true);
-    });
-  });
-
-}
-
-module.exports = { getLayers, allLayersExist, getPublicLayers, isPublic };
\ No newline at end of file
diff --git a/src/baseStorage.js b/src/baseStorage.js
new file mode 100644
index 0000000000000000000000000000000000000000..a31fb7fd3d0a6dce3fbf653ca5309d678b0160b4
--- /dev/null
+++ b/src/baseStorage.js
@@ -0,0 +1,43 @@
+const config = require("../config");
+const { createStorage } = require("./storageFactory");
+
+class BaseStorage {
+
+  constructor(storage) {
+    this.storage = storage;
+  }
+
+  getLayers(ids, boundingbox) {
+    return this.storage.getLayers(ids, boundingbox);
+  }
+
+  getPublicLayers() {
+    return this.storage.getPublicLayers();
+  }
+
+  isPublic(url) {
+    return this.storage.isPublic(url);
+  }
+
+  validateLayers(ids) {
+    return this.storage.validateLayers(ids);
+  }
+
+}
+
+class BaseStorageInstance {
+
+  constructor() {
+    if (!BaseStorageInstance.instance) {
+      const storage = createStorage(config.storage);
+      BaseStorageInstance.instance = new BaseStorage(storage)
+    }
+  }
+
+  getInstance() {
+    return BaseStorageInstance.instance;
+  }
+
+}
+
+module.exports = BaseStorageInstance;
\ No newline at end of file
diff --git a/src/getCapabilitiesHandler.js b/src/getCapabilitiesHandler.js
index 9ad510a838e5490cc87f57625d5d66546c64b595..94df3890940b157eb085e149b2694697f77315b9 100644
--- a/src/getCapabilitiesHandler.js
+++ b/src/getCapabilitiesHandler.js
@@ -1,9 +1,11 @@
-const assets = require("../src/assets");
 const pug = require("pug");
+const BaseStorage = require('./baseStorage');
+
+const storage = new BaseStorage().getInstance();
 
 const getCapabilitiesHandler = (req, res) => {
 
-  assets.getPublicLayers().then(layers => {
+  storage.getPublicLayers().then(layers => {
 
     const compiledFunction = pug.compileFile("./views/capabilities.pug");
     let capabilities = compiledFunction({ layers: layers });
diff --git a/src/getSceneHandler.js b/src/getSceneHandler.js
index 31aa4f369a6632fd407253880f8773f06758b253..fbd0c65ddd8b180468d028faab751e68aef09035 100644
--- a/src/getSceneHandler.js
+++ b/src/getSceneHandler.js
@@ -1,8 +1,10 @@
-const assets = require("../src/assets");
+const BaseStorage = require('./baseStorage');
+
+const storage = new BaseStorage().getInstance();
 
 const getSceneHandler = (req, res) => {
 
-  assets.getLayers(req.query.layers, req.query.boundingbox).then(layers => {
+  storage.getLayers(req.query.layers, req.query.boundingbox).then(layers => {
 
     layers = layers.map(layer => {
       delete layer.scope;
diff --git a/src/storage.js b/src/storage.js
new file mode 100644
index 0000000000000000000000000000000000000000..e34eaaa53d9aa7bcf3a841b2d705b5980e5e4ffb
--- /dev/null
+++ b/src/storage.js
@@ -0,0 +1,121 @@
+const fs = require("fs");
+const boxIntersect = require("box-intersect");
+const path = require('path');
+
+class JSONStorage {
+
+  constructor(path) {
+    this.path = path;
+  }
+
+  getLayers(ids, boundingbox) {
+    if (boundingbox === undefined) {
+
+      return new Promise((resolve, reject) => {
+        fs.readFile(this.path, (err, data) => {
+          if (err) {
+            reject();
+          }
+          let assets = JSON.parse(data);
+          let requestedLayers = ids.split(",");
+          assets = assets.filter(asset => requestedLayers.includes(asset.id));
+          assets = assets.filter(asset => asset.scope == "public");
+          resolve(assets);
+        });
+      });
+
+    } else {
+
+      return this.getIntersectingLayers(ids, boundingbox);
+
+    }
+  }
+
+  getPublicLayers() {
+    return new Promise((resolve, reject) => {
+      fs.readFile(this.path, (err, data) => {
+        let assets = JSON.parse(data);
+        assets = assets.filter(asset => asset.scope == "public");
+        resolve(assets);
+      });
+    });
+  }
+
+  isPublic(url) {
+    return new Promise((resolve, reject) => {
+      fs.readFile(this.path, (err, data) => {
+        let assets = JSON.parse(data);
+        assets = assets.filter(asset => {
+          let parentDir = path.dirname(asset.url);
+          return !path.relative(parentDir, url).startsWith("..");
+        });
+        if (assets.length == 0) {
+          resolve(false);
+          return;
+        }
+        if (!assets[0].scope == "public") {
+          resolve(false);
+          return;
+        }
+        resolve(true);
+      });
+    });
+  }
+
+  validateLayers(ids) {
+    if (!ids) return Promise.reject();
+
+    return new Promise((resolve, reject) => {
+      fs.readFile(this.path, (err, data) => {
+        if (err) {
+          reject();
+        }
+        let assets = JSON.parse(data);
+        let layers = ids.split(",");
+        layers.forEach(layer => {
+          if (assets.findIndex(asset => asset.id == layer) == -1) {
+            reject();
+          }
+        });
+        resolve();
+      });
+    });
+  }
+
+  getIntersectingLayers(ids, bb) {
+
+    return new Promise((resolve, reject) => {
+      fs.readFile(this.path, (err, data) => {
+        if (err) {
+          reject();
+        }
+        let assets = JSON.parse(data);
+        let requestedBB = bb.split(",").map(token => parseFloat(token));
+        let requestedLayers = ids.split(",");
+
+        assets = assets.filter(asset => requestedLayers.includes(asset.id));
+        assets = assets.filter(asset => asset.scope == "public");
+
+        assets = assets.filter(asset => {
+
+          let overlaps = boxIntersect([
+            [...asset.boundingbox],
+            [...requestedBB]
+          ]);
+
+          if (overlaps.length > 0) {
+            return true;
+          }
+          return false;
+        });
+
+        resolve(assets);
+
+      });
+    });
+
+  }
+
+}
+
+module.exports = JSONStorage;
\ No newline at end of file
diff --git a/src/storageFactory.js b/src/storageFactory.js
new file mode 100644
index 0000000000000000000000000000000000000000..8548f17bde6149ab6568cf21844b6ce84647b86a
--- /dev/null
+++ b/src/storageFactory.js
@@ -0,0 +1,17 @@
+const JSONStorage = require("./storage");
+
+const createStorage = (params) => {
+
+  switch (params.type) {
+
+    case "JSON": {
+
+      return new JSONStorage(params.path);
+
+    }
+
+  }
+
+}
+
+module.exports = {createStorage};
\ No newline at end of file
diff --git a/src/validationCheckFactory.js b/src/validationCheckFactory.js
index cc4a0e43021e40e5bcff8803a47546d4b33ebcf1..5e778b550d8e8250295a34068eb83f1f6b175481 100644
--- a/src/validationCheckFactory.js
+++ b/src/validationCheckFactory.js
@@ -1,6 +1,8 @@
 const { query } = require("express-validator");
 const { toLower, toUpper, boundingboxIsValid } = require("../src/customSanitizers");
-const assets = require("../src/assets");
+const BaseStorage = require('./baseStorage');
+
+const storage = new BaseStorage().getInstance();
 
 const commonChecks = () => {
   return [
@@ -37,7 +39,7 @@ const getChecksFor = (parameter) => {
           .matches(/^EPSG:\d{4,5}$/).withMessage("InvalidParameterValue"),
         query("layers")
           .exists().withMessage("MissingParameterValue")
-          .custom(value => assets.allLayersExist(value)).withMessage("UnknownLayer"),
+          .custom(value => storage.validateLayers(value)).withMessage("UnknownLayer"),
         query("boundingbox")
           .optional()
           .matches(/^((\-?\d+(\.\d+)?),){3}(\-?\d+(\.\d+)?)$/).withMessage("InvalidParameterValue")