diff --git a/README.md b/README.md
index 212d73f..6ccd2c7 100644
--- a/README.md
+++ b/README.md
@@ -25,16 +25,19 @@ npm install -g openapi3-generator
 
   Options:
 
-    -V, --version                  output the version number
-    -o, --output <outputDir>       directory where to put the generated files (defaults to current directory)
-    -t, --templates <templateDir>  directory where templates are located (defaults to internal templates directory)
-    -b, --basedir <baseDir>        directory to use as the base when resolving local file references (defaults to OpenAPI file directory)
-    -h, --help                     output usage information
+    -V, --version                  		output the version number
+    -o, --output <outputDir>       		directory where to put the generated files (defaults to current directory)
+    -t, --templates <templateDir>  		directory where templates are located (defaults to internal templates directory)
+    -b, --basedir <baseDir>        		directory to use as the base when resolving local file references (defaults to OpenAPI file directory)
+    -c, --curl        		        	generate a curl scripts (defaults is false)
+    -s, --skipExistingFiles        		skip existing files
+    -d, --deleteFolders <folderName>    directory names to be deleted, e.g. "auto", "*"
+    -h, --help                     		output usage information
 ```
 
 #### Examples
 
-The shortest possible syntax:
+The shortest possible syntax to create markdowns for the openapi.yaml file:
 ```bash
 og openapi.yaml markdown
 ```
@@ -44,6 +47,21 @@ Specify where to put the generated code:
 og -o ./my-docs openapi.yaml markdown
 ```
 
+The syntax to create an express server with only the endpoints for the openapi.yaml file:
+```bash
+og -o ./express-server openapi.yaml express
+```
+
+The syntax to create an full functionaly CRUD-Server, which reads and writes from json-files for the openapi.yaml file:
+```bash
+og -o ./demo-crud-server openapi.yaml json_crud_server
+```
+
+The syntax to create an full functionaly CRUD-Server with own templates and deletion of the existing demo-server :
+```bash
+og -d * -o ./demo-server -t ./ openapi.yaml demo-server-templates
+```
+
 ## Templates
 
 ### Creating your own templates
@@ -55,6 +73,7 @@ The files in your template can be of the following types:
 2. Templates: This kind of files will be compiled using [Handlebars](http://handlebarsjs.com/), and copied to the output directory.
 3. Path templates: This kind of files will be compiled using [Handlebars](http://handlebarsjs.com/), but it will generate one file per OpenAPI path.
 
+#### Example 1 - Express server
 Assuming we have the following OpenAPI Spec:
 ```yaml
 openapi: "3.0.0"
@@ -109,6 +128,107 @@ In this example the generated directory structure will be like this:
   |+ user/
    | - route.js        // this file also contains the code for methods on users.
 ```
+#### Example 2 - Json CRUD server
+Assuming we have the following OpenAPI Spec:
+```yaml
+openapi: 3.0.0
+info:
+  title: CRUD Service
+  version: 1.0.0
+  description: CRUD Service Example.
+servers:
+  - url: http://localhost:8080/crud-service/rest/v1
+...
+paths:
+ ...
+  /variants:    
+    get:...
+    post:...
+  /variants/{variantId}:  
+    parameters:
+      - name: variantId ...
+    get:...
+    delete:...
+    put:...
+  /variants/{variantId}/phases:
+    parameters:
+      - name: variantId ...
+    get:...
+    post:...
+  ...
+components:
+ ...
+  schemas:
+  ....
+    Variant:
+      description: The variant as it is used in the CRUD service.
+      type: object
+      properties:
+        id:
+          type: "integer"
+          format: "int64"
+          description: The variant's internal ID.
+          example: 123456
+        name:
+          type: "string"
+          description: The variant's name.
+          example: "Variant"
+        creationInfo:
+          $ref: "#/components/schemas/CreationInfo"
+        modificationInfo:
+          $ref: "#/components/schemas/ModificationInfo"
+        objectVersionInfo:
+          $ref: "#/components/schemas/ObjectVersionInfo"
+      required:
+        - name 
+    ....
+```
+And some template files like this:
+```
+|+ api/
+ |- index.js.hbs       		    // This is a static template, it contains placeholders that will be filled in, e.g. includes for each file in routes.
+ |+ constrains/
+  |- $$schema$$.constrain.js.hbs    // This file will be generated for each schema and contains standard functions to check constrains, each could be change.
+ |+ data/
+  |- $$schema$$.data.json.hbs       // This json file will be generated for each schema and will be filled with the example values of the schemas.
+ |+ helpers/
+  |- errorResponse.js      	    // This file will be static and contains the errorModel.
+  |- helper.js                      // This file will be static and contains the helper methods for the crud functionality to read, write and search in json files.
+ |+ models/
+  |- $$schema$$.model.js.hbs        // This file will be generated for each schema and includes the model for the schema and the mandatory field checks.
+ |+ routes/
+  |- $$path$$.route.js.hbs          // This file will be generated for each operation and contains skeleton code for each method for an operation.
+ |+ services/
+  |- $$path$$.service.js.hbs        // This file will be generated for each operation and contains the crud functionality code for each method for an operation.
+
+```
+The first important thing to notice here is the variable notation in `$$path$$.route.js.hbs`. It will be replaced by the name of the path.
+The second important thing to notice here is the variable notation in `$$schema$$.model.js.hbs`. It will be replaced by the name of the schema.
+
+
+In this example the generated directory structure will be like this:
+```
+|+ api/
+ |- index.js     		    // This file will now e.g. have included the files in routes.
+ |+ constrains/
+  |- variants.constrain.js          // This file will be used to check additionaly constrains. It can be replaced by a static file with the same name.
+	...
+ |+ data/
+  |- variants.data.json   	    // This json filecontains the example values for the Schama Variant and is used to store new variants and changes.
+	...
+|+ helpers/
+  |- errorResponse.js      	    // This file contains the errorModel.
+  |- helper.js      		    // This file contains the helper methods for the crud functionality to read, write and search in json files.
+ |+ models/
+  |- variants.model.js    	    // This file contains the model for the schema Variants and the mandatory field checks to create or update a variant.
+	...
+ |+ routes/
+  |- variants.route.js              // This file contains the code for methods on variants.
+	...
+ |+ services/
+  |- variants.service.js            // This file contains the code for methods on variants to read  write the data from variants.datajson.
+	...
+```
 
 ### Template file extensions
 You can (optionally) name your template files with `.hbs` extensions, which will be removed when writing the generated
@@ -158,3 +278,4 @@ Check out some examples in the [markdown](./templates/markdown/.partials) templa
 
 * Fran Méndez ([@fmvilas](http://twitter.com/fmvilas))
 * Richard Klose ([@richardklose](http://github.com/richardklose))
+* Matthias Suessmeier ([@suessmma](https://github.com/suessmma))
diff --git a/lib/beautifier.js b/lib/beautifier.js
index b5c2693..e920f6a 100644
--- a/lib/beautifier.js
+++ b/lib/beautifier.js
@@ -65,7 +65,7 @@ const beautifySchema = (schema) => {
   return schema;
 };
 
-const beautifyOperation = (operation, operationName, pathName, options) => {
+const beautifyOperation = (operation, operationName, path, pathName, options) => {
   operation.slug = slugg(`op-${operationName}-${pathName}`);
   operation.summaryAsHTML = mdToHTML(operation.summary);
   operation.descriptionAsHTML = mdToHTML(operation.description);
@@ -116,6 +116,19 @@ const beautifyOperation = (operation, operationName, pathName, options) => {
     });
   }
 
+  operation.parameters = [];
+  _.each(path.parameters, param => {
+    operation.parameters.push(param);
+    if (param.name.toLowerCase() == path.pathIdParameter) {
+      operation.idparameter = param.name;
+    }
+  });
+  if(operation.operationId == undefined){
+    operation.operationId = _.camelCase(`${operationName}${pathName}`);
+  }
+  if(path.additionalData != undefined){
+    operation.additionalData = path.additionalData;
+  }
   return operation;
 };
 
@@ -128,6 +141,20 @@ const cleanBrackets = text => {
   return finalText;
 };
 
+/**
+ * Accommodates Openapi object for additional operation with other objects for easier reading.
+ */
+const generateAdditionalOperation = (operationName, path, id) => {
+  const pathLower = path.toLowerCase();
+  const opertationNameLower = "/" + operationName.toLowerCase();
+  const idLower = '{' + id.toLowerCase() + '}';
+  if (!pathLower.endsWith(opertationNameLower) && !pathLower.endsWith(idLower)) {
+    return path.substring(path.lastIndexOf('/')+1,path.length);
+  } else {
+    return null;
+  }
+}
+
 module.exports = (openapi, config) => {
   openapi.basePath = openapi.basePath || '';
   openapi.info = openapi.info || {};
@@ -177,8 +204,21 @@ module.exports = (openapi, config) => {
 
     const httpMethods = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'COPY', 'HEAD', 'OPTIONS', 'LINK', 'UNLIK', 'PURGE', 'LOCK', 'UNLOCK', 'PROPFIND'];
 
+
+    pathBasic = pathName === '/' ? 'root' : pathName.split('/')[1];
+    let pathIdParameter = ''
+    if (pathBasic.endsWith('s')){
+      pathIdParameter = _.camelCase(pathBasic.slice(0, -1).concat("Id")).toLowerCase();
+    }else{
+      pathIdParameter = _.camelCase(pathBasic.slice(0).concat("Id")).toLowerCase();
+    }
+    path.pathIdParameter = pathIdParameter;
+    const additionalData = generateAdditionalOperation(path.endpointName, pathName, pathIdParameter);
+    if(additionalData !=null){
+      path.additionalData = additionalData;
+    }
     _.each(path, (operation, operationName) => {
-      if (httpMethods.includes(operationName.toUpperCase())) beautifyOperation(operation, operationName, pathName, config);
+      if (httpMethods.includes(operationName.toUpperCase())) beautifyOperation(operation, operationName, path, pathName, config);
     });
   });
 
@@ -186,7 +226,14 @@ module.exports = (openapi, config) => {
 
   const commonPrefix = sharedStart(Object.keys(openapi.paths));
   const levels = commonPrefix.split('/').length - 1;
-  openapi.__commonPrefix = commonPrefix.split('/').slice(0, levels).join('/');
-
+  openapi.__commonPrefix = commonPrefix.split('/').slice(0, levels);
+  let baseServerPath = '';
+  if (openapi.servers) {
+    baseServerPath = openapi.servers[0].url;
+    baseServerPath = baseServerPath.slice(baseServerPath.indexOf('/', 8), baseServerPath.length)
+  }
+  if (openapi.basePath == ''){
+    openapi.basePath = baseServerPath;
+  }
   return openapi;
 };
diff --git a/lib/generator.js b/lib/generator.js
index 5198a7d..bc4a8bc 100644
--- a/lib/generator.js
+++ b/lib/generator.js
@@ -22,7 +22,7 @@ const HELPERS_DIRNAME = '.helpers';
 const PARTIALS_DIRNAME = '.partials';
 
 /**
- * Deletes all matching subfolders in target directory 
+ * Deletes all matching subfolders in target directory
  *
  * @param   {Object}  config Configuration options
  * @returns {Promise}
@@ -78,7 +78,7 @@ const generateFile = options => new Promise((resolve, reject) => {
         console.warn(yellow(`Skipping file: ${generated_path}`));
         resolve();
       }
-      
+
     } catch (e) {
       reject(e);
     }
@@ -97,8 +97,8 @@ const generateOperationFile = (config, operation, operation_name) => new Promise
   fs.readFile(path.join(config.root, config.file_name), 'utf8', (err, data) => {
     if (err) return reject(err);
     const subdir = config.root
-        .replace(new RegExp(`${config.templates_dir}[/]?`),'')
-        .replace("$$path$$", _.kebabCase(operation_name));
+      .replace(config.templates_dir + "\\" ,'')
+      .replace("$$path$$", _.kebabCase(operation_name));
 
     const new_filename = config.file_name.replace('$$path$$', operation_name).replace(/.hbs$/, '');
     const target_file = path.resolve(config.target_dir, subdir, new_filename);
@@ -112,9 +112,15 @@ const generateOperationFile = (config, operation, operation_name) => new Promise
     });
 
     xfs.mkdirpSync(path.dirname(target_file));
-    fs.writeFile(target_file, content, 'utf8', (err) => {
-      if (err) return reject(err);
-      resolve();
+    fs.access(target_file, fs.F_OK, (err) => {
+      if (err) {
+        fs.writeFile(target_file, content, 'utf8', (err) => {
+          if (err) return reject(err);
+          resolve();
+        });
+      }else{
+        resolve();
+      }
     });
   });
 });
@@ -134,7 +140,6 @@ const generateOperationFiles = config => new Promise((resolve, reject) => {
     }
 
     path_name = path_name.replace(/}/g, '').replace(/{/g, ':');
-
     files[operation_name].push({
       path_name,
       path,
@@ -148,6 +153,64 @@ const generateOperationFiles = config => new Promise((resolve, reject) => {
   });
 });
 
+/**
+ * Recursiv function to add all proporties of the schema with the name
+ *
+ * @param   {Object}  config Configuration options
+ * @returns {Promise}
+ */
+
+function setPropertyName(property, name) {
+  property.name = name;
+  _.each(property.properties, (pro, pro_name) => {
+    setPropertyName(pro,pro_name );
+  });
+}
+
+/**
+ * Generates all the files for each schema by iterating over the schemas.
+ *
+ * @param   {Object}  config Configuration options
+ * @returns {Promise}
+ */
+const generateSchemaFiles = config => new Promise((resolve, reject) => {
+  const files = {};
+  _.each(config.data.openapi.components.schemas, (schema, schema_name) => {
+    _.each(schema.properties, (property, property_name) => {
+      setPropertyName(property, property_name);
+    });
+
+    fs.readFile(path.join(config.root, config.file_name), 'utf8', (err, data) => {
+      if (err) return reject(err);
+      const subdir = config.root
+        .replace(config.templates_dir + "\\", '');
+      const new_schema_name = schema_name + "s"
+      const new_filename = config.file_name.replace('$$schema$$', _.camelCase(new_schema_name)).replace(/.hbs$/, '');
+      const target_file = path.resolve(config.target_dir, subdir, new_filename);
+      const template = Handlebars.compile(data.toString());
+      const content = template({
+        openbrace: '{',
+        closebrace: '}',
+        schema_name: new_schema_name,
+        schema_properties: schema.properties,
+        schema_properties_required: schema.required,
+        openapi: config.data.openapi
+      });
+
+      xfs.mkdirpSync(path.dirname(target_file));
+      fs.access(target_file, fs.F_OK, (err) => {
+        if (err) {
+          fs.writeFile(target_file, content, 'utf8', (err) => {
+            if (err) return reject(err);
+            resolve();
+          });
+        } else {
+          resolve();
+        }
+      });
+    });
+  });
+});
 /**
  * Generates the directory structure.
  *
@@ -181,6 +244,17 @@ const generateDirectoryStructure = config => new Promise((resolve, reject) => {
         });
         const template_path = path.relative(templates_dir, path.resolve(root, stats.name));
         fs.unlink(path.resolve(target_dir, template_path), next);
+      }else if (stats.name.includes('$$schema$$') || root.includes("$$schema$$")) {
+        // this file should be handled for each in openapi.paths
+        await generateSchemaFiles({
+          root,
+          templates_dir,
+          target_dir,
+          data: config,
+          file_name: stats.name
+        });
+        const template_path = path.relative(templates_dir, path.resolve(root, stats.name));
+        fs.unlink(path.resolve(target_dir, template_path), next);
       } else {
         const file_path = path.relative(templates_dir, path.resolve(root, stats.name));
         if (!file_path.startsWith(`${PARTIALS_DIRNAME}${path.sep}`) && !file_path.startsWith(`${HELPERS_DIRNAME}${path.sep}`)) {
diff --git a/package.json b/package.json
index b87b113..1222ef6 100644
--- a/package.json
+++ b/package.json
@@ -42,6 +42,10 @@
     {
       "name": "Richard Klose",
       "email": "richard.klose@gmail.com"
+    },
+    {
+      "name": "Matthias Suessmeier",
+      "email": "suessmma94@gmail.com"
     }
   ],
   "homepage": "https://github.com/fmvilas/openapi3-generator",
diff --git a/templates/json_crud_server/.editorconfig b/templates/json_crud_server/.editorconfig
new file mode 100644
index 0000000..279aeed
--- /dev/null
+++ b/templates/json_crud_server/.editorconfig
@@ -0,0 +1,15 @@
+root = true
+
+[*]
+end_of_line = lf
+insert_final_newline = true
+charset = utf-8
+trim_trailing_whitespace = true
+indent_style = space
+indent_size = 2
+
+[Makefile]
+indent_style = tab
+
+[*.md]
+trim_trailing_whitespace = false
diff --git a/templates/json_crud_server/.eslintrc b/templates/json_crud_server/.eslintrc
new file mode 100644
index 0000000..f9e47ce
--- /dev/null
+++ b/templates/json_crud_server/.eslintrc
@@ -0,0 +1,79 @@
+extends: 'eslint:recommended'
+
+env:
+  node: true
+  es6: true
+
+parserOptions:
+  ecmaVersion: 2017
+
+rules:
+  # Possible Errors
+  no-console: 0
+  valid-jsdoc: [0, {requireReturn: false, requireParamDescription: false, requireReturnDescription: false}]
+
+  # Best Practices
+  consistent-return: 0
+  curly: 0
+  block-scoped-var: 2
+  no-else-return: 2
+  no-process-env: 2
+  no-self-compare: 2
+  no-throw-literal: 2
+  no-void: 2
+  radix: 2
+  wrap-iife: [2, outside]
+
+  # Variables
+  no-shadow: 0
+  no-use-before-define: [2, nofunc]
+  no-unused-vars: [2, { "argsIgnorePattern": "next" }]
+
+  # Node.js
+  no-process-exit: 0
+  handle-callback-err: [2, err]
+  no-new-require: 2
+  no-path-concat: 2
+
+  # Stylistic Issues
+  quotes: [2, single]
+  camelcase: 0
+  indent: [2, 2]
+  no-lonely-if: 2
+  no-floating-decimal: 2
+  brace-style: [2, 1tbs, { "allowSingleLine": true }]
+  comma-style: [2, last]
+  consistent-this: [0, self]
+  func-style: 0
+  max-nested-callbacks: 0
+  new-cap: [2, {capIsNewExceptions: [JID]}]
+  no-multiple-empty-lines: [2, {max: 1}]
+  no-nested-ternary: 2
+  semi-spacing: [2, {before: false, after: true}]
+  operator-assignment: [2, always]
+  padded-blocks: [2, never]
+  quote-props: [2, as-needed]
+  space-before-function-paren: [2, always]
+  keyword-spacing: [2, {after: true}]
+  space-before-blocks: [2, always]
+  array-bracket-spacing: [2, never]
+  computed-property-spacing: [2, never]
+  space-in-parens: [2, never]
+  space-unary-ops: [2, {words: true, nonwords: false}]
+  #spaced-line-comment: [2, always]
+  wrap-regex: 2
+  linebreak-style: [2, unix]
+  semi: [2, always]
+
+  # ECMAScript 6
+  arrow-spacing: [2, {before: true, after: true}]
+  no-class-assign: 2
+  no-const-assign: 2
+  no-dupe-class-members: 2
+  no-this-before-super: 2
+  no-var: 2
+  object-shorthand: [2, always]
+  prefer-arrow-callback: 2
+  prefer-const: 2
+  prefer-spread: 2
+  prefer-template: 2
diff --git a/templates/json_crud_server/.gitignore b/templates/json_crud_server/.gitignore
new file mode 100644
index 0000000..825fc67
--- /dev/null
+++ b/templates/json_crud_server/.gitignore
@@ -0,0 +1,3 @@
+node_modules
+.DS_Store
+npm-debug.log
diff --git a/templates/json_crud_server/.helpers/all.js b/templates/json_crud_server/.helpers/all.js
new file mode 100644
index 0000000..43b223e
--- /dev/null
+++ b/templates/json_crud_server/.helpers/all.js
@@ -0,0 +1,258 @@
+// Module constructor provides dependency injection from the generator instead of relying on require's cache here to ensure
+// the same instance of Handlebars gets the helpers installed and Lodash is definitiely available
+// regardless of where remote templates reside: in another Node project or a plain directory, which may have different or no modules available.
+module.exports = (Handlebars, _) => {
+
+  /**
+   * Compares two values.
+   */
+  Handlebars.registerHelper('equal', (lvalue, rvalue, options) => {
+    if (arguments.length < 3)
+      throw new Error('Handlebars Helper equal needs 2 parameters');
+    if (lvalue != rvalue) {
+      return options.inverse(this);
+    }
+
+    return options.fn(this);
+  });
+
+  /**
+   * Checks if a string ends with a provided value.
+   */
+  Handlebars.registerHelper('endsWith', (lvalue, rvalue, options) => {
+    if (arguments.length < 3)
+      throw new Error('Handlebars Helper equal needs 2 parameters');
+    if (lvalue.lastIndexOf(rvalue) !== lvalue.length - 1 || lvalue.length - 1 < 0) {
+      return options.inverse(this);
+    }
+    return options.fn(this);
+  });
+
+  /**
+   * Checks if Value end with another value not case sensitive.
+   */
+  Handlebars.registerHelper('endsWithLowerCase', (lvalue, rvalue, options) => {
+    if (arguments.length < 3)
+      throw new Error('Handlebars Helper match needs 2 parameters');
+    if (lvalue != undefined && rvalue != undefined) {
+      const lvalueLowerCase = lvalue.toLowerCase();
+      const rvalueLowerCase = rvalue.toLowerCase();
+      if (!lvalueLowerCase.endsWith(rvalueLowerCase)) {
+        return options.inverse(this);
+      }
+      return options.fn(this);
+    } else {
+      return options.inverse(this);
+    }
+  });
+  /**
+   * Checks if a method is a valid HTTP method.
+   */
+  Handlebars.registerHelper('validMethod', (method, options) => {
+    const authorized_methods = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'COPY', 'HEAD', 'OPTIONS', 'LINK', 'UNLIK', 'PURGE', 'LOCK', 'UNLOCK', 'PROPFIND'];
+
+    if (arguments.length < 3)
+      throw new Error('Handlebars Helper validMethod needs 1 parameter');
+    if (authorized_methods.indexOf(method.toUpperCase()) === -1) {
+      return options.inverse(this);
+    }
+
+    return options.fn(this);
+  });
+
+  /**
+   * Checks if a collection of responses contains no error responses.
+   */
+  Handlebars.registerHelper('ifNoErrorResponses', (responses, options) => {
+    const codes = responses ? Object.keys(responses) : [];
+    if (codes.find(code => Number(code) >= 400)) return options.inverse(this);
+
+    return options.fn(this);
+  });
+
+  /**
+   * Checks if a collection of responses contains no success responses.
+   */
+  Handlebars.registerHelper('ifNoSuccessResponses', (responses, options) => {
+    const codes = responses ? Object.keys(responses) : [];
+    if (codes.find(code => Number(code) >= 200 && Number(code) < 300)) return options.inverse(this);
+
+    return options.fn(this);
+  });
+
+  /**
+   * Checks if a string matches a RegExp.
+   */
+  Handlebars.registerHelper('match', (lvalue, rvalue, options) => {
+    if (arguments.length < 3)
+      throw new Error('Handlebars Helper match needs 2 parameters');
+    if (!lvalue.match(rvalue)) {
+      return options.inverse(this);
+    }
+
+    return options.fn(this);
+  });
+  /**
+   * Check if value exists
+   */
+  Handlebars.registerHelper('NotUndefined', (value, options) => {
+    if (arguments.length < 2)
+      throw new Error('Handlebars Helper match needs 2 parameters');
+    if (value != undefined) {
+      return options.fn(this);
+    } else {
+      return options.inverse(this);
+    }
+  });
+  /**
+   * Provides different ways to compare two values (i.e. equal, greater than, different, etc.)
+   */
+  Handlebars.registerHelper('compare', (lvalue, rvalue, options) => {
+    if (arguments.length < 3) throw new Error('Handlebars Helper "compare" needs 2 parameters');
+
+    const operator = options.hash.operator || '==';
+    const operators = {
+      '==': (l, r) => {
+        return l == r;
+      },
+      '===': (l, r) => {
+        return l === r;
+      },
+      '!=': (l, r) => {
+        return l != r;
+      },
+      '<': (l, r) => {
+        return l < r;
+      },
+      '>': (l, r) => {
+        return l > r;
+      },
+      '<=': (l, r) => {
+        return l <= r;
+      },
+      '>=': (l, r) => {
+        return l >= r;
+      },
+      typeof: (l, r) => {
+        return typeof l == r;
+      }
+    };
+
+    if (!operators[operator]) throw new Error(`Handlebars Helper 'compare' doesn't know the operator ${operator}`);
+
+    const result = operators[operator](lvalue, rvalue);
+
+    if (result) {
+      return options.fn(this);
+    }
+
+    return options.inverse(this);
+  });
+
+  /**
+   * Capitalizes a string.
+   */
+  Handlebars.registerHelper('capitalize', (str) => {
+    return _.capitalize(str);
+  });
+
+  /**
+   * Converts a string to its camel-cased version.
+   */
+  Handlebars.registerHelper('camelCase', (str) => {
+    return _.camelCase(str);
+  });
+
+  /**
+   * Converts a multi-line string to a single line.
+   */
+  Handlebars.registerHelper('inline', (str) => {
+    return str ? str.replace(/\n/g, '') : '';
+  });
+
+  /**
+   * Quotes a JS identifier, if necessary.
+   */
+  Handlebars.registerHelper('quote', (str) => {
+    return /[$&@-]/.test(str) ? `'${str}'` : str
+  });
+
+  /**
+   * Transform Proporty to valid json.
+   */
+  Handlebars.registerHelper('transformToJsonData', (property) => {
+    return checkProperty(property);
+  });
+
+  /**
+   * Helper function to transform proporty to valid json.
+   */
+  function checkProperty(property) {
+    if (property.type == "integer" || property.type == "boolean" || property.type == "number") {
+      return `"${property.name}": ${checkExampleValues(property.example, property.type)}`;
+    } else if (property.type == "object") {
+      let object = `"${property.name}": {`;
+      let i;
+      for (i = 0; i < _.values(property.properties).length; i++) {
+        object += checkProperty(_.values(property.properties)[i]);
+        if (i < _.values(property.properties).length - 1) {
+          object += `,`;
+        }
+      }
+      object += `}`;
+      return object;
+    } else if (property.type == "array") {
+      let object = `"${property.name}": [`;
+      let i;
+      if (property.example != undefined) {
+        for (i = 0; i < property.example.length; i++) {
+          object += checkExampleValues(property.example[i], property.items.type);
+          if (i < property.example.length - 1) {
+            object += `,`;
+          }
+        }
+      }
+      object += `]`;
+      return object;
+    } else if (property.type == "string") {
+      return `"${property.name}": ${checkExampleValues(property.example, property.type)}`;
+    } else {
+      return `"${property.name}": ${checkExampleValues(property.example, property.type)}`;
+    }
+  }
+
+  /**
+   * Helper function to transform example values to valid json.
+   */
+  function checkExampleValues(example, type) {
+    if (type == "integer" || type == "boolean" || type == "number") {
+      return example;
+    } else if (type == "object") {
+      let object = `"${example.name}": {`;
+      let i;
+      for (i = 0; i < _.values(example.properties).length; i++) {
+        object += checkProperty(_.values(example.properties)[i]);
+        if (i < _.values(property.properties).length - 1) {
+          object += `,`;
+        }
+      }
+      object += `}`;
+      return object;
+    } else if (type == "array") {
+      let object = `"${example.name}": [`;
+      let i;
+      for (i = 0; i < example.length; i++) {
+        object += checkProperty(_.values(example.properties)[i]);
+        if (i < _.values(example.properties).length - 1) {
+          object += `,`;
+        }
+      }
+      object += `]`;
+      return object;
+    } else if (type == "string") {
+      return `"${example}"`;
+    } else {
+      return `"${example}"`;
+    }
+  }
+}
diff --git a/templates/json_crud_server/README.md b/templates/json_crud_server/README.md
new file mode 100644
index 0000000..d24b98a
--- /dev/null
+++ b/templates/json_crud_server/README.md
@@ -0,0 +1,3 @@
+# {{openapi.info.title}}
+
+{{openapi.info.description}}
diff --git a/templates/json_crud_server/config/common.yml.hbs b/templates/json_crud_server/config/common.yml.hbs
new file mode 100644
index 0000000..89d34b8
--- /dev/null
+++ b/templates/json_crud_server/config/common.yml.hbs
@@ -0,0 +1,30 @@
+defaults: &defaults
+  api:
+    port: 3500
+
+  logger:
+    name: {{openapi.info.title}}
+    level: debug
+    levels:
+      trace:
+      debug: STDOUT
+      info:
+      warn:
+      error: STDERR
+      fatal:
+
+development:
+  <<: *defaults
+
+production:
+  <<: *defaults
+
+  logger:
+    level: debug
+    levels:
+      trace:
+      debug: STDOUT
+      info: ./log/info.log
+      warn: ./log/warn.log
+      error: ./log/error.log
+      fatal: ./log/fatal.log
diff --git a/templates/json_crud_server/log/.gitkeep b/templates/json_crud_server/log/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/templates/json_crud_server/package.json b/templates/json_crud_server/package.json
new file mode 100644
index 0000000..a630837
--- /dev/null
+++ b/templates/json_crud_server/package.json
@@ -0,0 +1,16 @@
+{
+  "name": "{{package.name}}",
+  "description": "{{inline openapi.info.description}}",
+  "version": "{{openapi.info.version}}",
+  "scripts": {
+    "start": "node src/bin/www",
+    "dev": "node src/bin/www | bunyan"
+  },
+  "dependencies": {
+    "body-parser": "1.13.2",
+    "bunyan": "1.5.1",
+    "cookie-parser": "1.3.5",
+    "express": "4.13.1",
+    "node-yaml-config": "0.0.3"
+  }
+}
diff --git a/templates/json_crud_server/src/api/constrains/$$schema$$.constrain.js.hbs b/templates/json_crud_server/src/api/constrains/$$schema$$.constrain.js.hbs
new file mode 100644
index 0000000..6b8c829
--- /dev/null
+++ b/templates/json_crud_server/src/api/constrains/$$schema$$.constrain.js.hbs
@@ -0,0 +1,18 @@
+const errorModel = require('../helpers/errorResponse');
+function checkDublicateConstraints{{schema_name}}(entity, list){
+  //if(){
+  return true;
+  //}else{
+  //throw new errorModel.ErrorResponse(15, `Variant with Name '${entity.name}' already exists.`, "test", 404, `Variant with Name '${entity.name}' already exists.`);}
+}
+function checkOtherConstraints{{schema_name}}(entity)
+{
+  //if(){
+  return true;
+  //}else{
+  //throw new errorModel.ErrorResponse(15, `Variant with Name '${entity.name}' already exists.`, "test", 404, `Variant with Name '${entity.name}' already exists.`);}}
+}
+  module.exports = {
+  checkDublicateConstraints{{schema_name}},
+  checkOtherConstraints{{schema_name}}
+};
diff --git a/templates/json_crud_server/src/api/data/$$schema$$.data.json.hbs b/templates/json_crud_server/src/api/data/$$schema$$.data.json.hbs
new file mode 100644
index 0000000..be57fa3
--- /dev/null
+++ b/templates/json_crud_server/src/api/data/$$schema$$.data.json.hbs
@@ -0,0 +1,5 @@
+[{
+{{#each schema_properties}}
+  {{{transformToJsonData this}}}{{#unless @last}},{{/unless}}
+  {{/each}}
+}]
diff --git a/templates/json_crud_server/src/api/helpers/errorResponse.js b/templates/json_crud_server/src/api/helpers/errorResponse.js
new file mode 100644
index 0000000..25a5ad3
--- /dev/null
+++ b/templates/json_crud_server/src/api/helpers/errorResponse.js
@@ -0,0 +1,27 @@
+class ErrorResponse {
+      constructor(
+        errorCode,
+        title,
+        instance,
+        status,
+        detail
+    ) {
+      this.errorCode= errorCode;
+      this.title= title;
+      this.instance= instance;
+      this.status= status;
+      this.detail= detail;
+      }
+}
+
+ErrorResponse.prototype.toString = function ErrorResponseToString() {
+  return '{' +
+    this.errorCode + " | " +
+    this.title + " | " +
+    this.instance + " | " +
+    this.status + " | " +
+    this.detail + '}'
+}
+module.exports = {
+  ErrorResponse
+};
diff --git a/templates/json_crud_server/src/api/helpers/helper.js b/templates/json_crud_server/src/api/helpers/helper.js
new file mode 100644
index 0000000..34b25d5
--- /dev/null
+++ b/templates/json_crud_server/src/api/helpers/helper.js
@@ -0,0 +1,100 @@
+const errorModel = require('../helpers/errorResponse');
+const fs = require('fs');
+const getNewId = (array) => {
+  if (array.length > 0) {
+    return array[array.length - 1].id + 1;
+  } else {
+    return 100000;
+  }
+};
+const newDate = () => new Date().toString();
+
+
+function mustBeInArray(array, id) {
+  return new Promise((resolve, reject) => {
+    const row = array.find(r => r.id == id);
+    if (!row) {
+      reject(new errorModel.ErrorResponse(15,"Object with id "+ id + " was not found", "test", 404, "Object with id "+ id + " was not found"))
+    }
+    resolve(row);
+  })
+}
+
+function writeJSONFile(filename, content) {
+  fs.writeFileSync(filename, JSON.stringify(content), 'utf8', (err) => {
+    if (err) {
+      console.log(err);
+    }
+  })
+}
+
+function isArray(what) {
+  if (Object.prototype.toString.call(what) === '[object Array]'){
+    throw new errorModel.ErrorResponse(15,"Now Array is allowed", "test", 400, "Now Array is allowed");
+  }
+}
+function getUniqueElementsInArray(arr, comp) {
+
+  const unique = arr
+    .map(e => e[comp])
+
+    // store the keys of the unique objects
+    .map((e, i, final) => final.indexOf(e) === i && i)
+
+    // eliminate the dead keys & store unique objects
+    .filter(e => arr[e]).map(e => arr[e]);
+
+  return unique;
+}
+
+function checkLike(value, part){
+  if(value.indexOf(part) > -1){
+    return true;
+  }else{
+    return false;
+  }
+}
+function filterValueWithOperator(filterParameter, operator, value, valueCollection, list){
+  switch(operator){
+    case "=":
+      if (!isArray(value)){
+        return list.filter(x => x[filterParameter] == value);
+      }
+    case "!=":
+      if (!isArray(value)){
+        return list.filter(x => x[filterParameter] != value);
+      }
+    case "IN":
+      if (Object.prototype.toString.call(valueCollection) === '[object Array]') {
+        filterlist = [];
+        valueCollection.forEach(x => filterlist.push(...list.filter(y => y[filterParameter] == x)));
+        return filterlist;
+      }else{
+        return list.filter(x => x[filterParameter] == value);
+      }
+      return list.filter(x => x[filterParameter] == value);
+    case "NOT_IN":
+      if (Object.prototype.toString.call(valueCollection) === '[object Array]') {
+        filterlist = list.filter(x => !(valueCollection.includes( x[filterParameter])));
+        return filterlist;
+      }else{
+        return list.filter(x => x[filterParameter] != value);
+      }
+    case "LIKE":
+      return list.filter(x => checkLike(x[filterParameter],value));
+    case "NOT_LIKE":
+      return list.filter(x => !(checkLike(x[filterParameter],value)));
+    default:
+      throw new errorModel.ErrorResponse(15,"Wrong Operator", "test", 400, "Wrong Operator");
+  }
+}
+module.exports = {
+  getNewId,
+  newDate,
+  mustBeInArray,
+  writeJSONFile,
+  isArray,
+  getUniqueElementsInArray,
+  checkLike,
+  filterValueWithOperator
+};
diff --git a/templates/json_crud_server/src/api/index.js.hbs b/templates/json_crud_server/src/api/index.js.hbs
new file mode 100644
index 0000000..41bb17d
--- /dev/null
+++ b/templates/json_crud_server/src/api/index.js.hbs
@@ -0,0 +1,46 @@
+const express = require('express');
+const cookieParser = require('cookie-parser');
+const bodyParser = require('body-parser');
+const config = require('../lib/config');
+const logger = require('../lib/logger');
+
+const log = logger(config.logger);
+const app = express();
+
+app.use(bodyParser.json());
+app.use(bodyParser.urlencoded({ extended: false }));
+app.use(cookieParser());
+
+/*
+ * Routes
+ */
+{{#each @root.openapi.endpoints}}
+{{#endsWith @root.openapi.basePath '/'}}
+app.use('{{@root.openapi.basePath}}{{..}}', require('./routes/{{..}}.route.js'));
+{{else}}
+app.use('{{@root.openapi.basePath}}/{{..}}', require('./routes/{{..}}.route.js'));
+{{/endsWith}}
+{{/each}}
+
+// catch 404
+app.use((req, res, next) => {
+   log.error(`Error 404 on ${req.url}.`);
+   res.status(404).send({
+      errorCode: 15,
+      title: `URL ${req.url} not found.`,
+      instance: "test",
+      status: 404,
+      detail: `URL ${req.url} not found.`
+   });
+});
+
+// catch errors
+app.use((err, req, res, next) => {
+   const status = err.status || 500;
+   log.error(`Error ${status} (${err.toString()}) on ${req.method} ${req.url} with payload ${req.body}.`);
+   res.set('Content-Type', 'application/json');
+   res.status(status).send(err);
+});
+
+
+    module.exports = app;
diff --git a/templates/json_crud_server/src/api/models/$$schema$$.model.js.hbs b/templates/json_crud_server/src/api/models/$$schema$$.model.js.hbs
new file mode 100644
index 0000000..d697755
--- /dev/null
+++ b/templates/json_crud_server/src/api/models/$$schema$$.model.js.hbs
@@ -0,0 +1,55 @@
+const {{camelCase this.schema_name}}Check = require('../constrains/{{camelCase this.schema_name}}.constrain.js');
+const errorModel = require('../helpers/errorResponse');
+const helper = require('../helpers/helper.js');
+
+class {{schema_name}}Model {
+      constructor(
+        {{#each schema_properties}}
+        {{this.name}}{{#unless @last}},{{/unless}}
+        {{/each}}
+    ) {
+      {{#each schema_properties}}
+      this.{{this.name}}= {{this.name}};
+       {{/each}}
+      }
+}
+function adaptModel(content, list, newInfo) {
+ let entity;
+ try{
+  entity= new {{schema_name}}Model(
+  {{#each schema_properties}}
+  content.{{this.name}}{{#unless @last}},{{/unless}}
+  {{/each}}
+  );
+  if(!newInfo){
+    const index =   list.findIndex(p => p.id == content.id);
+    {{#each schema_properties}}
+    if (entity.{{this.name}} == undefined){
+       entity.{{this.name}} = list[index].{{this.name}};
+    }
+    {{/each}}
+  }
+  if(checkRequiredConstraints{{schema_name}}(entity) && {{camelCase this.schema_name}}Check.checkDublicateConstraints{{schema_name}}(entity, list) && {{camelCase this.schema_name}}Check.checkOtherConstraints{{schema_name}}(entity)){
+      return entity;
+  }
+   }catch (e) {
+     throw e;
+   }
+}
+function checkRequiredConstraints{{schema_name}}(entity){
+      {{#each schema_properties_required}}
+      if(entity.{{this}} == undefined){
+      throw new errorModel.ErrorResponse(15, `{{../schema_name}} required attribute '{{this}}'.`, "test", 400, `{{../schema_name}} required attribute '{{this}}'.`);
+      }
+      {{/each}}
+        return true;
+      }
+  {{schema_name}}Model.prototype.toString = function {{schema_name}}ModelToString() {
+          return '{' + {{#each schema_properties}}
+                      this.{{this.name}}{{#unless @last}} + " | " + {{/unless}}{{/each}} + '}'
+  }
+module.exports = {
+  {{schema_name}}Model,
+  adaptModel,
+  checkRequiredConstraints{{schema_name}}
+};
diff --git a/templates/json_crud_server/src/api/routes/$$path$$.route.js.hbs b/templates/json_crud_server/src/api/routes/$$path$$.route.js.hbs
new file mode 100644
index 0000000..2297408
--- /dev/null
+++ b/templates/json_crud_server/src/api/routes/$$path$$.route.js.hbs
@@ -0,0 +1,56 @@
+const express = require('express');
+const {{camelCase operation_name}} = require('../services/{{operation_name}}.service');
+
+const router = new express.Router();
+
+{{#each operation}}
+  {{#each this.path}}
+    {{#validMethod @key}}
+/**
+ {{#each ../descriptionLines}}
+ * {{{this}}}
+ {{/each}}
+ */
+router.{{@key}}('{{../../subresource}}', async (req, res, next) => {
+  const options = {
+   {{#if ../requestBody}}
+    body: req.body{{#compare (lookup ../parameters 'length') 0 operator = '>' }},{{/compare}}
+    {{/if}}
+    {{#each ../parameters}}
+      {{#equal this.in "query"}}
+    {{../name}}: req.query.{{../name}}{{#unless @last}},{{/unless}}
+      {{/equal}}
+      {{#equal this.in "path"}}
+    {{../name}}: req.params.{{../name}}{{#unless @last}},{{/unless}}
+      {{/equal}}
+      {{#match @../key "(post|put)"}}
+        {{#equal ../in "body"}}
+    {{../name}}: req.body.{{../name}}{{#unless @last}},{{/unless}}
+        {{/equal}}
+      {{/match}}
+    {{/each}}
+  };
+
+  try {
+    const result = await {{camelCase ../../../operation_name}}.{{../operationId}}(options);
+    {{#ifNoSuccessResponses ../responses}}
+    res.status(200).send(result.data);
+    {{else}}
+    res.status(result.status || 200).send(result);
+    {{/ifNoSuccessResponses}}
+  } catch (err) {
+    {{#ifNoErrorResponses ../responses}}
+    return res.status(500).send({
+      status: 500,
+      error: 'Server Error'
+    });
+    {{else}}
+      next(err);
+    {{/ifNoErrorResponses}}
+  }
+});
+
+    {{/validMethod}}
+  {{/each}}
+{{/each}}
+module.exports = router;
diff --git a/templates/json_crud_server/src/api/services/$$path$$.service.js.hbs b/templates/json_crud_server/src/api/services/$$path$$.service.js.hbs
new file mode 100644
index 0000000..361bd7f
--- /dev/null
+++ b/templates/json_crud_server/src/api/services/$$path$$.service.js.hbs
@@ -0,0 +1,161 @@
+let {{camelCase operation_name}} = require('../data/{{camelCase operation_name}}.data.json');
+const {{camelCase operation_name}}Filename = './src/api/data/{{camelCase operation_name}}.data.json';
+{{#each operation}}
+{{#NotUndefined this.path.additionalData}}
+let  {{camelCase ../path.additionalData}} =  require('../data/{{camelCase  ../path.additionalData}}.data.json');
+const {{camelCase../path.additionalData}}Filename = './src/api/data/{{camelCase  ../path.additionalData}}.data.json';
+{{/NotUndefined}}
+{{/each}}
+const {{camelCase operation_name}}Model = require('../models/{{camelCase operation_name}}.model.js');
+{{#each operation}}
+{{#NotUndefined this.path.additionalData}}
+const {{camelCase../path.additionalData}}Model = require('../models/{{camelCase ../path.additionalData}}.model.js');
+{{/NotUndefined}}
+{{/each}}
+const errorModel = require('../helpers/errorResponse');
+const helper = require('../helpers/helper.js');
+{{#each operation}}
+  {{#each this.path}}
+    {{#validMethod @key}}
+/**
+ * @param {Object} options
+{{#each ../parameters}}
+{{#if this.name}}
+ * @param {{../../../../openbrace}}{{capitalize type}}{{../../../../closebrace}} options.{{name}} {{inline description}}
+{{/if}}
+{{/each}}
+ * @throws {Error}
+ * @return {Promise}
+ */
+module.exports.{{../operationId}} = async (options) => {
+  {{#compare @key "get"}}
+  {{#endsWithLowerCase ../operationId ../idparameter}}
+  return new Promise((resolve, reject) => {
+    {{#each ../parameters}}
+      {{#equal this.in "path"}}
+    const {{{quote ../name}}}= options.{{../name}};
+    {{/equal}}
+    {{/each}}
+    helper.mustBeInArray(  {{camelCase ../../../operation_name}}, {{../idparameter}})
+      .then(x => {
+        resolve(x)
+      })
+     .catch(err => reject(err))
+  });
+    {{else}}
+    {{#NotUndefined ../additionalData}}
+      return new Promise((resolve, reject) => {
+        {{#each ../parameters}}
+        {{#equal this.in "path"}}
+        const {{{quote ../name}}}= options.{{../name}};
+        {{/equal}}
+        {{/each}}
+        helper.mustBeInArray(  {{camelCase ../../../operation_name}}, {{../idparameter}})
+        .then(x => {
+            const {{camelCase ../additionalData}}Filtered = {{camelCase ../additionalData}}.filter(x => x.{{../idparameter}} == {{../idparameter}});
+            if ({{camelCase ../additionalData}}Filtered.length === 0) {
+              resolve([]);
+            }
+            resolve({{camelCase ../additionalData}}Filtered);
+            })
+          .catch(err => reject(err))
+        });
+      {{else}}
+        return new Promise((resolve, reject) => {
+      if ({{camelCase ../../../operation_name}}.length === 0) {
+        resolve([]);
+      }
+      resolve({{camelCase ../../../operation_name}})
+      });
+      {{/NotUndefined}}
+            {{/endsWithLowerCase}}
+  {{else}}
+    {{#compare @key "post"}}
+    {{#NotUndefined ../additionalData}}
+    return new Promise((resolve, reject) => {
+      {{#each ../parameters}}
+      {{#equal this.in "path"}}
+      const {{{quote ../name}}}= options.{{../name}};
+      {{/equal}}
+      {{/each}}
+      helper.mustBeInArray(  {{camelCase ../../../operation_name}}, {{../idparameter}})
+      .then(x => {
+          let  tempEntity = options.body;
+          helper.isArray(tempEntity);
+          const id = helper.getNewId({{camelCase ../additionalData}});
+          tempEntity.id = id;
+          tempEntity.{{../idparameter}} = {{../idparameter}}
+          const  {{camelCase ../additionalData}}New=  {{camelCase ../additionalData}}Model.adaptModel(tempEntity,{{camelCase ../additionalData}}, true );
+          {{camelCase ../additionalData}}.push({{camelCase ../additionalData}}New);
+          helper.writeJSONFile({{camelCase ../additionalData}}Filename, {{camelCase ../additionalData}});
+          resolve({{camelCase ../additionalData}}New);
+          })
+          .catch(err => reject(err))
+       });
+
+    {{else}}
+    return new Promise((resolve, reject) => {
+    let  tempEntity = options.body;
+    const id = helper.getNewId({{camelCase ../../../operation_name}});
+    tempEntity.id = id;
+    const {{camelCase ../../../operation_name}}New =  {{camelCase ../../../operation_name}}Model.adaptModel(tempEntity,{{camelCase ../../../operation_name}}, true );
+    {{camelCase ../../../operation_name}}.push({{camelCase ../../../operation_name}}New);
+    helper.writeJSONFile({{camelCase ../../../operation_name}}Filename, {{camelCase ../../../operation_name}});
+    resolve({{camelCase ../../../operation_name}}New)
+    });
+        {{/NotUndefined}}
+    {{else}}
+    {{#compare @key "put"}}
+    {{#endsWithLowerCase ../operationId ../idparameter}}
+    return new Promise((resolve, reject) => {
+      let  tempEntityUpdate = options.body;
+      let {{camelCase ../../../operation_name}}Updated = options.body;
+      {{#each ../parameters}}
+      {{#equal this.in "path"}}
+      const {{{quote ../name}}}= options.{{../name}};
+      {{/equal}}
+      {{/each}}
+      helper.mustBeInArray(  {{camelCase ../../../operation_name}}, {{../idparameter}})
+        .then(x => {
+          const index =   {{camelCase ../../../operation_name}}.findIndex(p => p.id == {{../idparameter}});
+          tempEntityUpdate.id = x.id
+          const {{camelCase ../../../operation_name}}Updated =  {{camelCase ../../../operation_name}}Model.adaptModel( tempEntityUpdate,{{camelCase ../../../operation_name}}, false );
+          {{camelCase ../../../operation_name}}[index] = {...{{camelCase ../../../operation_name}}Updated};
+          helper.writeJSONFile({{camelCase ../../../operation_name}}Filename, {{camelCase ../../../operation_name}});
+          resolve({{camelCase ../../../operation_name}}[index])
+        })
+        .catch(err => reject(err))
+    });
+        {{else}}
+         //to implement
+        {{/endsWithLowerCase}}
+        {{else}}
+        {{#compare @key "delete"}}
+        {{#endsWithLowerCase ../operationId ../idparameter}}
+    return new Promise((resolve, reject) => {
+             {{#each ../parameters}}
+             {{#equal this.in "path"}}
+      const {{{quote ../name}}}= options.{{../name}};
+             {{/equal}}
+             {{/each}}
+      helper.mustBeInArray(  {{camelCase ../../../operation_name}}, {{../idparameter}})
+       .then(x => {
+         {{camelCase ../../../operation_name}} = {{camelCase ../../../operation_name}}.filter(f => f.id != {{../idparameter}})
+         helper.writeJSONFile({{camelCase ../../../operation_name}}Filename, {{camelCase ../../../operation_name}});
+         resolve({status: 204})
+       })
+        .catch(err => reject(err))
+    });
+           {{else}}
+            //to implement
+           {{/endsWithLowerCase}}
+             {{else}}
+              //to implement
+             {{/compare}}            {{/compare}}
+      {{/compare}}
+  {{/compare}}
+};
+
+    {{/validMethod}}
+  {{/each}}
+{{/each}}
diff --git a/templates/json_crud_server/src/bin/www b/templates/json_crud_server/src/bin/www
new file mode 100644
index 0000000..f3d6070
--- /dev/null
+++ b/templates/json_crud_server/src/bin/www
@@ -0,0 +1,82 @@
+#!/usr/bin/env node
+
+/**
+ * Module dependencies.
+ */
+const app = require('../api');
+const http = require('http');
+const config = require('../lib/config');
+const logger = require('../lib/logger');
+
+const log = logger(config.logger);
+
+/**
+ * Get port from environment and store in Express.
+ */
+const port = normalizePort(config.api.port || '3000');
+app.set('port', port);
+
+/**
+ * Create HTTP server.
+ */
+const server = http.createServer(app);
+
+/**
+ * Listen on provided port, on all network interfaces.
+ */
+server.listen(port);
+server.on('error', onError);
+server.on('listening', onListening);
+
+/**
+ * Normalize a port into a number, string, or false.
+ */
+function normalizePort (val) {
+  const port = parseInt(val, 10);
+
+  if (isNaN(port)) {
+    // named pipe
+    return val;
+  }
+
+  if (port >= 0) {
+    // port number
+    return port;
+  }
+
+  return false;
+}
+
+/**
+ * Event listener for HTTP server "error" event.
+ */
+function onError (error) {
+  if (error.syscall !== 'listen') {
+    throw error;
+  }
+
+  const bind = typeof port === 'string' ? `Pipe ${port}` : `Port ${port}`;
+
+  // handle specific listen errors with friendly messages
+  switch (error.code) {
+  case 'EACCES':
+    log.fatal(`${bind} requires elevated privileges`);
+    process.exit(1);
+    break;
+  case 'EADDRINUSE':
+    log.fatal(`${bind} is already in use`);
+    process.exit(1);
+    break;
+  default:
+    throw error;
+  }
+}
+
+/**
+ * Event listener for HTTP server "listening" event.
+ */
+function onListening () {
+  const addr = server.address();
+  const bind = typeof addr === 'string' ? `pipe ${addr}` : `port ${addr.port}`;
+  log.debug(`Listening on ${bind}`);
+}
diff --git a/templates/json_crud_server/src/lib/config.js b/templates/json_crud_server/src/lib/config.js
new file mode 100644
index 0000000..1c0ec13
--- /dev/null
+++ b/templates/json_crud_server/src/lib/config.js
@@ -0,0 +1,6 @@
+const path = require('path');
+const yaml_config = require('node-yaml-config');
+
+const config = yaml_config.load(path.join(__dirname, '../../config/common.yml'));
+
+module.exports = config;
diff --git a/templates/json_crud_server/src/lib/logger.js b/templates/json_crud_server/src/lib/logger.js
new file mode 100644
index 0000000..36ac60d
--- /dev/null
+++ b/templates/json_crud_server/src/lib/logger.js
@@ -0,0 +1,32 @@
+const bunyan = require('bunyan');
+
+/**
+ * @param {Object} config Logger configuration
+ */
+module.exports = config => {
+  const bunyanConfig = [];
+  const levels = Object.keys(config.levels);
+
+  levels.forEach(level => {
+    const bunyanLevel = config.levels[level];
+    if (!bunyanLevel) return;
+
+    if (level === 'debug' && config.level !== 'debug') return;
+
+    const logger = {level};
+
+    if (bunyanLevel === 'STDOUT') {
+      logger.stream = process.stdout;
+    } else if (bunyanLevel === 'STDERR') {
+      logger.stream = process.stderr;
+    } else if (bunyanLevel) {
+      logger.path = bunyanLevel;
+    } else {
+      return;
+    }
+
+    bunyanConfig.push(logger);
+  });
+
+  return bunyan.createLogger({ name: config.name, streams: bunyanConfig });
+};
diff --git a/tests/openapi3/crud-json-server.yaml b/tests/openapi3/crud-json-server.yaml
new file mode 100644
index 0000000..d4ad1d5
--- /dev/null
+++ b/tests/openapi3/crud-json-server.yaml
@@ -0,0 +1,1358 @@
+openapi: 3.0.0
+info:
+  title: CRUD Service
+  version: 1.0.0
+  description: CRUD Service Example.
+  
+servers:
+  - url: http://localhost:8080/crud-service/rest/v1
+    description: Local development server.
+  
+security:
+  - oidc: []
+
+paths:
+  /configurations:
+    summary: Endpoint for handling the configuration.
+    description: Endpoint for execution operations on CRUD configuration.
+    
+    get:
+      tags:
+      - "configuration"
+      summary: Lists all configuration.
+      description: Returns all configuration available in the database.
+      responses:
+        "200":
+          description: "successful operation"
+          content:
+            application/json:
+              schema:
+                type: "array"
+                items:
+                  $ref: "#/components/schemas/Configuration"
+        "401":
+          $ref: '#/components/responses/UnauthorizedError'  
+        "403":
+          $ref: '#/components/responses/ForbiddenError'   
+        "404":
+          $ref: '#/components/responses/NotFoundError'     
+        "405":
+          $ref: '#/components/responses/MethodNotAllowedError'   
+        "500":
+          $ref: '#/components/responses/InternalServerError'   
+        default:
+          $ref: '#/components/responses/ApplicationError'  
+          
+    post:
+      tags:
+      - "configuration"
+      summary: Add a configuration.
+      description: Add a new configuration to the database.
+      requestBody:
+        description: The configuration to be created.
+        content:
+          application/json:
+            schema:
+              $ref: "#/components/schemas/Configuration"
+      responses:
+        "200":
+          description: "configuration was created successfully"
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/Configuration"
+        "400":
+          $ref: '#/components/responses/BadRequestError'   
+        "401":
+          $ref: '#/components/responses/UnauthorizedError'
+        "403":
+          $ref: '#/components/responses/ForbiddenError'  
+        "405":
+          $ref: '#/components/responses/MethodNotAllowedError' 
+        "412":
+          $ref: '#/components/responses/PreconditionFailedError'  
+        "500":
+          $ref: '#/components/responses/InternalServerError'           
+        default:
+          $ref: '#/components/responses/ApplicationError'             
+  
+  /configurations/{configurationId}:
+    summary: Endpoint for handling configurations specified by their IDs.
+    description: Endpoint for handling configurations specified by their IDs.
+    parameters:
+      - name: configurationId
+        in: path
+        description: "ID of configuration"
+        required: true
+        schema:
+          type: "integer"
+          format: "int64"
+  
+    get:
+      tags:
+      - "configuration"
+      summary: Read a configuration.
+      description: Read a single configuration by its ID.
+      responses:
+        "200":
+          description: "successful operation"
+          content:
+            application/json:
+              schema:
+                  $ref: "#/components/schemas/Configuration"
+        "401":
+          $ref: '#/components/responses/UnauthorizedError'
+        "403":
+          $ref: '#/components/responses/ForbiddenError'  
+        "404":
+          $ref: '#/components/responses/NotFoundError'   
+        "405":
+          $ref: '#/components/responses/MethodNotAllowedError' 
+        "500":
+          $ref: '#/components/responses/InternalServerError'            
+        default:
+          $ref: '#/components/responses/ApplicationError'  
+          
+    delete:
+      tags:
+      - "configuration"
+      summary: Delete a configuration.
+      description: Removes a configuration from the database.
+      responses:
+        "204":
+          description: "no content"
+        "401":
+          $ref: '#/components/responses/UnauthorizedError'
+        "403":
+          $ref: '#/components/responses/ForbiddenError'  
+        "404":
+          $ref: '#/components/responses/NotFoundError'   
+        "405":
+          $ref: '#/components/responses/MethodNotAllowedError' 
+        "500":
+          $ref: '#/components/responses/InternalServerError'           
+        default:
+          $ref: '#/components/responses/ApplicationError'
+          
+    put:
+      tags:
+      - "configuration"
+      summary: Update a configuration.
+      description: Updates an existing configuration in the database.
+      requestBody:
+        description: The configuration's properties to be updated.
+        content:
+          application/json:
+            schema:
+              $ref: "#/components/schemas/Configuration"
+      responses:
+        "200":
+          description: "successful operation"
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/Configuration"
+        "400":
+          $ref: '#/components/responses/BadRequestError'
+        "401":
+          $ref: '#/components/responses/UnauthorizedError'
+        "403":
+          $ref: '#/components/responses/ForbiddenError'  
+        "404":
+          $ref: '#/components/responses/NotFoundError'   
+        "405":
+          $ref: '#/components/responses/MethodNotAllowedError' 
+        "409":
+          $ref: '#/components/responses/ConflictError'   
+        "412":
+          $ref: '#/components/responses/PreconditionFailedError'    
+        "500":
+          $ref: '#/components/responses/InternalServerError'
+        default:
+          $ref: '#/components/responses/ApplicationError'    
+
+  /states:
+    summary: Endpoint for handling the State.
+    description: Endpoint for execution operations on CRUD State.
+    
+    get:
+      tags:
+      - "state"
+      summary: Lists all States.
+      description: Returns all State available in the database.
+      responses:
+        "200":
+          description: "successful operation"
+          content:
+            application/json:
+              schema:
+                type: "array"
+                items:
+                  $ref: "#/components/schemas/State"
+        "401":
+          $ref: '#/components/responses/UnauthorizedError'  
+        "403":
+          $ref: '#/components/responses/ForbiddenError'   
+        "404":
+          $ref: '#/components/responses/NotFoundError'     
+        "405":
+          $ref: '#/components/responses/MethodNotAllowedError'   
+        "500":
+          $ref: '#/components/responses/InternalServerError'   
+        default:
+          $ref: '#/components/responses/ApplicationError'  
+
+    post:
+      tags:
+      - "state"
+      summary: Add State.
+      description: Add a new State to the database.
+      requestBody:
+        description: The State to be created.
+        content:
+          application/json:
+            schema:
+              $ref: "#/components/schemas/State"
+      responses:
+        "200":
+          description: "State was created successfully"
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/State"
+        "400":
+          $ref: '#/components/responses/BadRequestError'   
+        "401":
+          $ref: '#/components/responses/UnauthorizedError'
+        "403":
+          $ref: '#/components/responses/ForbiddenError'  
+        "405":
+          $ref: '#/components/responses/MethodNotAllowedError' 
+        "412":
+          $ref: '#/components/responses/PreconditionFailedError'  
+        "500":
+          $ref: '#/components/responses/InternalServerError'           
+        default:
+          $ref: '#/components/responses/ApplicationError' 
+          
+  /states/{stateId}:
+    summary: Endpoint for handling States specified by their IDs.
+    description: Endpoint for handling States specified by their IDs.
+    parameters:
+      - name: stateId
+        in: path
+        description: "ID of State"
+        required: true
+        schema:
+          type: "integer"
+          format: "int64"        
+
+    get:
+      tags:
+      - "state"
+      summary: Read a State.
+      description: Read a single State by its ID.
+      responses:
+        "200":
+          description: "successful operation"
+          content:
+            application/json:
+              schema:
+                  $ref: "#/components/schemas/State"
+        "401":
+          $ref: '#/components/responses/UnauthorizedError'
+        "403":
+          $ref: '#/components/responses/ForbiddenError'  
+        "404":
+          $ref: '#/components/responses/NotFoundError'   
+        "405":
+          $ref: '#/components/responses/MethodNotAllowedError' 
+        "500":
+          $ref: '#/components/responses/InternalServerError'            
+        default:
+          $ref: '#/components/responses/ApplicationError'  
+          
+    delete:
+      tags:
+      - "state"
+      summary: Delete a State.
+      description: Removes a State from the database.
+      responses:
+        "204":
+          description: "no content"
+        "401":
+          $ref: '#/components/responses/UnauthorizedError'
+        "403":
+          $ref: '#/components/responses/ForbiddenError'  
+        "404":
+          $ref: '#/components/responses/NotFoundError'   
+        "405":
+          $ref: '#/components/responses/MethodNotAllowedError' 
+        "500":
+          $ref: '#/components/responses/InternalServerError'           
+        default:
+          $ref: '#/components/responses/ApplicationError'
+          
+    put:
+      tags:
+      - "state"
+      summary: Update a State.
+      description: Updates an existing State in the database.
+      requestBody:
+        description: The State's properties to be updated.
+        content:
+          application/json:
+            schema:
+              $ref: "#/components/schemas/State"
+      responses:
+        "200":
+          description: "successful operation"
+          content:
+            application/json:
+              schema:
+                  $ref: "#/components/schemas/State"
+        "400":
+          $ref: '#/components/responses/BadRequestError'
+        "401":
+          $ref: '#/components/responses/UnauthorizedError'
+        "403":
+          $ref: '#/components/responses/ForbiddenError'  
+        "404":
+          $ref: '#/components/responses/NotFoundError'   
+        "405":
+          $ref: '#/components/responses/MethodNotAllowedError' 
+        "409":
+          $ref: '#/components/responses/ConflictError'   
+        "412":
+          $ref: '#/components/responses/PreconditionFailedError'    
+        "500":
+          $ref: '#/components/responses/InternalServerError'
+        default:
+          $ref: '#/components/responses/ApplicationError'
+
+          
+  /phases/{phaseId}/comments:       
+    summary: Endpoint for handling comments.
+    description: Endpoint for handling comments belonging to a specific phase.
+    parameters:
+      - name: phaseId
+        in: path
+        description: "ID of the parent phase"
+        required: true
+        schema:
+          type: "integer"
+          format: "int64"
+          
+    get:
+      tags:
+      - "comment"
+      summary: Lists all comments belonging to a specific  phase by phaseId.
+      description: Returns all the comments for the specified  phase from the database.
+      responses:
+        "200":
+          description: "successful operation"
+          content:
+            application/json:
+              schema:
+                type: "array"
+                items:
+                  $ref: "#/components/schemas/Comment" 
+        "401":
+          $ref: '#/components/responses/UnauthorizedError'
+        "403":
+          $ref: '#/components/responses/ForbiddenError'  
+        "404":
+          $ref: '#/components/responses/NotFoundError'   
+        "405":
+          $ref: '#/components/responses/MethodNotAllowedError' 
+        "500":
+          $ref: '#/components/responses/InternalServerError'            
+        default:
+          $ref: '#/components/responses/ApplicationError'                  
+          
+    post:
+      tags:
+      - "comment"
+      summary: Add a comment belonging to a specific  phase by phaseId.
+      description: Add a new comment belonging to a specific  phase to the database.
+      requestBody:
+        description: The comment to be created.
+        content:
+          application/json:
+            schema:
+              $ref: "#/components/schemas/Comment"
+      responses:
+        "200":
+          description: "comment was created successfully"
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/Comment"
+        "400":
+          $ref: '#/components/responses/BadRequestError'   
+        "401":
+          $ref: '#/components/responses/UnauthorizedError'
+        "403":
+          $ref: '#/components/responses/ForbiddenError'  
+        "405":
+          $ref: '#/components/responses/MethodNotAllowedError' 
+        "412":
+          $ref: '#/components/responses/PreconditionFailedError'  
+        "500":
+          $ref: '#/components/responses/InternalServerError'           
+        default:
+          $ref: '#/components/responses/ApplicationError'        
+
+
+  /demands/{demandId}/comments:       
+    summary: Endpoint for handling comments.
+    description: Endpoint for handling comments belonging to a specific  phase.
+    parameters:
+      - name: demandId
+        in: path
+        description: "ID of the parent  phase"
+        required: true
+        schema:
+          type: "integer"
+          format: "int64"
+          
+    get:
+      tags:
+      - "comment"
+      summary: Lists all comments belonging to a demand by demandId.
+      description: Returns all the comments for the demand from the database.
+      responses:
+        "200":
+          description: "successful operation"
+          content:
+            application/json:
+              schema:
+                type: "array"
+                items:
+                  $ref: "#/components/schemas/Comment"   
+        "401":
+          $ref: '#/components/responses/UnauthorizedError'
+        "403":
+          $ref: '#/components/responses/ForbiddenError'  
+        "404":
+          $ref: '#/components/responses/NotFoundError'   
+        "405":
+          $ref: '#/components/responses/MethodNotAllowedError' 
+        "500":
+          $ref: '#/components/responses/InternalServerError'            
+        default:
+          $ref: '#/components/responses/ApplicationError'                  
+          
+    post:
+      tags:
+      - "comment"
+      summary: Add a comment belonging to a specific demand by demandId.
+      description: Add a new comment belonging to a specific demand to the database.
+      requestBody:
+        description: The comment to be created.
+        content:
+          application/json:
+            schema:
+              $ref: "#/components/schemas/Comment"
+      responses:
+        "200":
+          description: "comment was created successfully"
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/Comment"
+        "400":
+          $ref: '#/components/responses/BadRequestError'   
+        "401":
+          $ref: '#/components/responses/UnauthorizedError'
+        "403":
+          $ref: '#/components/responses/ForbiddenError'  
+        "405":
+          $ref: '#/components/responses/MethodNotAllowedError' 
+        "412":
+          $ref: '#/components/responses/PreconditionFailedError'  
+        "500":
+          $ref: '#/components/responses/InternalServerError'           
+        default:
+          $ref: '#/components/responses/ApplicationError'            
+                  
+
+  /comments/{commentId}:
+    summary: Endpoint for handling comment specified by their IDs.
+    description: Endpoint for handling comment specified by their IDs.
+    parameters:
+      - name: commentId
+        in: path
+        description: "ID of comment"
+        required: true
+        schema:
+          type: "integer"
+          format: "int64"   
+          
+    delete:
+      tags:
+      - "comment"
+      summary: Delete a comment.
+      description: Removes a comment from the database.
+      responses:
+        "204":
+          description: "no content"
+        "401":
+          $ref: '#/components/responses/UnauthorizedError'
+        "403":
+          $ref: '#/components/responses/ForbiddenError'  
+        "404":
+          $ref: '#/components/responses/NotFoundError'   
+        "405":
+          $ref: '#/components/responses/MethodNotAllowedError' 
+        "500":
+          $ref: '#/components/responses/InternalServerError'           
+        default:
+          $ref: '#/components/responses/ApplicationError'
+          
+    put:
+      tags:
+      - "comment"
+      summary: Update a comment.
+      description: Updates an existing comment in the database.
+      requestBody:
+        description: The comment's properties to be updated.
+        content:
+          application/json:
+            schema:
+              $ref: "#/components/schemas/Comment"
+      responses:
+        "200":
+          description: "successful operation"
+          content:
+            application/json:
+              schema:
+                  $ref: "#/components/schemas/Comment"
+        "400":
+          $ref: '#/components/responses/BadRequestError'
+        "401":
+          $ref: '#/components/responses/UnauthorizedError'
+        "403":
+          $ref: '#/components/responses/ForbiddenError'  
+        "404":
+          $ref: '#/components/responses/NotFoundError'   
+        "405":
+          $ref: '#/components/responses/MethodNotAllowedError' 
+        "409":
+          $ref: '#/components/responses/ConflictError'   
+        "412":
+          $ref: '#/components/responses/PreconditionFailedError'    
+        "500":
+          $ref: '#/components/responses/InternalServerError'
+        default:
+          $ref: '#/components/responses/ApplicationError'
+
+  /variants:
+    summary: Endpoint for handling the variants.
+    description: Endpoint for execution operations on CRUD variants.
+    
+    get:
+      tags:
+      - "variant"
+      summary: Lists all variants.
+      description: Returns all the variants available in the database.
+      responses:
+        "200":
+          description: "successful operation"
+          content:
+            application/json:
+              schema:
+                type: "array"
+                items:
+                  $ref: "#/components/schemas/Variant"
+        "401":
+          $ref: '#/components/responses/UnauthorizedError'  
+        "403":
+          $ref: '#/components/responses/ForbiddenError'   
+        "404":
+          $ref: '#/components/responses/NotFoundError'     
+        "405":
+          $ref: '#/components/responses/MethodNotAllowedError'   
+        "500":
+          $ref: '#/components/responses/InternalServerError'   
+        default:
+          $ref: '#/components/responses/ApplicationError'  
+            
+    post:
+      tags:
+      - "variant"
+      summary: Add variant.
+      description: Add a new variant to the database.
+      requestBody:
+        description: The variant to be created.
+        content:
+          application/json:
+            schema:
+              $ref: "#/components/schemas/Variant"
+      responses:
+        "200":
+          description: "variant was created successfully"
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/Variant"
+        "400":
+          $ref: '#/components/responses/BadRequestError'   
+        "401":
+          $ref: '#/components/responses/UnauthorizedError'
+        "403":
+          $ref: '#/components/responses/ForbiddenError'  
+        "405":
+          $ref: '#/components/responses/MethodNotAllowedError' 
+        "412":
+          $ref: '#/components/responses/PreconditionFailedError'  
+        "500":
+          $ref: '#/components/responses/InternalServerError'           
+        default:
+          $ref: '#/components/responses/ApplicationError' 
+          
+  /variants/{variantId}:  
+    summary: Endpoint for handling variants specified by their IDs.
+    description: Endpoint for handling variants specified by their IDs.
+    parameters:
+      - name: variantId
+        in: path
+        description: "ID of variant to return"
+        required: true
+        schema:
+          type: "integer"
+          format: "int64"
+    
+    get:
+      tags:
+      - "variant"
+      summary: Read a variant.
+      description: Read a single variant by its ID.
+      responses:
+        "200":
+          description: "successful operation"
+          content:
+            application/json:
+              schema:
+                  $ref: "#/components/schemas/Variant"
+        "401":
+          $ref: '#/components/responses/UnauthorizedError'
+        "403":
+          $ref: '#/components/responses/ForbiddenError'  
+        "404":
+          $ref: '#/components/responses/NotFoundError'   
+        "405":
+          $ref: '#/components/responses/MethodNotAllowedError' 
+        "500":
+          $ref: '#/components/responses/InternalServerError'            
+        default:
+          $ref: '#/components/responses/ApplicationError'
+    
+    delete:
+      tags:
+      - "variant"
+      summary: Delete variant.
+      description: Removes a variant from the database.
+      responses:
+        "204":
+          description: "no content"
+        "401":
+          $ref: '#/components/responses/UnauthorizedError'
+        "403":
+          $ref: '#/components/responses/ForbiddenError'  
+        "404":
+          $ref: '#/components/responses/NotFoundError'   
+        "405":
+          $ref: '#/components/responses/MethodNotAllowedError' 
+        "500":
+          $ref: '#/components/responses/InternalServerError'    
+        "412":  
+          $ref: '#/components/responses/PreconditionFailedError' 
+        default:
+          $ref: '#/components/responses/ApplicationError'
+          
+    put:
+      tags:
+      - "variant"
+      summary: Update variant.
+      description: Updates an existing variant in the database.
+      requestBody:
+        description: The variant's properties to be updated.
+        content:
+          application/json:
+            schema:
+              $ref: "#/components/schemas/Variant"
+      responses:
+        "200":
+          description: "successful operation"
+          content:
+            application/json:
+              schema:
+                  $ref: "#/components/schemas/Variant"
+        "400":
+          $ref: '#/components/responses/BadRequestError'
+        "401":
+          $ref: '#/components/responses/UnauthorizedError'
+        "403":
+          $ref: '#/components/responses/ForbiddenError'  
+        "404":
+          $ref: '#/components/responses/NotFoundError'   
+        "405":
+          $ref: '#/components/responses/MethodNotAllowedError' 
+        "409":
+          $ref: '#/components/responses/ConflictError'   
+        "412":
+          $ref: '#/components/responses/PreconditionFailedError'    
+        "500":
+          $ref: '#/components/responses/InternalServerError'
+        default:
+          $ref: '#/components/responses/ApplicationError'
+      
+  /variants/{variantId}/phases:
+    summary: Endpoint for handling  phases.
+    description: Endpoint for handling  phases belonging to a specific variant.
+    parameters:
+      - name: variantId
+        in: path
+        description: "ID of the parent variant"
+        required: true
+        schema:
+          type: "integer"
+          format: "int64"
+          
+    get:
+      tags:
+      - "phase"
+      summary: Lists all  phases.
+      description: Returns all the  phases for the specified variant from the database.
+      responses:
+        "200":
+          description: "successful operation"
+          content:
+            application/json:
+              schema:
+                type: "array"
+                items:
+                  $ref: "#/components/schemas/Phase"
+        "401":
+          $ref: '#/components/responses/UnauthorizedError'
+        "403":
+          $ref: '#/components/responses/ForbiddenError'  
+        "404":
+          $ref: '#/components/responses/NotFoundError'   
+        "405":
+          $ref: '#/components/responses/MethodNotAllowedError' 
+        "500":
+          $ref: '#/components/responses/InternalServerError'            
+        default:
+          $ref: '#/components/responses/ApplicationError'                  
+                  
+    post:
+      tags:
+      - "phase"
+      summary: Create new  phase.
+      description: Adds a new  phase to the variant specified by its ID.
+      requestBody:
+        description: The new  phase's properties.
+        content:
+          application/json:
+            schema:
+              $ref: "#/components/schemas/Phase"
+      responses:
+        "200":
+          description: " phase was created successfully"
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/Phase"
+        "400":
+          $ref: '#/components/responses/BadRequestError'   
+        "401":
+          $ref: '#/components/responses/UnauthorizedError'
+        "403":
+          $ref: '#/components/responses/ForbiddenError'  
+        "405":
+          $ref: '#/components/responses/MethodNotAllowedError' 
+        "412":
+          $ref: '#/components/responses/PreconditionFailedError'  
+        "500":
+          $ref: '#/components/responses/InternalServerError'           
+        default:
+          $ref: '#/components/responses/ApplicationError' 
+          
+  /phases/{phaseId}:
+    summary: Endpoint for handling  phases.
+    description: Endpoint for handling  phases specified by their ID.
+    parameters:
+      - name: phaseId
+        in: path
+        description: "ID of the  phase"
+        required: true
+        schema:
+          type: "integer"
+          format: "int64"
+    
+    get:
+      tags:
+      - "phase"
+      summary: Reads a  phase.
+      description: Reads one  phase from the database specified by its ID.
+      responses:
+        "200":
+          description: "successful operation"
+          content:
+            application/json:
+              schema:
+                  $ref: "#/components/schemas/Phase"
+        "401":
+          $ref: '#/components/responses/UnauthorizedError'
+        "403":
+          $ref: '#/components/responses/ForbiddenError'  
+        "404":
+          $ref: '#/components/responses/NotFoundError'   
+        "405":
+          $ref: '#/components/responses/MethodNotAllowedError' 
+        "500":
+          $ref: '#/components/responses/InternalServerError'            
+        default:
+          $ref: '#/components/responses/ApplicationError'
+          
+    delete:
+      tags:
+      - "phase"
+      summary: Delete  phase.
+      description: Removes a  phase from the database.
+      responses:
+        "204":
+          description: "no content"
+        "401":
+          $ref: '#/components/responses/UnauthorizedError'
+        "403":
+          $ref: '#/components/responses/ForbiddenError'  
+        "404":
+          $ref: '#/components/responses/NotFoundError'   
+        "405":
+          $ref: '#/components/responses/MethodNotAllowedError' 
+        "412":  
+          $ref: '#/components/responses/PreconditionFailedError'   
+        "500":
+          $ref: '#/components/responses/InternalServerError'           
+        default:
+          $ref: '#/components/responses/ApplicationError'
+      
+    put:
+      tags:
+      - "phase"
+      summary: Update  phase.
+      description: Updates an existing  phase in the database.
+      requestBody:
+        description: The  phase's properties to be updated.
+        content:
+          application/json:
+            schema:
+              $ref: "#/components/schemas/Phase"
+      responses:
+        "200":
+          description: "successful operation"
+          content:
+            application/json:
+              schema:
+                  $ref: "#/components/schemas/Phase"
+        "400":
+          $ref: '#/components/responses/BadRequestError'
+        "401":
+          $ref: '#/components/responses/UnauthorizedError'
+        "403":
+          $ref: '#/components/responses/ForbiddenError'  
+        "404":
+          $ref: '#/components/responses/NotFoundError'   
+        "405":
+          $ref: '#/components/responses/MethodNotAllowedError' 
+        "409":
+          $ref: '#/components/responses/ConflictError'   
+        "412":
+          $ref: '#/components/responses/PreconditionFailedError'    
+        "500":
+          $ref: '#/components/responses/InternalServerError'
+        default:
+          $ref: '#/components/responses/ApplicationError'
+          
+          
+  /phases/{phaseId}/demands:
+    summary: Endpoint for handling demands.
+    description: Endpoint for handling demands belonging to a specific phase.
+    parameters:
+      - name: phaseId
+        in: path
+        description: "ID of the parent phase"
+        required: true
+        schema:
+          type: "integer"
+          format: "int64"
+          
+    get:
+      tags:
+      - "demand"
+      summary: Lists all demands belonging to a specific  phase by phaseId.
+      description: Returns all the demands for the specified  phase from the database.
+      responses:
+        "200":
+          description: "successful operation"
+          content:
+            application/json:
+              schema:
+                type: "array"
+                items:
+                  $ref: "#/components/schemas/Demand"
+        "401":
+          $ref: '#/components/responses/UnauthorizedError'
+        "403":
+          $ref: '#/components/responses/ForbiddenError'  
+        "404":
+          $ref: '#/components/responses/NotFoundError'   
+        "405":
+          $ref: '#/components/responses/MethodNotAllowedError' 
+        "500":
+          $ref: '#/components/responses/InternalServerError'            
+        default:
+          $ref: '#/components/responses/ApplicationError'                  
+                  
+    post:
+      tags:
+      - "demand"
+      summary: Add a demand belonging to a specific phase by phaseId.
+      description: Adds a new demand to the phase specified by its ID.
+      requestBody:
+        description: The new demand's properties.
+        content:
+          application/json:
+            schema:
+              $ref: "#/components/schemas/Demand"
+      responses:
+        "200":
+          description: "succesful operation"
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/Demand"
+        "400":
+          $ref: '#/components/responses/BadRequestError'   
+        "401":
+          $ref: '#/components/responses/UnauthorizedError'
+        "403":
+          $ref: '#/components/responses/ForbiddenError'  
+        "405":
+          $ref: '#/components/responses/MethodNotAllowedError' 
+        "412":
+          $ref: '#/components/responses/PreconditionFailedError'  
+        "500":
+          $ref: '#/components/responses/InternalServerError'           
+        default:
+          $ref: '#/components/responses/ApplicationError' 
+          
+          
+  /demands/{demandId}:
+    summary: Endpoint for handling demands.
+    description: Endpoint for handling demands specified by their ID.
+    parameters:
+      - name: demandId
+        in: path
+        description: "ID of the demand"
+        required: true
+        schema:
+          type: "integer"
+          format: "int64"
+    
+    get:
+      tags:
+      - "demand"
+      summary: Reads a demand.
+      description: Reads one demand from the database specified by its ID.
+      responses:
+        "200":
+          description: "successful operation"
+          content:
+            application/json:
+              schema:
+                  $ref: "#/components/schemas/Demand"
+        "401":
+          $ref: '#/components/responses/UnauthorizedError'
+        "403":
+          $ref: '#/components/responses/ForbiddenError'  
+        "404":
+          $ref: '#/components/responses/NotFoundError'   
+        "405":
+          $ref: '#/components/responses/MethodNotAllowedError' 
+        "500":
+          $ref: '#/components/responses/InternalServerError'            
+        default:
+          $ref: '#/components/responses/ApplicationError'
+          
+    delete:
+      tags:
+      - "demand"
+      summary: Delete demand.
+      description: Removes a demand from the database.
+      responses:
+        "204":
+          description: "no content"
+        "401":
+          $ref: '#/components/responses/UnauthorizedError'
+        "403":
+          $ref: '#/components/responses/ForbiddenError'  
+        "404":
+          $ref: '#/components/responses/NotFoundError'   
+        "405":
+          $ref: '#/components/responses/MethodNotAllowedError' 
+        "412":  
+          $ref: '#/components/responses/PreconditionFailedError'   
+        "500":
+          $ref: '#/components/responses/InternalServerError'           
+        default:
+          $ref: '#/components/responses/ApplicationError'
+      
+    put:
+      tags:
+      - "demand"
+      summary: Update demand.
+      description: Updates an existing demand in the database.
+      requestBody:
+        description: The demand's properties to be updated.
+        content:
+          application/json:
+            schema:
+              $ref: "#/components/schemas/Demand"
+      responses:
+        "200":
+          description: "successful operation"
+          content:
+            application/json:
+              schema:
+                  $ref: "#/components/schemas/Demand"
+        "400":
+          $ref: '#/components/responses/BadRequestError'
+        "401":
+          $ref: '#/components/responses/UnauthorizedError'
+        "403":
+          $ref: '#/components/responses/ForbiddenError'  
+        "404":
+          $ref: '#/components/responses/NotFoundError'   
+        "405":
+          $ref: '#/components/responses/MethodNotAllowedError' 
+        "409":
+          $ref: '#/components/responses/ConflictError'   
+        "412":
+          $ref: '#/components/responses/PreconditionFailedError'    
+        "500":
+          $ref: '#/components/responses/InternalServerError'
+        default:
+          $ref: '#/components/responses/ApplicationError'
+     
+     
+    
+components:
+
+  securitySchemes:
+    oidc:
+      type: http
+      scheme: bearer
+      bearerFormat: JWT
+
+  schemas:
+      
+    Configuration:
+      description: The configuration as it is used in the CRUD service.
+      type: object
+      properties:
+        id:
+          type: "integer"
+          format: "int64"
+          description: The configuration' s internal ID
+          example: 123456
+        externalId: 
+          type: "string"
+          description: The external id as string.
+          example: "C0001"
+        name:
+          type: "string"
+          description: The configuration as String.
+          example: "Configuration 1"
+      required:
+        - name
+    
+    State:
+      description: The State as it is used in the CRUD service.
+      type: object
+      properties: 
+        id:
+          type: "integer"
+          format: "int64"
+          description: The State's internal ID.
+          example: 123456
+        name:
+          type: "string"
+          description: The State's name.
+          example: "failed"
+      required: 
+        - name
+      
+    Variant:
+      description: The variant as it is used in the CRUD service.
+      type: object
+      properties:
+        id:
+          type: "integer"
+          format: "int64"
+          description: The variant's internal ID.
+          example: 123456
+        name:
+          type: "string"
+          description: The variant's name.
+          example: "Variant"
+        creationInfo:
+          $ref: "#/components/schemas/CreationInfo"
+        modificationInfo:
+          $ref: "#/components/schemas/ModificationInfo"
+        objectVersionInfo:
+          $ref: "#/components/schemas/ObjectVersionInfo"
+      required:
+        - name
+        
+    Phase:
+      description: The phase as it is used in the CRUD service.
+      type: object
+      properties:
+        id:
+          type: "integer"
+          format: "int64"
+          description: The phase's internal ID.
+          example: 123456
+        variantId:
+          type: "integer"
+          format: "int64"
+          description: The ID of the phase's parent variant.
+          example: 123456
+        availableConfigurationIds:
+          type: array
+          items:
+            type: "integer"
+            format: "int64"
+          description: The configurations available in this phase.
+          example: [123456, 789123]
+        name:
+          type: "string"
+          description: The  phase's name.
+          example: "A 1.3"
+          pattern: '^[A-Z]( )?[0-9]\.[0-9]$'
+        creationInfo:
+          $ref: "#/components/schemas/CreationInfo"
+        modificationInfo:
+          $ref: "#/components/schemas/ModificationInfo"
+        objectVersionInfo:
+          $ref: "#/components/schemas/ObjectVersionInfo"
+      required:
+        - name
+        - variantId
+        - availableConfigurationIds
+        
+    Demand:
+      description: The demand as it is used in the CRUD service.
+      type: object
+      properties:
+        id:
+          type: "integer"
+          format: "int64"
+          description: The demand's internal ID.
+          example: 123456
+        phaseId:
+          type: "integer"
+          format: "int64"
+          description: The parent phase's internal ID.
+          example: 123456
+        configuration:
+          $ref: "#/components/schemas/Configuration"
+        state:
+          $ref: "#/components/schemas/State"
+        usage:
+          type: "string"
+          description: The demand's usage.
+          example: "Sample Usage"
+        creationInfo:
+          $ref: "#/components/schemas/CreationInfo"
+        modificationInfo:
+          $ref: "#/components/schemas/ModificationInfo"
+        objectVersionInfo:
+          $ref: "#/components/schemas/ObjectVersionInfo"
+      required:
+        - phaseId
+        - configuration
+        - usage
+        
+    Comment:
+      description: A comment created by a user.
+      type: object
+      properties:
+        id:
+          type: "integer"
+          format: "int64"
+          description: The comment's internal ID.
+          example: 123456
+        comment:
+          type: "string"
+          description: The comment as it was enetered by the user.
+          example: "Some comment"
+        phaseId:
+          type: "integer"
+          format: "int64"
+          example: 123456
+        demandId:
+          type: "integer"
+          format: "int64"
+          example: 123456
+        creationInfo:
+          $ref: "#/components/schemas/CreationInfo"
+      required:
+        - comment
+        
+    ModificationInfo:
+      description: The modification info contains meta information about the data object's last modification.
+      type: object
+      properties:
+        updatedBy:
+          type: "string"
+          description: The unique ID of the user, who committed the latest modifications.
+          example: "suessmma"
+        updatedAt:
+          type: "string"
+          format: "date-time"
+          description: The date and time when the data object was updated.
+          example: "2020-02-23T18:25:43.511Z"
+      required:
+        - updatedBy
+        - updatedAt
+  
+    ObjectVersionInfo:
+      description: The version info describes the current version of the objects in this application.
+      type: object
+      properties:
+        objectVersion:
+            type: "integer"
+            format: "int32"
+            description: The object's internal version.
+            example: 1
+      required:
+        - objectVersion
+  
+    CreationInfo:
+      description: The creation info contains meta information about the data object's creation.
+      type: object
+      properties:
+        createdBy:
+          type: "string"
+          description: The unique ID of the user, who created the data object.
+          example: "suessmma"
+        createdAt:
+          type: "string"
+          format: "date-time"
+          description: The date and time when the data object was created.
+          example: "2020-02-23T18:25:43.511Z"
+      required:
+        - createdBy
+        - createdAt
+        
+        
+    ApplicationErrorResponse:
+      description: Scheme describing an internal application error, which will be shown to the user.
+      type: object
+      properties:
+        errorCode:
+          type: "integer"
+          format: "int64"
+          description: A unique error code defined in the service to specify the cause of the error.
+          example: 15
+        title:
+          type: "string"
+          description: A concise description of the error. 
+          example: "Unknown ID"
+        instance:
+          type: "string"
+          description: A unique error ID.
+          example: "bbcec01a-da1c-4437-8f77-17ede1bb2d2a"
+        status:
+          type: "integer"
+          description: The HTTP status code.
+          example: 500
+        detail:
+          type: "string"
+          description: Optional attribute to show the stacktrace in the response.
+          example: "com.bmw.heat.exception.SomeException: SomeException error occurred!\r\n\tat..."
+      required:
+        - errorCode
+        - title
+        - instance
+        - status
+        
+        
+  responses:
+    BadRequestError:
+      description: A bad request error occured.
+      content:
+        application/json:
+          schema:
+            $ref: "#/components/schemas/ApplicationErrorResponse"   
+  
+    UnauthorizedError:
+      description: A unauthorized error occured.
+      content:
+        application/json:
+          schema:
+            $ref: "#/components/schemas/ApplicationErrorResponse" 
+            
+    ForbiddenError:
+      description: A forbidden error occured.
+      content:
+        application/json:
+          schema:
+            $ref: "#/components/schemas/ApplicationErrorResponse" 
+            
+    NotFoundError:
+      description: A not found error occured.
+      content:
+        application/json:
+          schema:
+            $ref: "#/components/schemas/ApplicationErrorResponse"  
+            
+    MethodNotAllowedError:
+      description: A method not allowed error occured.
+      content:
+        application/json:
+          schema:
+            $ref: "#/components/schemas/ApplicationErrorResponse"      
+  
+    ConflictError:
+      description: Another request has updated or deleted the same object.
+      content:
+        application/json:
+          schema:
+            $ref: "#/components/schemas/ApplicationErrorResponse"  
+            
+    PreconditionFailedError:
+      description: A precondition was violated
+      content:
+        application/json:
+          schema:
+            $ref: "#/components/schemas/ApplicationErrorResponse"
+            
+    InternalServerError:
+      description: A internal server error occured.
+      content:
+        application/json:
+          schema:
+            $ref: "#/components/schemas/ApplicationErrorResponse"              
+            
+    ApplicationError:
+      description: An other error occurred. The response content describes the error's details.
+      content:
+        application/json:
+          schema:
+            $ref: "#/components/schemas/ApplicationErrorResponse"
\ No newline at end of file