diff --git a/validationmdl/validationcore/CONTRIBUTING.md b/validationmdl/validationcore/CONTRIBUTING.md
new file mode 100644
index 0000000000000000000000000000000000000000..dd4b0ed5f4fb40350bf63a0f88291b921c547cfd
--- /dev/null
+++ b/validationmdl/validationcore/CONTRIBUTING.md
@@ -0,0 +1,12 @@
+# Contributing
+
+## Must follow the guide for issues
+  - Use the search tool before opening a new issue.
+  - Please provide source code and stack trace if you found a bug.
+  - Please review the existing issues, [project cards](https://github.com/thedevsaddam/govalidator/projects/1) and provide feedback to them
+
+## Pull Request Process
+  - Open your pull request against `dev` branch
+  - It should pass all tests in the available continuous integrations systems such as TravisCI.
+  - You should add/modify tests to cover your proposed code changes.
+  - If your pull request contains a new feature, please document it on the README.
diff --git a/validationmdl/validationcore/LICENSE.md b/validationmdl/validationcore/LICENSE.md
new file mode 100644
index 0000000000000000000000000000000000000000..5786a9421b13c54aadb26eec80bda6628c144bb4
--- /dev/null
+++ b/validationmdl/validationcore/LICENSE.md
@@ -0,0 +1,21 @@
+# The MIT License (MIT)
+
+Copyright (c) 2017 Saddam H <thedevsaddam@gmail.com>
+
+> Permission is hereby granted, free of charge, to any person obtaining a copy
+> of this software and associated documentation files (the "Software"), to deal
+> in the Software without restriction, including without limitation the rights
+> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+> copies of the Software, and to permit persons to whom the Software is
+> furnished to do so, subject to the following conditions:
+>
+> The above copyright notice and this permission notice shall be included in
+> all copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+> THE SOFTWARE.
diff --git a/validationmdl/validationcore/README.md b/validationmdl/validationcore/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..11eff74fee33bf7f84c061748ff85214bee5d77a
--- /dev/null
+++ b/validationmdl/validationcore/README.md
@@ -0,0 +1,232 @@
+Package govalidator
+=========================
+[![Build Status](https://travis-ci.org/thedevsaddam/govalidator.svg?branch=master)](https://travis-ci.org/thedevsaddam/govalidator)
+[![Project status](https://img.shields.io/badge/version-1.9-green.svg)](https://github.com/thedevsaddam/govalidator/releases)
+[![Go Report Card](https://goreportcard.com/badge/github.com/thedevsaddam/govalidator)](https://goreportcard.com/report/github.com/thedevsaddam/govalidator)
+[![Coverage Status](https://coveralls.io/repos/github/thedevsaddam/govalidator/badge.svg?branch=master)](https://coveralls.io/github/thedevsaddam/govalidator?branch=master)
+[![GoDoc](https://godoc.org/github.com/thedevsaddam/govalidator?status.svg)](https://godoc.org/github.com/thedevsaddam/govalidator)
+[![License](https://img.shields.io/dub/l/vibe-d.svg)](https://github.com/thedevsaddam/govalidator/blob/dev/LICENSE.md)
+
+Validate golang request data with simple rules. Highly inspired by Laravel's request validation.
+
+
+### Installation
+
+Install the package using
+```go
+$ go get github.com/thedevsaddam/govalidator
+// or
+$ go get gopkg.in/thedevsaddam/govalidator.v1
+```
+
+### Usage
+
+To use the package import it in your `*.go` code
+```go
+import "github.com/thedevsaddam/govalidator"
+// or
+import "gopkg.in/thedevsaddam/govalidator.v1"
+```
+
+### Example
+
+***Validate `form-data`, `x-www-form-urlencoded` and `query params`***
+
+```go
+
+package main
+
+import (
+	"encoding/json"
+	"fmt"
+	"net/http"
+
+	"github.com/thedevsaddam/govalidator"
+)
+
+func handler(w http.ResponseWriter, r *http.Request) {
+	rules := govalidator.MapData{
+		"username": []string{"required", "between:3,8"},
+		"email":    []string{"required", "min:4", "max:20", "email"},
+		"web":      []string{"url"},
+		"phone":    []string{"digits:11"},
+		"agree":    []string{"bool"},
+		"dob":      []string{"date"},
+	}
+
+	messages := govalidator.MapData{
+		"username": []string{"required:আপনাকে অবশ্যই ইউজারনেম দিতে হবে", "between:ইউজারনেম অবশ্যই ৩-৮ অক্ষর হতে হবে"},
+		"phone":    []string{"digits:ফোন নাম্বার অবশ্যই ১১ নম্বারের হতে হবে"},
+	}
+
+	opts := govalidator.Options{
+		Request:         r,        // request object
+		Rules:           rules,    // rules map
+		Messages:        messages, // custom message map (Optional)
+		RequiredDefault: true,     // all the field to be pass the rules
+	}
+	v := govalidator.New(opts)
+	e := v.Validate()
+	err := map[string]interface{}{"validationError": e}
+	w.Header().Set("Content-type", "application/json")
+	json.NewEncoder(w).Encode(err)
+}
+
+func main() {
+	http.HandleFunc("/", handler)
+	fmt.Println("Listening on port: 9000")
+	http.ListenAndServe(":9000", nil)
+}
+
+```
+
+Send request to the server using curl or postman: `curl GET "http://localhost:9000?web=&phone=&zip=&dob=&agree="`
+
+
+***Response***
+```json
+{
+    "validationError": {
+        "agree": [
+            "The agree may only contain boolean value, string or int 0, 1"
+        ],
+        "dob": [
+            "The dob field must be a valid date format. e.g: yyyy-mm-dd, yyyy/mm/dd etc"
+        ],
+        "email": [
+            "The email field is required",
+            "The email field must be a valid email address"
+        ],
+        "phone": [
+            "ফোন নাম্বার অবশ্যই ১১ নম্বারের হতে হবে"
+        ],
+        "username": [
+            "আপনাকে অবশ্যই ইউজারনেম দিতে হবে",
+            "ইউজারনেম অবশ্যই ৩-৮ অক্ষর হতে হবে"
+        ],
+        "web": [
+            "The web field format is invalid"
+        ]
+    }
+}
+```
+
+### More examples
+
+***Validate file***
+
+* [Validate file](doc/FILE_VALIDATION.md)
+
+***Validate `application/json` or `text/plain` as raw body***
+
+* [Validate JSON to simple struct](doc/SIMPLE_STRUCT_VALIDATION.md)
+* [Validate JSON to map](doc/MAP_VALIDATION.md)
+* [Validate JSON to nested struct](doc/NESTED_STRUCT.md)
+* [Validate using custom rule](doc/CUSTOM_RULE.md)
+
+### Validation Rules
+* `alpha` The field under validation must be entirely alphabetic characters.
+* `alpha_dash` The field under validation may have alpha-numeric characters, as well as dashes and underscores.
+* `alpha_num` The field under validation must be entirely alpha-numeric characters.
+* `between:numeric,numeric` The field under validation check the length of characters/ length of array, slice, map/ range between two integer or float number etc.
+* `numeric` The field under validation must be entirely numeric characters.
+* `numeric_between:numeric,numeric` The field under validation must be a numeric value between the range.
+   e.g: `numeric_between:18,65` may contains numeric value like `35`, `55` . You can also pass float value to check
+* `bool` The field under validation must be able to be cast as a boolean. Accepted input are `true, false, 1, 0, "1" and "0"`.
+* `credit_card` The field under validation must have a valid credit card number. Accepted cards are `Visa, MasterCard, American Express, Diners Club, Discover and JCB card`
+* `coordinate` The field under validation must have a value of valid coordinate.
+* `css_color` The field under validation must have a value of valid CSS color. Accepted colors are `hex, rgb, rgba, hsl, hsla` like `#909, #00aaff, rgb(255,122,122)`
+* `date` The field under validation must have a valid date of format yyyy-mm-dd or yyyy/mm/dd.
+* `date:dd-mm-yyyy` The field under validation must have a valid date of format dd-mm-yyyy.
+* `digits:int` The field under validation must be numeric and must have an exact length of value.
+* `digits_between:int,int` The field under validation must be numeric and must have length between the range.
+   e.g: `digits_between:3,5` may contains digits like `2323`, `12435`
+* `in:foo,bar` The field under validation must have one of the values. e.g: `in:admin,manager,user` must contain the values (admin or manager or user)
+* `not_in:foo,bar` The field under validation must have one value except foo,bar. e.g: `not_in:admin,manager,user` must not contain the values (admin or manager or user)
+* `email` The field under validation must have a valid email.
+* `float` The field under validation must have a valid float number.
+* `max:numeric` The field under validation must have a min length of characters for string, items length for slice/map, value for integer or float.
+   e.g: `min:3` may contains characters minimum length of 3 like `"john", "jane", "jane321"` but not `"mr", "xy"`
+* `max:numeric` The field under validation must have a max length of characters for string, items length for slice/map, value for integer or float.
+   e.g: `max:6` may contains characters maximum length of 6 like `"john doe", "jane doe"` but not `"john", "jane"`
+* `len:numeric` The field under validation must have an exact length of characters, exact integer or float value, exact size of map/slice.
+   e.g: `len:4` may contains characters exact length of 4 like `Food, Mood, Good`
+* `ip` The field under validation must be a valid IP address.
+* `ip_v4` The field under validation must be a valid IP V4 address.
+* `ip_v6` The field under validation must be a valid IP V6 address.
+* `json` The field under validation must be a valid JSON string.
+* `lat` The field under validation must be a valid latitude.
+* `lon` The field under validation must be a valid longitude.
+* `regex:regular expression` The field under validation validate against the regex. e.g: `regex:^[a-zA-Z]+$` validate the letters.
+* `required` The field under validation must be present in the input data and not empty. A field is considered "empty" if one of the following conditions are true: 1) The value is null. 2)The value is an empty string. 3) Zero length of map, slice. 4) Zero value for integer or float
+* `size:integer` The field under validation validate a file size only in form-data ([see example](doc/FILE_VALIDATION.md))
+* `ext:jpg,png` The field under validation validate a file extension ([see example](doc/FILE_VALIDATION.md))
+* `mime:image/jpg,image/png` The field under validation validate a file mime type ([see example](doc/FILE_VALIDATION.md))
+* `url` The field under validation must be a valid URL.
+* `uuid` The field under validation must be a valid UUID.
+* `uuid_v3` The field under validation must be a valid UUID V3.
+* `uuid_v4` The field under validation must be a valid UUID V4.
+* `uuid_v5` The field under validation must be a valid UUID V5.
+
+### Add Custom Rules
+
+```go
+func init() {
+	// simple example
+	govalidator.AddCustomRule("must_john", func(field string, rule string, message string, value interface{}) error {
+		val := value.(string)
+		if val != "john" || val != "John" {
+			return fmt.Errorf("The %s field must be John or john", field)
+		}
+		return nil
+	})
+
+	// custom rules to take fixed length word.
+	// e.g: word:5 will throw error if the field does not contain exact 5 word
+	govalidator.AddCustomRule("word", func(field string, rule string, message string, value interface{}) error {
+		valSlice := strings.Fields(value.(string))
+		l, _ := strconv.Atoi(strings.TrimPrefix(rule, "word:")) //handle other error
+		if len(valSlice) != l {
+			return fmt.Errorf("The %s field must be %d word", field, l)
+		}
+		return nil
+	})
+
+}
+```
+Note: Array, map, slice can be validated by adding custom rules.
+
+### Custom Message/ Localization
+If you need to translate validation message you can pass messages as options.
+
+```go
+messages := govalidator.MapData{
+	"username": []string{"required:You must provide username", "between:The username field must be between 3 to 8 chars"},
+	"zip":      []string{"numeric:Please provide zip field as numeric"},
+}
+
+opts := govalidator.Options{
+	Messages:        messages,
+}
+```
+
+### Contribution
+If you are interested to make the package better please send pull requests or create an issue so that others can fix.
+[Read the contribution guide here](CONTRIBUTING.md)
+
+### Contributors
+
+- [Jun Kimura](https://github.com/bluele)
+- [Steve HIll](https://github.com/stevehill1981)
+- [ErickSkrauch](https://github.com/erickskrauch)
+- [Sakib Sami](https://github.com/s4kibs4mi)
+- [Rip](https://github.com/ripbandit)
+- [Jose Nazario](https://github.com/paralax)
+
+### See all [contributors](https://github.com/thedevsaddam/govalidator/graphs/contributors)
+
+### See [benchmarks](doc/BENCHMARK.md)
+### Read [API documentation](https://godoc.org/github.com/thedevsaddam/govalidator)
+
+### **License**
+The **govalidator** is an open-source software licensed under the [MIT License](LICENSE.md).
diff --git a/validationmdl/validationcore/doc/BENCHMARK.md b/validationmdl/validationcore/doc/BENCHMARK.md
new file mode 100644
index 0000000000000000000000000000000000000000..ab378b425323c1c7c40d8a5882652ed5e0d0d18e
--- /dev/null
+++ b/validationmdl/validationcore/doc/BENCHMARK.md
@@ -0,0 +1,36 @@
+Benchmarks
+===================
+
+Machine: Mac Book Pro-2015 2.7GHz 8GB
+Go version: go1.8.1 darwin/amd64
+
+| ➜ go test -run=XXX -bench=. -benchmem=true |           |            |           |              |
+|--------------------------------------------|-----------|------------|-----------|--------------|
+| Benchmark_IsAlpha-4                        | 5000000   | 323 ns/op  | 0 B/op    | 0 allocs/op  |
+| Benchmark_IsAlphaDash-4                    | 3000000   | 415 ns/op  | 0 B/op    | 0 allocs/op  |
+| Benchmark_IsAlphaNumeric-4                 | 5000000   | 338 ns/op  | 0 B/op    | 0 allocs/op  |
+| Benchmark_IsBoolean-4                      | 100000000 | 10.6 ns/op | 0 B/op    | 0 allocs/op  |
+| Benchmark_IsCreditCard-4                   | 3000000   | 543 ns/op  | 0 B/op    | 0 allocs/op  |
+| Benchmark_IsCoordinate-4                   | 2000000   | 950 ns/op  | 0 B/op    | 0 allocs/op  |
+| Benchmark_IsCSSColor-4                     | 5000000   | 300 ns/op  | 0 B/op    | 0 allocs/op  |
+| Benchmark_IsDate-4                         | 2000000   | 719 ns/op  | 0 B/op    | 0 allocs/op  |
+| Benchmark_IsDateDDMMYY-4                   | 3000000   | 481 ns/op  | 0 B/op    | 0 allocs/op  |
+| Benchmark_IsEmail-4                        | 1000000   | 1172 ns/op | 0 B/op    | 0 allocs/op  |
+| Benchmark_IsFloat-4                        | 3000000   | 432 ns/op  | 0 B/op    | 0 allocs/op  |
+| Benchmark_IsIn-4                           | 200000000 | 7.34 ns/op | 0 B/op    | 0 allocs/op  |
+| Benchmark_IsJSON-4                         | 1000000   | 1595 ns/op | 768 B/op  | 12 allocs/op |
+| Benchmark_IsNumeric-4                      | 10000000  | 195 ns/op  | 0 B/op    | 0 allocs/op  |
+| Benchmark_IsLatitude-4                     | 3000000   | 523 ns/op  | 0 B/op    | 0 allocs/op  |
+| Benchmark_IsLongitude-4                    | 3000000   | 516 ns/op  | 0 B/op    | 0 allocs/op  |
+| Benchmark_IsIP-4                           | 1000000   | 1073 ns/op | 0 B/op    | 0 allocs/op  |
+| Benchmark_IsIPV4-4                         | 3000000   | 580 ns/op  | 0 B/op    | 0 allocs/op  |
+| Benchmark_IsIPV6-4                         | 1000000   | 1288 ns/op | 0 B/op    | 0 allocs/op  |
+| Benchmark_IsMatchedRegex-4                 | 200000    | 7133 ns/op | 5400 B/op | 66 allocs/op |
+| Benchmark_IsURL-4                          | 1000000   | 1159 ns/op | 0 B/op    | 0 allocs/op  |
+| Benchmark_IsUUID-4                         | 2000000   | 832 ns/op  | 0 B/op    | 0 allocs/op  |
+| Benchmark_IsUUID3-4                        | 2000000   | 783 ns/op  | 0 B/op    | 0 allocs/op  |
+| Benchmark_IsUUID4-4                        | 2000000   | 899 ns/op  | 0 B/op    | 0 allocs/op  |
+| Benchmark_IsUUID5-4                        | 2000000   | 828 ns/op  | 0 B/op    | 0 allocs/op  |
+| BenchmarkRoller_Start-4                    | 200000    | 6869 ns/op | 2467 B/op | 28 allocs/op |
+| Benchmark_isContainRequiredField-4         | 300000000 | 4.23 ns/op | 0 B/op    | 0 allocs/op  |
+| Benchmark_Validate-4                       | 200000    | 9347 ns/op | 664 B/op  | 28 allocs/op |
diff --git a/validationmdl/validationcore/doc/CUSTOM_RULE.md b/validationmdl/validationcore/doc/CUSTOM_RULE.md
new file mode 100644
index 0000000000000000000000000000000000000000..f8c4ab266c01111373375f65e0ca6fba1ebf659c
--- /dev/null
+++ b/validationmdl/validationcore/doc/CUSTOM_RULE.md
@@ -0,0 +1,86 @@
+
+### Validate with custom rule
+
+You can register custom validation rules. This rule will work for both `Validate` and `ValidateJSON` method. You will get all the information you need to validate an input.
+
+```go
+package main
+
+import (
+	"encoding/json"
+	"errors"
+	"fmt"
+	"net/http"
+	"strconv"
+	"strings"
+
+	"github.com/thedevsaddam/govalidator"
+)
+
+func init() {
+	// custom rules to take fixed length word.
+	// e.g: max_word:5 will throw error if the field contains more than 5 words
+	govalidator.AddCustomRule("max_word", func(field string, rule string, message string, value interface{}) error {
+		valSlice := strings.Fields(value.(string))
+		l, _ := strconv.Atoi(strings.TrimPrefix(rule, "max_word:")) //handle other error
+		if len(valSlice) > l {
+			if message != "" {
+				return errors.New(message)
+			}
+			return fmt.Errorf("The %s field must not be greater than %d words", field, l)
+		}
+		return nil
+	})
+}
+
+type article struct {
+	Title string   `json:"title"`
+	Body  string   `json:"body"`
+	Tags  []string `json:"tags"`
+}
+
+func handler(w http.ResponseWriter, r *http.Request) {
+	var article article
+	rules := govalidator.MapData{
+		"title": []string{"between:10,120"},
+		"body":  []string{"max_word:150"}, // using custom rule max_word
+		"tags":  []string{"between:3,5"},
+	}
+
+	opts := govalidator.Options{
+		Request:         r,
+		Data:            &article,
+		Rules:           rules,
+		RequiredDefault: true, //force user to fill all the inputs
+	}
+
+	v := govalidator.New(opts)
+	e := v.ValidateJSON()
+	err := map[string]interface{}{"validationError": e}
+	w.Header().Set("Content-type", "applciation/json")
+	json.NewEncoder(w).Encode(err)
+}
+
+func main() {
+	http.HandleFunc("/", handler)
+	fmt.Println("Listening on port: 9000")
+	http.ListenAndServe(":9000", nil)
+}
+
+```
+***Resposne***
+```json
+{
+    "validationError": {
+        "body": [
+            "The body field must not be greater than 150 words"
+        ],
+        "tags": [
+            "The tags field must be between 3 and 5"
+        ],
+        "title": [
+            "The title field must be between 10 and 120"
+        ]
+    }
+}
+```
diff --git a/validationmdl/validationcore/doc/FILE_VALIDATION.md b/validationmdl/validationcore/doc/FILE_VALIDATION.md
new file mode 100644
index 0000000000000000000000000000000000000000..55e68d128db3e88da4b9874a9fb3e80aa26a3408
--- /dev/null
+++ b/validationmdl/validationcore/doc/FILE_VALIDATION.md
@@ -0,0 +1,67 @@
+
+### Validate File
+
+For `multipart/form-data` validation, use `file:` prefix to _field_ name which contains the file. If use custom message then also use the `file:` prefix to Messages MapData key.
+
+```go
+package main
+
+import (
+	"encoding/json"
+	"fmt"
+	"net/http"
+
+	"github.com/thedevsaddam/govalidator"
+)
+
+func handler(w http.ResponseWriter, r *http.Request) {
+	rules := govalidator.MapData{
+		"file:photo": []string{"ext:jpg,png", "size:10000", "mime:jpg,png", "required"},
+	}
+
+	messages := govalidator.MapData{
+			"file:photo": []string{"ext:Only jpg/png is allowed", "required:Photo is required"},
+	}
+
+	opts := govalidator.Options{
+		Request: r,     // request object
+		Rules:   rules, // rules map,
+		Messages: messages,
+	}
+	v := govalidator.New(opts)
+	e := v.Validate()
+	err := map[string]interface{}{"validationError": e}
+	w.Header().Set("Content-type", "applciation/json")
+	json.NewEncoder(w).Encode(err)
+}
+
+func main() {
+	http.HandleFunc("/", handler)
+	fmt.Println("Listening on port: 9000")
+	http.ListenAndServe(":9000", nil)
+}
+
+```
+***Resposne***
+```json
+{
+    "validationError": {
+        "photo": [
+            "Photo is required"
+        ]
+    }
+}
+
+or
+
+{
+    "validationError": {
+        "photo": [
+            "Only jpg/png is allowed",
+            "The photo field size is can not be greater than 10000 bytes",
+            "The photo field file mime text/plain is invalid"
+        ]
+    }
+}
+```
+Note: At this time it can validate only single file.
diff --git a/validationmdl/validationcore/doc/MAP_VALIDATION.md b/validationmdl/validationcore/doc/MAP_VALIDATION.md
new file mode 100644
index 0000000000000000000000000000000000000000..e3e0c505a83e041845af6b63819d3d2e2625d78d
--- /dev/null
+++ b/validationmdl/validationcore/doc/MAP_VALIDATION.md
@@ -0,0 +1,85 @@
+### Validate JSON body into Map
+
+When using ValidateJSON you must provide data struct or map, rules and request. You can also pass message rules if you need custom message or localization.
+
+```go
+package main
+
+import (
+	"encoding/json"
+	"fmt"
+	"net/http"
+
+	"github.com/thedevsaddam/govalidator"
+)
+
+func handler(w http.ResponseWriter, r *http.Request) {
+	rules := govalidator.MapData{
+		"username": []string{"required", "between:3,5"},
+		"email":    []string{"required", "min:4", "max:20", "email"},
+		"web":      []string{"url"},
+		"age":      []string{"numeric_between:18,56"},
+	}
+
+	data := make(map[string]interface{}, 0)
+
+	opts := govalidator.Options{
+		Request: r,
+		Rules:   rules,
+		Data:    &data,
+	}
+
+	vd := govalidator.New(opts)
+	e := vd.ValidateJSON()
+	fmt.Println(data)
+	err := map[string]interface{}{"validation error": e}
+	w.Header().Set("Content-type", "applciation/json")
+	json.NewEncoder(w).Encode(err)
+}
+
+func main() {
+	http.HandleFunc("/", handler)
+	fmt.Println("Listening on port: 9000")
+	http.ListenAndServe(":9000", nil)
+}
+
+```
+
+***Resposne***
+```json
+{
+    "validationError": {
+        "age": [
+            "The age field must be between 18 and 56"
+        ],
+        "dob": [
+            "The dob field must be a valid date format. e.g: yyyy-mm-dd, yyyy/mm/dd etc"
+        ],
+        "email": [
+            "The email field is required",
+            "The email field must be a valid email address"
+        ],
+        "phone": [
+            "The phone field must be 11 digits"
+        ],
+        "postalCode": [
+            "The postalCode field must be 4 digits"
+        ],
+        "roles": [
+            "The roles field must be length of 4"
+        ],
+        "username": [
+            "The username field is required",
+            "The username field must be between 3 and 8"
+        ],
+        "village": [
+            "The village field must be between 3 and 10"
+        ],
+        "web": [
+            "The web field format is invalid"
+        ]
+    }
+}
+```
+
+Note: You can pass custom message
diff --git a/validationmdl/validationcore/doc/NESTED_STRUCT.md b/validationmdl/validationcore/doc/NESTED_STRUCT.md
new file mode 100644
index 0000000000000000000000000000000000000000..3425b83a5f4224d6b19fdf4ae6dd27a5f355bb90
--- /dev/null
+++ b/validationmdl/validationcore/doc/NESTED_STRUCT.md
@@ -0,0 +1,95 @@
+
+### Validate JSON body with nested struct and slice
+
+
+```go
+package main
+
+import (
+	"encoding/json"
+	"fmt"
+	"net/http"
+
+	"github.com/thedevsaddam/govalidator"
+)
+
+type (
+	user struct {
+		Username string `json:"username"`
+		Email    string `json:"email"`
+		Web      string `json:"web"`
+		Age      int    `json:"age"`
+		Phone    string `json:"phone"`
+		Agree    bool   `json:"agree"`
+		DOB      string `json:"dob"`
+		Address  address
+		Roles    []string `json:"roles"`
+	}
+
+	address struct {
+		Village    string `json:"village"`
+		PostalCode string `json:"postalCode"`
+	}
+)
+
+func handler(w http.ResponseWriter, r *http.Request) {
+	var usr user
+	rules := govalidator.MapData{
+		"username":   []string{"required", "between:3,8"},
+		"email":      []string{"required", "min:4", "max:20", "email"},
+		"web":        []string{"url"},
+		"age":        []string{"between:18,56"},
+		"phone":      []string{"digits:11"},
+		"agree":      []string{"bool"},
+		"dob":        []string{"date"},
+		"village":    []string{"between:3,10"},
+		"postalCode": []string{"digits:4"},
+		"roles":      []string{"len:4"},
+	}
+	opts := govalidator.Options{
+		Request:         r,     // request object
+		Rules:           rules, // rules map
+		Data:            &usr,
+		RequiredDefault: true, // all the field to be required
+	}
+	v := govalidator.New(opts)
+	e := v.ValidateJSON()
+	fmt.Println(usr)
+	err := map[string]interface{}{"validationError": e}
+	w.Header().Set("Content-type", "applciation/json")
+	json.NewEncoder(w).Encode(err)
+}
+
+func main() {
+	http.HandleFunc("/", handler)
+	fmt.Println("Listening on port: 9000")
+	http.ListenAndServe(":9000", nil)
+}
+
+```
+***Resposne***
+```json
+{
+    "validationError": {
+        "email": [
+            "The email field must be minimum 4 char",
+            "The email field must be a valid email address"
+        ],
+        "phone": [
+            "The phone field must be 11 digits"
+        ],
+        "postalCode": [
+            "The postalCode field must be 4 digits"
+        ],
+        "roles": [
+            "The roles field must be length of 4"
+        ],
+        "village": [
+            "The village field must be between 3 and 10"
+        ],
+        "web": [
+            "The web field format is invalid"
+        ]
+    }
+}
+```
diff --git a/validationmdl/validationcore/doc/SIMPLE_STRUCT_VALIDATION.md b/validationmdl/validationcore/doc/SIMPLE_STRUCT_VALIDATION.md
new file mode 100644
index 0000000000000000000000000000000000000000..be9e8f685ef99dc823c24919060041e532d9a9c2
--- /dev/null
+++ b/validationmdl/validationcore/doc/SIMPLE_STRUCT_VALIDATION.md
@@ -0,0 +1,79 @@
+
+### Validate JSON body into a simple Struct
+
+When using ValidateJSON you must provide data struct or map, rules and request. You can also pass message rules if you need custom message or localization.
+
+```go
+package main
+
+import (
+	"encoding/json"
+	"fmt"
+	"net/http"
+
+	"github.com/thedevsaddam/govalidator"
+)
+
+type user struct {
+	Username string           `json:"username"`
+	Email    string           `json:"email"`
+	Web      string           `json:"web"`
+	Age      govalidator.Int  `json:"age"`
+	Agree    govalidator.Bool `json:"agree"`
+}
+
+func handler(w http.ResponseWriter, r *http.Request) {
+	var user user
+	rules := govalidator.MapData{
+		"username": []string{"required", "between:3,5"},
+		"email":    []string{"required", "min:4", "max:20", "email"},
+		"web":      []string{"url"},
+		"age":      []string{"required"},
+		"agree":    []string{"required"},
+	}
+
+	opts := govalidator.Options{
+		Request: r,
+		Data:    &user,
+		Rules:   rules,
+	}
+
+	v := govalidator.New(opts)
+	e := v.ValidateJSON()
+	fmt.Println(user) // your incoming JSON data in Go data struct
+	err := map[string]interface{}{"validationError": e}
+	w.Header().Set("Content-type", "applciation/json")
+	json.NewEncoder(w).Encode(err)
+}
+
+func main() {
+	http.HandleFunc("/", handler)
+	fmt.Println("Listening on port: 9000")
+	http.ListenAndServe(":9000", nil)
+}
+
+```
+***Resposne***
+```json
+{
+    "validationError": {
+        "age": [
+            "The age field is required"
+        ],
+        "agree": [
+            "The agree field is required"
+        ],
+        "email": [
+            "The email field is required",
+            "The email field must be minimum 4 char",
+            "The email field must be a valid email address"
+        ],
+        "username": [
+            "The username field is required",
+            "The username field must be between 3 and 5"
+        ]
+    }
+}
+```
+
+#### Note: When using `required` rule with number or boolean data, use provided custom type like: Int, Int64, Float32, Float64 or Bool
diff --git a/validationmdl/validationcore/errors.go b/validationmdl/validationcore/errors.go
new file mode 100644
index 0000000000000000000000000000000000000000..dd96b3a01ee1e23ab95287cf8ac09d456a602ca0
--- /dev/null
+++ b/validationmdl/validationcore/errors.go
@@ -0,0 +1,11 @@
+package govalidator
+
+import "errors"
+
+var (
+	errStringToInt          = errors.New("govalidator: unable to parse string to integer")
+	errStringToFloat        = errors.New("govalidator: unable to parse string to float")
+	errValidateArgsMismatch = errors.New("govalidator: provide at least *http.Request and rules for Validate method")
+	errInvalidArgument      = errors.New("govalidator: invalid number of argument")
+	errRequirePtr           = errors.New("govalidator: provide pointer to the data structure")
+)
diff --git a/validationmdl/validationcore/helper.go b/validationmdl/validationcore/helper.go
new file mode 100644
index 0000000000000000000000000000000000000000..e4b3f1f99a4067add71269ae1a1c0a937a14f8bf
--- /dev/null
+++ b/validationmdl/validationcore/helper.go
@@ -0,0 +1,152 @@
+package govalidator
+
+import (
+	"encoding/json"
+	"regexp"
+)
+
+// isAlpha check the input is letters (a-z,A-Z) or not
+func isAlpha(str string) bool {
+	return regexAlpha.MatchString(str)
+}
+
+// isAlphaDash check the input is letters, number with dash and underscore
+func isAlphaDash(str string) bool {
+	return regexAlphaDash.MatchString(str)
+}
+
+// isAlphaNumeric check the input is alpha numeric or not
+func isAlphaNumeric(str string) bool {
+	return regexAlphaNumeric.MatchString(str)
+}
+
+// isBoolean check the input contains boolean type values
+// in this case: "0", "1", "true", "false", "True", "False"
+func isBoolean(str string) bool {
+	bools := []string{"0", "1", "true", "false", "True", "False"}
+	for _, b := range bools {
+		if b == str {
+			return true
+		}
+	}
+	return false
+}
+
+//isCreditCard check the provided card number is a valid
+//  Visa, MasterCard, American Express, Diners Club, Discover or JCB card
+func isCreditCard(card string) bool {
+	return regexCreditCard.MatchString(card)
+}
+
+// isCoordinate is a valid Coordinate or not
+func isCoordinate(str string) bool {
+	return regexCoordinate.MatchString(str)
+}
+
+// isCSSColor is a valid CSS color value (hex, rgb, rgba, hsl, hsla) etc like #909, #00aaff, rgb(255,122,122)
+func isCSSColor(str string) bool {
+	return regexCSSColor.MatchString(str)
+}
+
+// isDate check the date string is valid or not
+func isDate(date string) bool {
+	return regexDate.MatchString(date)
+}
+
+// isDateDDMMYY check the date string is valid or not
+func isDateDDMMYY(date string) bool {
+	return regexDateDDMMYY.MatchString(date)
+}
+
+// isEmail check a email is valid or not
+func isEmail(email string) bool {
+	return regexEmail.MatchString(email)
+}
+
+// isFloat check the input string is a float or not
+func isFloat(str string) bool {
+	return regexFloat.MatchString(str)
+}
+
+// isIn check if the niddle exist in the haystack
+func isIn(haystack []string, niddle string) bool {
+	for _, h := range haystack {
+		if h == niddle {
+			return true
+		}
+	}
+	return false
+}
+
+// isJSON check wheather the input string is a valid json or not
+func isJSON(str string) bool {
+	var data interface{}
+	if err := json.Unmarshal([]byte(str), &data); err != nil {
+		return false
+	}
+	return true
+}
+
+// isNumeric check the provided input string is numeric or not
+func isNumeric(str string) bool {
+	return regexNumeric.MatchString(str)
+}
+
+// isLatitude check the provided input string is a valid latitude or not
+func isLatitude(str string) bool {
+	return regexLatitude.MatchString(str)
+}
+
+// isLongitude check the provided input string is a valid longitude or not
+func isLongitude(str string) bool {
+	return regexLongitude.MatchString(str)
+}
+
+// isIP check the provided input string is a valid IP address or not
+func isIP(str string) bool {
+	return regexIP.MatchString(str)
+}
+
+// isIPV4 check the provided input string is a valid IP address version 4 or not
+// Ref: https://en.wikipedia.org/wiki/IPv4
+func isIPV4(str string) bool {
+	return regexIPV4.MatchString(str)
+}
+
+// isIPV6 check the provided input string is a valid IP address version 6 or not
+// Ref: https://en.wikipedia.org/wiki/IPv6
+func isIPV6(str string) bool {
+	return regexIPV6.MatchString(str)
+}
+
+// isMatchedRegex match the regular expression string provided in first argument
+// with second argument which is also a string
+func isMatchedRegex(rxStr, str string) bool {
+	rx := regexp.MustCompile(rxStr)
+	return rx.MatchString(str)
+}
+
+// isURL check a URL is valid or not
+func isURL(url string) bool {
+	return regexURL.MatchString(url)
+}
+
+// isUUID check the provided string is valid UUID or not
+func isUUID(str string) bool {
+	return regexUUID.MatchString(str)
+}
+
+// isUUID3 check the provided string is valid UUID version 3 or not
+func isUUID3(str string) bool {
+	return regexUUID3.MatchString(str)
+}
+
+// isUUID4 check the provided string is valid UUID version 4 or not
+func isUUID4(str string) bool {
+	return regexUUID4.MatchString(str)
+}
+
+// isUUID5 check the provided string is valid UUID version 5 or not
+func isUUID5(str string) bool {
+	return regexUUID5.MatchString(str)
+}
diff --git a/validationmdl/validationcore/helper_test.go b/validationmdl/validationcore/helper_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..abe98ecf6bcf225d8bb845c227972f85c014ec64
--- /dev/null
+++ b/validationmdl/validationcore/helper_test.go
@@ -0,0 +1,466 @@
+package govalidator
+
+import "testing"
+
+type inputs map[string]bool
+
+var (
+	_alpha = inputs{
+		"abcdefghijgklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ": true,
+		"7877**": false,
+		"abc":    true,
+		")(^%&)": false,
+	}
+	_alphaDash = inputs{
+		"abcdefghijgklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-": true,
+		"John_Do-E": true,
+		"+=a(0)":    false,
+	}
+	_alphaNumeric = inputs{
+		"abcdefghijgklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890": true,
+		"090a": true,
+		"*&*)": false,
+	}
+	_boolStringsList = inputs{
+		"0":     true,
+		"1":     true,
+		"true":  true,
+		"false": true,
+		"o":     false,
+		"a":     false,
+	}
+	// Ref: https://www.freeformatter.com/credit-card-number-generator-validator.html
+	_creditCardList = inputs{
+		"4896644531043572": true,
+		"2221005631780408": true,
+		"349902515380498":  true,
+		"6011843157272458": true,
+		"3543358904915048": true,
+		"5404269782892303": true,
+		"4508168417293390": true,
+		"0604595245598387": false,
+		"6388244169973297": false,
+	}
+	_coordinateList = inputs{
+		"30.297018,-78.486328": true,
+		"40.044438,-104.0625":  true,
+		"58.068581,-99.580078": true,
+		"abc, xyz":             false,
+		"0, 887":               false,
+	}
+	_cssColorList = inputs{
+		"#000":           true,
+		"#00aaff":        true,
+		"rgb(123,32,12)": true,
+		"#0":             false,
+		"#av":            false,
+	}
+	_dateList = inputs{
+		"2016-10-14": true,
+		"2013/02/18": true,
+		"2020/12/30": true,
+		"0001/14/30": false,
+	}
+	_dateDDMMYYList = inputs{
+		"01-01-2000": true,
+		"28/02/2001": true,
+		"01/12/2000": true,
+		"2012/11/30": false,
+		"201/11/30":  false,
+	}
+	_emailList = inputs{
+		"john@example.com":       true,
+		"thedevsaddam@gmail.com": true,
+		"jane@yahoo.com":         true,
+		"janeahoo.com":           false,
+		"janea@.com":             false,
+	}
+	_floatList         = inputs{"123": true, "12.50": true, "33.07": true, "abc": false, "o0.45": false}
+	_roleList          = []string{"admin", "manager", "supervisor"}
+	_validJSONString   = `{"FirstName": "Bob", "LastName": "Smith"}`
+	_invalidJSONString = `{"invalid json"}`
+	_numericStringList = inputs{"12": true, "09": true, "878": true, "100": true, "a": false, "xyz": false}
+	_latList           = inputs{"30.297018": true, "40.044438": true, "a": false, "xyz": false}
+	_lonList           = inputs{"-78.486328": true, "-104.0625": true, "a": false, "xyz": false}
+	_ipList            = inputs{"10.255.255.255": true, "172.31.255.255": true, "192.168.255.255": true, "a92.168.255.255": false, "172.31.255.25b": false}
+	_ipV6List          = inputs{
+		"1200:0000:AB00:1234:0000:2552:7777:1313": true,
+		"21DA:D3:0:2F3B:2AA:FF:FE28:9C5A":         true,
+		"10.255.255.255":                          false,
+	}
+	_urlList = inputs{
+		"http://www.google.com":  true,
+		"https://www.google.com": true,
+		"https://facebook.com":   true,
+		"yahoo.com":              true,
+		"adca":                   false,
+	}
+	_uuidList = inputs{
+		"ee7cf0a0-1922-401b-a1ae-6ec9261484c0": true,
+		"ee7cf0a0-1922-401b-a1ae-6ec9261484c1": true,
+		"ee7cf0a0-1922-401b-a1ae-6ec9261484a0": true,
+		"39888f87-fb62-5988-a425-b2ea63f5b81e": false,
+	}
+	_uuidV3List = inputs{
+		"a987fbc9-4bed-3078-cf07-9141ba07c9f3": true,
+		"b987fbc9-4bed-3078-cf07-9141ba07c9f3": true,
+		"ee7cf0a0-1922-401b-a1ae-6ec9261484c0": false,
+	}
+	_uuidV4List = inputs{
+		"df7cca36-3d7a-40f4-8f06-ae03cc22f045": true,
+		"ef7cca36-3d7a-40f4-8f06-ae03cc22f048": true,
+		"b987fbc9-4bed-3078-cf07-9141ba07c9f3": false,
+	}
+	_uuidV5List = inputs{
+		"39888f87-fb62-5988-a425-b2ea63f5b81e": true,
+		"33388f87-fb62-5988-a425-b2ea63f5b81f": true,
+		"b987fbc9-4bed-3078-cf07-9141ba07c9f3": false,
+	}
+)
+
+func Test_IsAlpha(t *testing.T) {
+	for a, s := range _alpha {
+		if isAlpha(a) != s {
+			t.Error("IsAlpha failed to determine alpha!")
+		}
+	}
+}
+
+func Benchmark_IsAlpha(b *testing.B) {
+	for n := 0; n < b.N; n++ {
+		isAlpha("abcdAXZY")
+	}
+}
+
+func Test_IsAlphaDash(t *testing.T) {
+	for a, s := range _alphaDash {
+		if isAlphaDash(a) != s {
+			t.Error("IsAlphaDash failed to determine alpha dash!")
+		}
+	}
+}
+
+func Benchmark_IsAlphaDash(b *testing.B) {
+	for n := 0; n < b.N; n++ {
+		isAlphaDash("John_Do-E")
+	}
+}
+
+func Test_IsAlphaNumeric(t *testing.T) {
+	for a, s := range _alphaNumeric {
+		if isAlphaNumeric(a) != s {
+			t.Error("IsAlphaNumeric failed to determine alpha numeric!")
+		}
+	}
+}
+
+func Benchmark_IsAlphaNumeric(b *testing.B) {
+	for n := 0; n < b.N; n++ {
+		isAlphaNumeric("abc12AZ")
+	}
+}
+
+func Test_IsBoolean(t *testing.T) {
+	for b, s := range _boolStringsList {
+		if isBoolean(b) != s {
+			t.Error("IsBoolean failed to determine boolean!")
+		}
+	}
+}
+
+func Benchmark_IsBoolean(b *testing.B) {
+	for n := 0; n < b.N; n++ {
+		isBoolean("true")
+	}
+}
+
+func Test_IsCreditCard(t *testing.T) {
+	for card, state := range _creditCardList {
+		if isCreditCard(card) != state {
+			t.Error("IsCreditCard failed to determine credit card!")
+		}
+	}
+}
+
+func Benchmark_IsCreditCard(b *testing.B) {
+	for n := 0; n < b.N; n++ {
+		isCreditCard("2221005631780408")
+	}
+}
+
+func Test_IsCoordinate(t *testing.T) {
+	for c, s := range _coordinateList {
+		if isCoordinate(c) != s {
+			t.Error("IsCoordinate failed to determine coordinate!")
+		}
+	}
+}
+
+func Benchmark_IsCoordinate(b *testing.B) {
+	for n := 0; n < b.N; n++ {
+		isCoordinate("30.297018,-78.486328")
+	}
+}
+
+func Test_IsCSSColor(t *testing.T) {
+	for c, s := range _cssColorList {
+		if isCSSColor(c) != s {
+			t.Error("IsCSSColor failed to determine css color code!")
+		}
+	}
+}
+
+func Benchmark_IsCSSColor(b *testing.B) {
+	for n := 0; n < b.N; n++ {
+		isCSSColor("#00aaff")
+	}
+}
+
+func Test_IsDate(t *testing.T) {
+	for d, s := range _dateList {
+		if isDate(d) != s {
+			t.Error("IsDate failed to determine date!")
+		}
+	}
+}
+
+func Benchmark_IsDate(b *testing.B) {
+	for n := 0; n < b.N; n++ {
+		isDate("2016-10-14")
+	}
+}
+
+func Test_IsDateDDMMYY(t *testing.T) {
+	for d, s := range _dateDDMMYYList {
+		if isDateDDMMYY(d) != s {
+			t.Error("IsDateDDMMYY failed to determine date!")
+		}
+	}
+}
+
+func Benchmark_IsDateDDMMYY(b *testing.B) {
+	for n := 0; n < b.N; n++ {
+		isDateDDMMYY("23-10-2014")
+	}
+}
+
+func Test_IsEmail(t *testing.T) {
+	for e, s := range _emailList {
+		if isEmail(e) != s {
+			t.Error("IsEmail failed to determine email!")
+		}
+	}
+}
+
+func Benchmark_IsEmail(b *testing.B) {
+	for n := 0; n < b.N; n++ {
+		isEmail("thedevsaddam@gmail.com")
+	}
+}
+
+func Test_IsFloat(t *testing.T) {
+	for f, s := range _floatList {
+		if isFloat(f) != s {
+			t.Error("IsFloat failed to determine float value!")
+		}
+	}
+}
+
+func Benchmark_IsFloat(b *testing.B) {
+	for n := 0; n < b.N; n++ {
+		isFloat("123.001")
+	}
+}
+
+func Test_IsIn(t *testing.T) {
+	if !isIn(_roleList, "admin") {
+		t.Error("IsIn failed!")
+	}
+}
+
+func Benchmark_IsIn(b *testing.B) {
+	for n := 0; n < b.N; n++ {
+		isIn(_roleList, "maager")
+	}
+}
+
+func Test_IsJSON(t *testing.T) {
+	if !isJSON(_validJSONString) {
+		t.Error("IsJSON failed!")
+	}
+	if isJSON(_invalidJSONString) {
+		t.Error("IsJSON unable to detect invalid json!")
+	}
+}
+
+func Benchmark_IsJSON(b *testing.B) {
+	for n := 0; n < b.N; n++ {
+		isJSON(_validJSONString)
+	}
+}
+
+func Test_IsNumeric(t *testing.T) {
+	for n, s := range _numericStringList {
+		if isNumeric(n) != s {
+			t.Error("IsNumeric failed!")
+		}
+	}
+}
+
+func Benchmark_IsNumeric(b *testing.B) {
+	for n := 0; n < b.N; n++ {
+		isNumeric("123")
+	}
+}
+
+func Test_IsLatitude(t *testing.T) {
+	for n, s := range _latList {
+		if isLatitude(n) != s {
+			t.Error("IsLatitude failed!")
+		}
+	}
+}
+
+func Benchmark_IsLatitude(b *testing.B) {
+	for n := 0; n < b.N; n++ {
+		isLatitude("30.297018")
+	}
+}
+
+func Test_IsLongitude(t *testing.T) {
+	for n, s := range _lonList {
+		if isLongitude(n) != s {
+			t.Error("IsLongitude failed!")
+		}
+	}
+}
+
+func Benchmark_IsLongitude(b *testing.B) {
+	for n := 0; n < b.N; n++ {
+		isLongitude("-78.486328")
+	}
+}
+
+func Test_IsIP(t *testing.T) {
+	for i, s := range _ipList {
+		if isIP(i) != s {
+			t.Error("IsIP failed!")
+		}
+	}
+}
+
+func Benchmark_IsIP(b *testing.B) {
+	for n := 0; n < b.N; n++ {
+		isIP("10.255.255.255")
+	}
+}
+
+func Test_IsIPV4(t *testing.T) {
+	for i, s := range _ipList {
+		if isIPV4(i) != s {
+			t.Error("IsIPV4 failed!")
+		}
+	}
+}
+
+func Benchmark_IsIPV4(b *testing.B) {
+	for n := 0; n < b.N; n++ {
+		isIPV4("10.255.255.255")
+	}
+}
+
+func Test_IsIPV6(t *testing.T) {
+	for i, s := range _ipV6List {
+		if isIPV6(i) != s {
+			t.Error("IsIPV4 failed!")
+		}
+	}
+}
+
+func Benchmark_IsIPV6(b *testing.B) {
+	for n := 0; n < b.N; n++ {
+		isIPV6("10.255.255.255")
+	}
+}
+
+func Test_IsMatchedRegex(t *testing.T) {
+	if !isMatchedRegex("^(name|age)$", "name") {
+		t.Error("IsMatchedRegex failed!")
+	}
+}
+
+func Benchmark_IsMatchedRegex(b *testing.B) {
+	for n := 0; n < b.N; n++ {
+		isMatchedRegex("^(name|age)$", "name")
+	}
+}
+
+func Test_IsURL(t *testing.T) {
+	for u, s := range _urlList {
+		if isURL(u) != s {
+			t.Error("IsURL failed!")
+		}
+	}
+}
+
+func Benchmark_IsURL(b *testing.B) {
+	for n := 0; n < b.N; n++ {
+		isURL("https://www.facebook.com")
+	}
+}
+
+func Test_IsUUID(t *testing.T) {
+	for u, s := range _uuidList {
+		if isUUID(u) != s {
+			t.Error("IsUUID failed!")
+		}
+	}
+}
+
+func Benchmark_IsUUID(b *testing.B) {
+	for n := 0; n < b.N; n++ {
+		isUUID("ee7cf0a0-1922-401b-a1ae-6ec9261484c0")
+	}
+}
+
+func Test_IsUUID3(t *testing.T) {
+	for u, s := range _uuidV3List {
+		if isUUID3(u) != s {
+			t.Error("IsUUID3 failed!")
+		}
+	}
+}
+
+func Benchmark_IsUUID3(b *testing.B) {
+	for n := 0; n < b.N; n++ {
+		isUUID3("a987fbc9-4bed-3078-cf07-9141ba07c9f3")
+	}
+}
+
+func Test_IsUUID4(t *testing.T) {
+	for u, s := range _uuidV4List {
+		if isUUID4(u) != s {
+			t.Error("IsUUID4 failed!")
+		}
+	}
+}
+
+func Benchmark_IsUUID4(b *testing.B) {
+	for n := 0; n < b.N; n++ {
+		isUUID4("57b73598-8764-4ad0-a76a-679bb6640eb1")
+	}
+}
+
+func Test_IsUUID5(t *testing.T) {
+	for u, s := range _uuidV5List {
+		if isUUID5(u) != s {
+			t.Error("IsUUID5 failed!")
+		}
+	}
+}
+
+func Benchmark_IsUUID5(b *testing.B) {
+	for n := 0; n < b.N; n++ {
+		isUUID5("987fbc97-4bed-5078-9f07-9141ba07c9f3")
+	}
+}
diff --git a/validationmdl/validationcore/regex_patterns.go b/validationmdl/validationcore/regex_patterns.go
new file mode 100644
index 0000000000000000000000000000000000000000..bdb5f2b4f0e937daed3b2c583b98d6cb9a5124e5
--- /dev/null
+++ b/validationmdl/validationcore/regex_patterns.go
@@ -0,0 +1,74 @@
+package govalidator
+
+import (
+	"regexp"
+)
+
+const (
+	// Alpha represents regular expression for alpha chartacters
+	Alpha string = "^[a-zA-Z]+$"
+	// AlphaDash represents regular expression for alpha chartacters with underscore and ash
+	AlphaDash string = "^[a-zA-Z0-9_-]+$"
+	// AlphaNumeric represents regular expression for alpha numeric chartacters
+	AlphaNumeric string = "^[a-zA-Z0-9]+$"
+	// CreditCard represents regular expression for credit cards like (Visa, MasterCard, American Express, Diners Club, Discover, and JCB cards). Ref: https://stackoverflow.com/questions/9315647/regex-credit-card-number-tests
+	CreditCard string = "^(?:4[0-9]{12}(?:[0-9]{3})?|[25][1-7][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\\d{3})\\d{11})$"
+	// Coordinate represents latitude and longitude regular expression
+	Coordinate string = "^[-+]?([1-8]?\\d(\\.\\d+)?|90(\\.0+)?),\\s*[-+]?(180(\\.0+)?|((1[0-7]\\d)|([1-9]?\\d))(\\.\\d+)?)$" // Ref: https://stackoverflow.com/questions/3518504/regular-expression-for-matching-latitude-longitude-coordinates
+	// CSSColor represents css valid color code with hex, rgb, rgba, hsl, hsla etc. Ref: http://www.regexpal.com/97509
+	CSSColor string = "^(#([\\da-f]{3}){1,2}|(rgb|hsl)a\\((\\d{1,3}%?,\\s?){3}(1|0?\\.\\d+)\\)|(rgb|hsl)\\(\\d{1,3}%?(,\\s?\\d{1,3}%?){2}\\))$"
+	// Date represents regular expression for valid date like: yyyy-mm-dd
+	Date string = "^(((19|20)([2468][048]|[13579][26]|0[48])|2000)[/-]02[/-]29|((19|20)[0-9]{2}[/-](0[469]|11)[/-](0[1-9]|[12][0-9]|30)|(19|20)[0-9]{2}[/-](0[13578]|1[02])[/-](0[1-9]|[12][0-9]|3[01])|(19|20)[0-9]{2}[/-]02[/-](0[1-9]|1[0-9]|2[0-8])))$"
+	// DateDDMMYY represents regular expression for valid date of format dd/mm/yyyy , dd-mm-yyyy etc.Ref: http://regexr.com/346hf
+	DateDDMMYY string = "^(0?[1-9]|[12][0-9]|3[01])[\\/\\-](0?[1-9]|1[012])[\\/\\-]\\d{4}$"
+	// Email represents regular expression for email
+	Email string = "^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+$"
+	// Float represents regular expression for finding fload number
+	Float string = "^[+-]?([0-9]*[.])?[0-9]+$"
+	// IP represents regular expression for ip address
+	IP string = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"
+	// IPV4 represents regular expression for ip address version 4
+	IPV4 string = "^([0-9]{1,3}\\.){3}[0-9]{1,3}(\\/([0-9]|[1-2][0-9]|3[0-2]))?$"
+	// IPV6 represents regular expression for ip address version 6
+	IPV6 string = `^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*(\/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8]))?$`
+	// Latitude represents latitude regular expression
+	Latitude string = "^(\\+|-)?(?:90(?:(?:\\.0{1,6})?)|(?:[0-9]|[1-8][0-9])(?:(?:\\.[0-9]{1,6})?))$"
+	// Longitude represents longitude regular expression
+	Longitude string = "^(\\+|-)?(?:180(?:(?:\\.0{1,6})?)|(?:[0-9]|[1-9][0-9]|1[0-7][0-9])(?:(?:\\.[0-9]{1,6})?))$"
+	// Numeric represents regular expression for numeric
+	Numeric string = "^[0-9]+$"
+	// URL represents regular expression for url
+	URL string = "^(?:http(s)?:\\/\\/)?[\\w.-]+(?:\\.[\\w\\.-]+)+[\\w\\-\\._~:/?#[\\]@!\\$&'\\(\\)\\*\\+,;=.]+$" // Ref: https://stackoverflow.com/questions/136505/searching-for-uuids-in-text-with-regex
+	// UUID represents regular expression for UUID
+	UUID string = "^[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89aAbB][a-f0-9]{3}-[a-f0-9]{12}$"
+	// UUID3 represents regular expression for UUID version 3
+	UUID3 string = "^[0-9a-f]{8}-[0-9a-f]{4}-3[0-9a-f]{3}-[0-9a-f]{4}-[0-9a-f]{12}$"
+	// UUID4 represents regular expression for UUID version 4
+	UUID4 string = "^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
+	// UUID5 represents regular expression for UUID version 5
+	UUID5 string = "^[0-9a-f]{8}-[0-9a-f]{4}-5[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
+)
+
+var (
+	regexAlpha        = regexp.MustCompile(Alpha)
+	regexAlphaDash    = regexp.MustCompile(AlphaDash)
+	regexAlphaNumeric = regexp.MustCompile(AlphaNumeric)
+	regexCreditCard   = regexp.MustCompile(CreditCard)
+	regexCoordinate   = regexp.MustCompile(Coordinate)
+	regexCSSColor     = regexp.MustCompile(CSSColor)
+	regexDate         = regexp.MustCompile(Date)
+	regexDateDDMMYY   = regexp.MustCompile(DateDDMMYY)
+	regexEmail        = regexp.MustCompile(Email)
+	regexFloat        = regexp.MustCompile(Float)
+	regexNumeric      = regexp.MustCompile(Numeric)
+	regexLatitude     = regexp.MustCompile(Latitude)
+	regexLongitude    = regexp.MustCompile(Longitude)
+	regexIP           = regexp.MustCompile(IP)
+	regexIPV4         = regexp.MustCompile(IPV4)
+	regexIPV6         = regexp.MustCompile(IPV6)
+	regexURL          = regexp.MustCompile(URL)
+	regexUUID         = regexp.MustCompile(UUID)
+	regexUUID3        = regexp.MustCompile(UUID3)
+	regexUUID4        = regexp.MustCompile(UUID4)
+	regexUUID5        = regexp.MustCompile(UUID5)
+)
diff --git a/validationmdl/validationcore/roller.go b/validationmdl/validationcore/roller.go
new file mode 100644
index 0000000000000000000000000000000000000000..a200f0451585124422da3dcddee2998fbb3acb04
--- /dev/null
+++ b/validationmdl/validationcore/roller.go
@@ -0,0 +1,300 @@
+package govalidator
+
+import (
+	"reflect"
+	"strings"
+)
+
+// ROADMAP
+// traverse map or struct
+// detect each type
+// if type is struct or map then traverse it
+// if type is not struct or map then just push them in parent map's key as key and value of it
+// make flatten all the type in map[string]interface{}
+// in this case mapWalker will do the task
+
+// roller represents a roller type that will be used to flatten our data in a map[string]interface{}
+type roller struct {
+	root          map[string]interface{}
+	typeName      string
+	tagIdentifier string
+	tagSeparator  string
+}
+
+// start start traversing through the tree
+func (r *roller) start(iface interface{}) {
+	//initialize the Tree
+	r.root = make(map[string]interface{})
+	r.typeName = ""
+	ifv := reflect.ValueOf(iface)
+	ift := reflect.TypeOf(iface)
+	if ift.Kind() == reflect.Ptr {
+		ifv = ifv.Elem()
+		ift = ift.Elem()
+	}
+	canInterface := ifv.CanInterface()
+	//check the provided root elment
+	switch ift.Kind() {
+	case reflect.Struct:
+		if canInterface {
+			r.traverseStruct(ifv.Interface())
+		}
+	case reflect.Map:
+		if ifv.Len() > 0 {
+			if canInterface {
+				r.traverseMap(ifv.Interface())
+			}
+		}
+	case reflect.Slice:
+		if canInterface {
+			r.push("slice", ifv.Interface())
+		}
+	}
+}
+
+// setTagIdentifier set the struct tag identifier. e.g: json, validate etc
+func (r *roller) setTagIdentifier(i string) {
+	r.tagIdentifier = i
+}
+
+// setTagSeparator set the struct tag separator. e.g: pipe (|) or comma (,)
+func (r *roller) setTagSeparator(s string) {
+	r.tagSeparator = s
+}
+
+// getFlatMap get the all flatten values
+func (r *roller) getFlatMap() map[string]interface{} {
+	return r.root
+}
+
+// getFlatVal return interfac{} value if exist
+func (r *roller) getFlatVal(key string) (interface{}, bool) {
+	var val interface{}
+	var ok bool
+	if val, ok = r.root[key]; ok {
+		return val, ok
+	}
+	return val, ok
+}
+
+// push add value to map if key does not exist
+func (r *roller) push(key string, val interface{}) bool {
+	if _, ok := r.root[key]; ok {
+		return false
+	}
+	r.root[key] = val
+	return true
+}
+
+// traverseStruct through all structs and add it to root
+func (r *roller) traverseStruct(iface interface{}) {
+	ifv := reflect.ValueOf(iface)
+	ift := reflect.TypeOf(iface)
+
+	if ift.Kind() == reflect.Ptr {
+		ifv = ifv.Elem()
+		ift = ift.Elem()
+	}
+
+	for i := 0; i < ift.NumField(); i++ {
+		v := ifv.Field(i)
+		rfv := ift.Field(i)
+
+		switch v.Kind() {
+		case reflect.Struct:
+			var typeName string
+			if len(rfv.Tag.Get(r.tagIdentifier)) > 0 {
+				tags := strings.Split(rfv.Tag.Get(r.tagIdentifier), r.tagSeparator)
+				if tags[0] != "-" {
+					typeName = tags[0]
+				}
+			} else {
+				typeName = rfv.Name
+			}
+			if v.CanInterface() {
+				switch v.Type().String() {
+				case "govalidator.Int":
+					r.push(typeName, v.Interface())
+				case "govalidator.Int64":
+					r.push(typeName, v.Interface())
+				case "govalidator.Float32":
+					r.push(typeName, v.Interface())
+				case "govalidator.Float64":
+					r.push(typeName, v.Interface())
+				case "govalidator.Bool":
+					r.push(typeName, v.Interface())
+				default:
+					r.typeName = ift.Name()
+					r.traverseStruct(v.Interface())
+				}
+			}
+		case reflect.Map:
+			if v.CanInterface() {
+				r.traverseMap(v.Interface())
+			}
+		case reflect.Ptr: // if the field inside struct is Ptr then get the type and underlying values as interface{}
+			ptrReflectionVal := reflect.Indirect(v)
+			if !isEmpty(ptrReflectionVal) {
+				ptrField := ptrReflectionVal.Type()
+				switch ptrField.Kind() {
+				case reflect.Struct:
+					if v.CanInterface() {
+						r.traverseStruct(v.Interface())
+					}
+				case reflect.Map:
+					if v.CanInterface() {
+						r.traverseMap(v.Interface())
+					}
+				}
+			}
+		default:
+			if len(rfv.Tag.Get(r.tagIdentifier)) > 0 {
+				tags := strings.Split(rfv.Tag.Get(r.tagIdentifier), r.tagSeparator)
+				// add if first tag is not hyphen
+				if tags[0] != "-" {
+					if v.CanInterface() {
+						r.push(tags[0], v.Interface())
+					}
+				}
+			} else {
+				if v.Kind() == reflect.Ptr {
+					if ifv.CanInterface() {
+						r.push(ift.Name()+"."+rfv.Name, ifv.Interface())
+					}
+				} else {
+					if v.CanInterface() {
+						r.push(ift.Name()+"."+rfv.Name, v.Interface())
+					}
+				}
+			}
+		}
+	}
+}
+
+// traverseMap through all the map and add it to root
+func (r *roller) traverseMap(iface interface{}) {
+	ifv := reflect.ValueOf(iface)
+	ift := reflect.TypeOf(iface)
+	if ift.Kind() == reflect.Ptr {
+		ifv = ifv.Elem()
+		ift = ift.Elem()
+	}
+
+	switch iface.(type) {
+	case map[string]interface{}:
+		for k, v := range iface.(map[string]interface{}) {
+			switch reflect.TypeOf(v).Kind() {
+			case reflect.Struct:
+				r.typeName = k // set the map key as name
+				r.traverseStruct(v)
+			case reflect.Map:
+				r.typeName = k // set the map key as name
+				r.traverseMap(v)
+			case reflect.Ptr: // if the field inside map is Ptr then get the type and underlying values as interface{}
+				switch reflect.TypeOf(v).Elem().Kind() {
+				case reflect.Struct:
+					r.traverseStruct(v)
+				case reflect.Map:
+					switch v.(type) {
+					case *map[string]interface{}:
+						r.traverseMap(*v.(*map[string]interface{}))
+					case *map[string]string:
+						r.traverseMap(*v.(*map[string]string))
+					case *map[string]bool:
+						r.traverseMap(*v.(*map[string]bool))
+					case *map[string]int:
+						r.traverseMap(*v.(*map[string]int))
+					case *map[string]int8:
+						r.traverseMap(*v.(*map[string]int8))
+					case *map[string]int16:
+						r.traverseMap(*v.(*map[string]int16))
+					case *map[string]int32:
+						r.traverseMap(*v.(*map[string]int32))
+					case *map[string]int64:
+						r.traverseMap(*v.(*map[string]int64))
+					case *map[string]float32:
+						r.traverseMap(*v.(*map[string]float32))
+					case *map[string]float64:
+						r.traverseMap(*v.(*map[string]float64))
+					case *map[string]uint:
+						r.traverseMap(*v.(*map[string]uint))
+					case *map[string]uint8:
+						r.traverseMap(*v.(*map[string]uint8))
+					case *map[string]uint16:
+						r.traverseMap(*v.(*map[string]uint16))
+					case *map[string]uint32:
+						r.traverseMap(*v.(*map[string]uint32))
+					case *map[string]uint64:
+						r.traverseMap(*v.(*map[string]uint64))
+					case *map[string]uintptr:
+						r.traverseMap(*v.(*map[string]uintptr))
+					}
+				default:
+					r.push(k, v.(interface{}))
+				}
+			default:
+				r.push(k, v)
+			}
+		}
+	case map[string]string:
+		for k, v := range iface.(map[string]string) {
+			r.push(k, v)
+		}
+	case map[string]bool:
+		for k, v := range iface.(map[string]bool) {
+			r.push(k, v)
+		}
+	case map[string]int:
+		for k, v := range iface.(map[string]int) {
+			r.push(k, v)
+		}
+	case map[string]int8:
+		for k, v := range iface.(map[string]int8) {
+			r.push(k, v)
+		}
+	case map[string]int16:
+		for k, v := range iface.(map[string]int16) {
+			r.push(k, v)
+		}
+	case map[string]int32:
+		for k, v := range iface.(map[string]int32) {
+			r.push(k, v)
+		}
+	case map[string]int64:
+		for k, v := range iface.(map[string]int64) {
+			r.push(k, v)
+		}
+	case map[string]float32:
+		for k, v := range iface.(map[string]float32) {
+			r.push(k, v)
+		}
+	case map[string]float64:
+		for k, v := range iface.(map[string]float64) {
+			r.push(k, v)
+		}
+	case map[string]uint:
+		for k, v := range iface.(map[string]uint) {
+			r.push(k, v)
+		}
+	case map[string]uint8:
+		for k, v := range iface.(map[string]uint8) {
+			r.push(k, v)
+		}
+	case map[string]uint16:
+		for k, v := range iface.(map[string]uint16) {
+			r.push(k, v)
+		}
+	case map[string]uint32:
+		for k, v := range iface.(map[string]uint32) {
+			r.push(k, v)
+		}
+	case map[string]uint64:
+		for k, v := range iface.(map[string]uint64) {
+			r.push(k, v)
+		}
+	case map[string]uintptr:
+		for k, v := range iface.(map[string]uintptr) {
+			r.push(k, v)
+		}
+	}
+}
diff --git a/validationmdl/validationcore/roller_test.go b/validationmdl/validationcore/roller_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..30e2032bc74c67e6ef0e5e51385383ea2d8e3015
--- /dev/null
+++ b/validationmdl/validationcore/roller_test.go
@@ -0,0 +1,411 @@
+package govalidator
+
+import (
+	"testing"
+)
+
+type Earth struct {
+	Human
+	Name     string
+	Liveable bool
+	Planet   map[string]interface{}
+}
+
+type Human struct {
+	Male
+	Female
+}
+
+type Male struct {
+	Name string
+	Age  int
+}
+
+type Female struct {
+	Name string
+	Age  int
+}
+
+type deepLevel struct {
+	Deep   string
+	Levels map[string]string
+}
+
+type structWithTag struct {
+	Name string `validate:"name"`
+	Age  int    `validate:"age"`
+}
+
+var p = map[string]interface{}{
+	"naam":  "Jane",
+	"bois":  29,
+	"white": true,
+}
+var dl = deepLevel{
+	Deep: "So much deep",
+	Levels: map[string]string{
+		"level 1": "20 m",
+		"level 2": "30 m",
+		"level 3": "80 m",
+		"level 4": "103 m",
+	},
+}
+var planet = map[string]interface{}{
+	"name":      "mars",
+	"age":       1000,
+	"red":       true,
+	"deepLevel": dl,
+	"p":         p,
+}
+var male = Male{"John", 33}
+var female = Female{"Jane", 30}
+var h = Human{
+	male,
+	female,
+}
+var e = Earth{
+	h,
+	"green earth",
+	true,
+	planet,
+}
+
+var m = make(map[string]interface{})
+
+type structWithPointerToEmbeddedStruct struct {
+	Male   *Male
+	Female *Female
+	Planet *map[string]interface{}
+}
+
+func init() {
+	m["earth"] = e
+	m["person"] = "John Doe"
+	m["iface"] = map[string]string{"another_person": "does it change root!"}
+	m["array"] = [5]int{1, 4, 5, 6, 7}
+}
+
+func TestRoller_push(t *testing.T) {
+	r := roller{}
+	r.setTagIdentifier("validate")
+	r.setTagSeparator("|")
+	r.start(male)
+	if r.push("Male.Name", "set new name") != false {
+		t.Error("push failed!")
+	}
+}
+
+func TestRoller_Start(t *testing.T) {
+	r := roller{}
+	r.setTagIdentifier("validate")
+	r.setTagSeparator("|")
+	r.start(m)
+	if len(r.getFlatMap()) != 20 {
+		t.Error("Start failed!")
+	}
+}
+
+func BenchmarkRoller_Start(b *testing.B) {
+	r := roller{}
+	r.setTagIdentifier("validate")
+	r.setTagSeparator("|")
+	for n := 0; n < b.N; n++ {
+		r.start(m)
+	}
+}
+
+func Test_Roller_Start_empty_map(t *testing.T) {
+	r := roller{}
+	emap := make(map[string]interface{}, 0)
+	r.setTagIdentifier("validate")
+	r.setTagSeparator("|")
+	r.start(emap)
+	if len(r.getFlatMap()) > 0 {
+		t.Error("Failed to validate empty map")
+	}
+}
+
+func TestRoller_traverseStructWithEmbeddedPointerStructAndMap(t *testing.T) {
+	r := roller{}
+	s := structWithPointerToEmbeddedStruct{
+		&male,
+		&female,
+		&p,
+	}
+	r.setTagIdentifier("validate")
+	r.setTagSeparator("|")
+	r.start(s)
+	if len(r.getFlatMap()) != 4 {
+		t.Error("traverseStructWithEmbeddedPointerStructAndMap failed!")
+	}
+}
+
+func TestRoller_traverseMapWithPointerStructAndMap(t *testing.T) {
+	r := roller{}
+	mapOfPointerVals := map[string]interface{}{
+		"structField":        male,
+		"structPointerField": &female,
+		"mapPointerField":    &p,
+	}
+
+	r.setTagIdentifier("validate")
+	r.setTagSeparator("|")
+	r.start(mapOfPointerVals)
+	if len(r.getFlatMap()) != 7 {
+		t.Error("traverseMapWithPointerStructAndMap failed!")
+	}
+}
+
+func TestRoller_StartPointerToStruct(t *testing.T) {
+	r := roller{}
+	r.setTagIdentifier("validate")
+	r.setTagSeparator("|")
+	r.start(&male)
+	if len(r.getFlatMap()) != 2 {
+		t.Error("StartPointerToStruct failed!")
+	}
+}
+
+func TestRoller_StartMap(t *testing.T) {
+	r := roller{}
+	r.setTagIdentifier("validate")
+	r.setTagSeparator("|")
+	r.start(m)
+	if len(r.getFlatMap()) != 20 {
+		t.Error("StartMap failed!")
+	}
+}
+
+func TestRoller_StartPointerToMap(t *testing.T) {
+	r := roller{}
+	r.setTagIdentifier("validate")
+	r.setTagSeparator("|")
+	r.start(&p)
+	if len(r.getFlatMap()) != 3 {
+		t.Error("StartPointerToMap failed!")
+	}
+}
+
+func TestRoller_StartStruct(t *testing.T) {
+	r := roller{}
+	r.setTagIdentifier("validate")
+	r.setTagSeparator("|")
+	r.start(h)
+
+	if len(r.getFlatMap()) != 4 {
+		t.Error("StartStruct failed!")
+	}
+}
+
+func TestRoller_StartStructWithTag(t *testing.T) {
+	r := roller{}
+	swTag := structWithTag{"John", 44}
+	r.setTagIdentifier("validate")
+	r.setTagSeparator("|")
+	r.start(swTag)
+
+	if len(r.getFlatMap()) != 2 {
+		t.Error("StartStructWithTag failed!")
+	}
+}
+
+func TestRoller_StartStructPointerWithTag(t *testing.T) {
+	r := roller{}
+	swTag := structWithTag{"John", 44}
+	r.setTagIdentifier("validate")
+	r.setTagSeparator("|")
+	r.start(&swTag)
+
+	if len(r.getFlatMap()) != 2 {
+		t.Error("StartStructPointerWithTag failed!")
+	}
+}
+
+func TestRoller_GetFlatVal(t *testing.T) {
+	r := roller{}
+	r.setTagIdentifier("validate")
+	r.setTagSeparator("|")
+	r.start(m)
+
+	//check struct field with string
+	name, _ := r.getFlatVal("Male.Name")
+	if name != "John" {
+		t.Error("GetFlatVal failed for struct string field!")
+	}
+
+	//check struct field with int
+	age, _ := r.getFlatVal("Male.Age")
+	if age != 33 {
+		t.Error("GetFlatVal failed for struct int field!")
+	}
+
+	//check struct field with array
+	intArrOf5, _ := r.getFlatVal("array")
+	if len(intArrOf5.([5]int)) != 5 {
+		t.Error("GetFlatVal failed for struct array of [5]int field!")
+	}
+
+	//check map key of string
+	person, _ := r.getFlatVal("person")
+	if person != "John Doe" {
+		t.Error("GetFlatVal failed for map[string]string!")
+	}
+
+	//check not existed key
+	_, ok := r.getFlatVal("not_existed_key")
+	if ok {
+		t.Error("GetFlatVal failed for not available key!")
+	}
+}
+
+func TestRoller_PremitiveDataType(t *testing.T) {
+	mStr := map[string]string{"oneStr": "hello", "twoStr": "Jane", "threeStr": "Doe"}
+	mBool := map[string]bool{"oneBool": true, "twoBool": false, "threeBool": true}
+	mInt := map[string]int{"oneInt": 1, "twoInt": 2, "threeInt": 3}
+	mInt8 := map[string]int8{"oneInt8": 1, "twoInt8": 2, "threeInt8": 3}
+	mInt16 := map[string]int16{"oneInt16": 1, "twoInt16": 2, "threeInt16": 3}
+	mInt32 := map[string]int32{"oneInt32": 1, "twoInt32": 2, "threeInt32": 3}
+	mInt64 := map[string]int64{"oneInt64": 1, "twoInt64": 2, "threeInt64": 3}
+	mFloat32 := map[string]float32{"onefloat32": 1.09, "twofloat32": 20.87, "threefloat32": 11.3}
+	mFloat64 := map[string]float64{"onefloat64": 10.88, "twofloat64": 92.09, "threefloat64": 3.90}
+	mUintptr := map[string]uintptr{"oneUintptr": 1, "twoUintptr": 2, "threeUintptr": 3}
+	mUint := map[string]uint{"oneUint": 1, "twoUint": 2, "threeUint": 3}
+	mUint8 := map[string]uint8{"oneUint8": 1, "twoUint8": 2, "threeUint8": 3}
+	mUint16 := map[string]uint16{"oneUint16": 1, "twoUint16": 2, "threeUint16": 3}
+	mUint32 := map[string]uint32{"oneUint32": 1, "twoUint32": 2, "threeUint32": 3}
+	mUint64 := map[string]uint64{"oneUint64": 1, "twoUint64": 2, "threeUint64": 3}
+	mComplex := map[string]interface{}{
+		"ptrToMapString":  &mStr,
+		"ptrToMapBool":    &mBool,
+		"ptrToMapInt":     &mInt,
+		"ptrToMapInt8":    &mInt8,
+		"ptrToMapInt16":   &mInt16,
+		"ptrToMapInt32":   &mInt32,
+		"ptrToMapInt64":   &mInt64,
+		"ptrToMapfloat32": &mFloat32,
+		"ptrToMapfloat64": &mFloat64,
+		"ptrToMapUintptr": &mUintptr,
+		"ptrToMapUint":    &mUint,
+		"ptrToMapUint8":   &mUint8,
+		"ptrToMapUint16":  &mUint16,
+		"ptrToMapUint32":  &mUint32,
+		"ptrToMapUint64":  &mUint64,
+	}
+	r := roller{}
+	r.setTagIdentifier("validate")
+	r.setTagSeparator("|")
+	r.start(mComplex)
+	itemsLen := len(mComplex) * 3
+	if len(r.getFlatMap()) != itemsLen {
+		t.Error("PremitiveDataType failed!")
+	}
+}
+
+func TestRoller_sliceOfType(t *testing.T) {
+	males := []Male{
+		{Name: "John", Age: 29},
+		{Name: "Jane", Age: 23},
+		{Name: "Tom", Age: 10},
+	}
+	r := roller{}
+	r.setTagIdentifier("validate")
+	r.setTagSeparator("|")
+	r.start(males)
+	i, _ := r.getFlatVal("slice")
+	if len(i.([]Male)) != len(males) {
+		t.Error("slice failed!")
+	}
+}
+
+func TestRoller_ptrSliceOfType(t *testing.T) {
+	males := []Male{
+		{Name: "John", Age: 29},
+		{Name: "Jane", Age: 23},
+		{Name: "Tom", Age: 10},
+	}
+	r := roller{}
+	r.setTagIdentifier("validate")
+	r.setTagSeparator("|")
+	r.start(&males)
+	i, _ := r.getFlatVal("slice")
+	if len(i.([]Male)) != len(males) {
+		t.Error("slice failed!")
+	}
+}
+
+func TestRoller_MapWithPointerPremitives(t *testing.T) {
+	type customType string
+	var str string
+	var varInt int
+	var varInt8 int8
+	var varInt16 int16
+	var varInt32 int32
+	var varInt64 int64
+	var varFloat32 float32
+	var varFloat64 float64
+	var varUint uint
+	var varUint8 uint8
+	var varUint16 uint16
+	var varUint32 uint32
+	var varUint64 uint64
+	var varUintptr uintptr
+	var x customType = "custom"
+	y := []string{"y", "z"}
+
+	males := map[string]interface{}{
+		"string":     &str,
+		"int":        &varInt,
+		"int8":       &varInt8,
+		"int16":      &varInt16,
+		"int32":      &varInt32,
+		"int64":      &varInt64,
+		"float32":    &varFloat32,
+		"float64":    &varFloat64,
+		"uint":       &varUint,
+		"uint8":      &varUint8,
+		"uint16":     &varUint16,
+		"uint32":     &varUint32,
+		"uint64":     &varUint64,
+		"uintPtr":    &varUintptr,
+		"customType": &x,
+		"y":          &y,
+	}
+	r := roller{}
+	r.setTagIdentifier("validate")
+	r.setTagSeparator("|")
+	r.start(males)
+
+	val, _ := r.getFlatVal("customType")
+	if *val.(*customType) != "custom" {
+		t.Error("fetching custom type value failed!")
+	}
+
+	valY, _ := r.getFlatVal("y")
+	if len(*valY.(*[]string)) != len(y) {
+		t.Error("fetching pointer to struct value failed!")
+	}
+
+	if len(r.getFlatMap()) != len(males) {
+		t.Error("MapWithPointerPremitives failed!")
+	}
+}
+
+type structWithCustomType struct {
+	Name      string  `json:"name"`
+	Integer   Int     `json:"integer"`
+	Integer64 Int64   `json:"integer64"`
+	Fpoint32  Float32 `json:"float32"`
+	Fpoint64  Float64 `json:"float64"`
+	Boolean   Bool    `json:"bool"`
+}
+
+func TestRoller_StartCustomType(t *testing.T) {
+	r := roller{}
+	swTag := structWithCustomType{Name: "John Doe", Integer: Int{Value: 44}}
+	r.setTagIdentifier("json")
+	r.setTagSeparator("|")
+	r.start(&swTag)
+	if len(r.getFlatMap()) != 6 {
+		t.Error("failed to push custom type")
+	}
+}
diff --git a/validationmdl/validationcore/rules.go b/validationmdl/validationcore/rules.go
new file mode 100644
index 0000000000000000000000000000000000000000..3a384257701debad0bc53d8d9170527e0ba8b8ae
--- /dev/null
+++ b/validationmdl/validationcore/rules.go
@@ -0,0 +1,1020 @@
+package govalidator
+
+import (
+	"errors"
+	"fmt"
+	"mime/multipart"
+	"net/url"
+	"reflect"
+	"strconv"
+	"strings"
+)
+
+// var mutex = &sync.Mutex{}
+// var Cnt = 0
+
+var rulesFuncMap = make(map[string]func(string, string, string, interface{}) error)
+
+// AddCustomRule help to add custom rules for validator
+// First argument it takes the rule name and second arg a func
+// Second arg must have this signature below
+// fn func(name string, fn func(field string, rule string, message string, value interface{}) error
+// see example in readme: https://github.com/thedevsaddam/govalidator#add-custom-rules
+func AddCustomRule(name string, fn func(field string, rule string, message string, value interface{}) error) {
+	if isRuleExist(name) {
+		panic(fmt.Errorf("govalidator: %s is already defined in rules", name))
+	}
+	rulesFuncMap[name] = fn
+}
+
+// validateCustomRules validate custom rules
+func validateCustomRules(field string, rule string, message string, value interface{}, errsBag url.Values) {
+
+	// loggermdl.LogDebug(field, " - ", rule)
+	// mutex.Lock()
+	// Cnt++
+	// mutex.Unlock()
+
+	for k, v := range rulesFuncMap {
+		if k == rule || strings.HasPrefix(rule, k+":") {
+			err := v(field, rule, message, value)
+			if err != nil {
+				errsBag.Add(field, err.Error())
+			}
+			break
+		}
+	}
+}
+
+func init() {
+
+	// Required check the Required fields
+	AddCustomRule("required", func(field, rule, message string, value interface{}) error {
+		err := fmt.Errorf("The %s field is required", field)
+		if message != "" {
+			err = errors.New(message)
+		}
+		if value == nil {
+			return err
+		}
+		if _, ok := value.(multipart.File); ok {
+			return nil
+		}
+		rv := reflect.ValueOf(value)
+		switch rv.Kind() {
+		case reflect.String, reflect.Array, reflect.Slice, reflect.Map:
+			if rv.Len() == 0 {
+				return err
+			}
+		case reflect.Int:
+			if isEmpty(value.(int)) {
+				return err
+			}
+		case reflect.Int8:
+			if isEmpty(value.(int8)) {
+				return err
+			}
+		case reflect.Int16:
+			if isEmpty(value.(int16)) {
+				return err
+			}
+		case reflect.Int32:
+			if isEmpty(value.(int32)) {
+				return err
+			}
+		case reflect.Int64:
+			if isEmpty(value.(int64)) {
+				return err
+			}
+		case reflect.Float32:
+			if isEmpty(value.(float32)) {
+				return err
+			}
+		case reflect.Float64:
+			if isEmpty(value.(float64)) {
+				return err
+			}
+		case reflect.Uint:
+			if isEmpty(value.(uint)) {
+				return err
+			}
+		case reflect.Uint8:
+			if isEmpty(value.(uint8)) {
+				return err
+			}
+		case reflect.Uint16:
+			if isEmpty(value.(uint16)) {
+				return err
+			}
+		case reflect.Uint32:
+			if isEmpty(value.(uint32)) {
+				return err
+			}
+		case reflect.Uint64:
+			if isEmpty(value.(uint64)) {
+				return err
+			}
+		case reflect.Uintptr:
+			if isEmpty(value.(uintptr)) {
+				return err
+			}
+		case reflect.Struct:
+			switch rv.Type().String() {
+			case "govalidator.Int":
+				if v, ok := value.(Int); ok {
+					if !v.IsSet {
+						return err
+					}
+				}
+			case "govalidator.Int64":
+				if v, ok := value.(Int64); ok {
+					if !v.IsSet {
+						return err
+					}
+				}
+			case "govalidator.Float32":
+				if v, ok := value.(Float32); ok {
+					if !v.IsSet {
+						return err
+					}
+				}
+			case "govalidator.Float64":
+				if v, ok := value.(Float64); ok {
+					if !v.IsSet {
+						return err
+					}
+				}
+			case "govalidator.Bool":
+				if v, ok := value.(Bool); ok {
+					if !v.IsSet {
+						return err
+					}
+				}
+			default:
+				panic("govalidator: invalid custom type for required rule")
+
+			}
+
+		default:
+			panic("govalidator: invalid type for required rule")
+
+		}
+		return nil
+	})
+
+	// Regex check the custom Regex rules
+	// Regex:^[a-zA-Z]+$ means this field can only contain alphabet (a-z and A-Z)
+	AddCustomRule("regex", func(field, rule, message string, value interface{}) error {
+		str := toString(value)
+		err := fmt.Errorf("The %s field format is invalid", field)
+		if message != "" {
+			err = errors.New(message)
+		}
+		rxStr := strings.TrimPrefix(rule, "regex:")
+		if !isMatchedRegex(rxStr, str) {
+			return err
+		}
+		return nil
+	})
+
+	// Alpha check if provided field contains valid letters
+	AddCustomRule("alpha", func(field string, vlaue string, message string, value interface{}) error {
+		str := toString(value)
+		err := fmt.Errorf("The %s may only contain letters", field)
+		if message != "" {
+			err = errors.New(message)
+		}
+		if !isAlpha(str) {
+			return err
+		}
+		return nil
+	})
+
+	// AlphaDash check if provided field contains valid letters, numbers, underscore and dash
+	AddCustomRule("alpha_dash", func(field string, vlaue string, message string, value interface{}) error {
+		str := toString(value)
+		err := fmt.Errorf("The %s may only contain letters, numbers, and dashes", field)
+		if message != "" {
+			err = errors.New(message)
+		}
+		if !isAlphaDash(str) {
+			return err
+		}
+		return nil
+	})
+
+	// AlphaNumeric check if provided field contains valid letters and numbers
+	AddCustomRule("alpha_num", func(field string, vlaue string, message string, value interface{}) error {
+		str := toString(value)
+		err := fmt.Errorf("The %s may only contain letters and numbers", field)
+		if message != "" {
+			err = errors.New(message)
+		}
+		if !isAlphaNumeric(str) {
+			return err
+		}
+		return nil
+	})
+
+	// Boolean check if provided field contains Boolean
+	// in this case: "0", "1", 0, 1, "true", "false", true, false etc
+	AddCustomRule("bool", func(field string, vlaue string, message string, value interface{}) error {
+		err := fmt.Errorf("The %s may only contain boolean value, string or int 0, 1", field)
+		if message != "" {
+			err = errors.New(message)
+		}
+		switch value.(type) {
+		case bool:
+			//if value is boolean then pass
+		case string:
+			if !isBoolean(value.(string)) {
+				return err
+			}
+		case int:
+			v := value.(int)
+			if v != 0 && v != 1 {
+				return err
+			}
+		case int8:
+			v := value.(int8)
+			if v != 0 && v != 1 {
+				return err
+			}
+		case int16:
+			v := value.(int16)
+			if v != 0 && v != 1 {
+				return err
+			}
+		case int32:
+			v := value.(int32)
+			if v != 0 && v != 1 {
+				return err
+			}
+		case int64:
+			v := value.(int64)
+			if v != 0 && v != 1 {
+				return err
+			}
+		case uint:
+			v := value.(uint)
+			if v != 0 && v != 1 {
+				return err
+			}
+		case uint8:
+			v := value.(uint8)
+			if v != 0 && v != 1 {
+				return err
+			}
+		case uint16:
+			v := value.(uint16)
+			if v != 0 && v != 1 {
+				return err
+			}
+		case uint32:
+			v := value.(uint32)
+			if v != 0 && v != 1 {
+				return err
+			}
+		case uint64:
+			v := value.(uint64)
+			if v != 0 && v != 1 {
+				return err
+			}
+		case uintptr:
+			v := value.(uintptr)
+			if v != 0 && v != 1 {
+				return err
+			}
+		}
+		return nil
+	})
+
+	// Between check the fields character length range
+	// if the field is array, map, slice then the valdiation rule will be the length of the data
+	// if the value is int or float then the valdiation rule will be the value comparison
+	AddCustomRule("between", func(field string, rule string, message string, value interface{}) error {
+		rng := strings.Split(strings.TrimPrefix(rule, "between:"), ",")
+		if len(rng) != 2 {
+			panic(errInvalidArgument)
+		}
+		minFloat, err := strconv.ParseFloat(rng[0], 64)
+		if err != nil {
+			panic(errStringToInt)
+		}
+		maxFloat, err := strconv.ParseFloat(rng[1], 64)
+		if err != nil {
+			panic(errStringToInt)
+		}
+		min := int(minFloat)
+
+		max := int(maxFloat)
+
+		err = fmt.Errorf("The %s field must be between %d and %d", field, min, max)
+		if message != "" {
+			err = errors.New(message)
+		}
+		rv := reflect.ValueOf(value)
+		switch rv.Kind() {
+		case reflect.String, reflect.Array, reflect.Map, reflect.Slice:
+			inLen := rv.Len()
+			if !(inLen >= min && inLen <= max) {
+				return err
+			}
+		case reflect.Int:
+			in := value.(int)
+			if !(in >= min && in <= max) {
+				return err
+			}
+		case reflect.Int8:
+			in := int(value.(int8))
+			if !(in >= min && in <= max) {
+				return err
+			}
+		case reflect.Int16:
+			in := int(value.(int16))
+			if !(in >= min && in <= max) {
+				return err
+			}
+		case reflect.Int32:
+			in := int(value.(int32))
+			if !(in >= min && in <= max) {
+				return err
+			}
+		case reflect.Int64:
+			in := int(value.(int64))
+			if !(in >= min && in <= max) {
+				return err
+			}
+		case reflect.Uint:
+			in := int(value.(uint))
+			if !(in >= min && in <= max) {
+				return err
+			}
+		case reflect.Uint8:
+			in := int(value.(uint8))
+			if !(in >= min && in <= max) {
+				return err
+			}
+		case reflect.Uint16:
+			in := int(value.(uint16))
+			if !(in >= min && in <= max) {
+				return err
+			}
+		case reflect.Uint32:
+			in := int(value.(uint32))
+			if !(in >= min && in <= max) {
+				return err
+			}
+		case reflect.Uint64:
+			in := int(value.(uint64))
+			if !(in >= min && in <= max) {
+				return err
+			}
+		case reflect.Uintptr:
+			in := int(value.(uintptr))
+			if !(in >= min && in <= max) {
+				return err
+			}
+		case reflect.Float32:
+			in := float64(value.(float32))
+			if !(in >= minFloat && in <= maxFloat) {
+				return fmt.Errorf("The %s field must be between %f and %f", field, minFloat, maxFloat)
+			}
+		case reflect.Float64:
+			in := value.(float64)
+			if !(in >= minFloat && in <= maxFloat) {
+				return fmt.Errorf("The %s field must be between %f and %f", field, minFloat, maxFloat)
+			}
+
+		}
+
+		return nil
+	})
+
+	// CreditCard check if provided field contains valid credit card number
+	// Accepted cards are Visa, MasterCard, American Express, Diners Club, Discover and JCB card
+	AddCustomRule("credit_card", func(field string, rule string, message string, value interface{}) error {
+		str := toString(value)
+		err := fmt.Errorf("The %s field must be a valid credit card number", field)
+		if message != "" {
+			err = errors.New(message)
+		}
+		if !isCreditCard(str) {
+			return err
+		}
+		return nil
+	})
+
+	// Coordinate check if provided field contains valid Coordinate
+	AddCustomRule("coordinate", func(field string, rule string, message string, value interface{}) error {
+		str := toString(value)
+		err := fmt.Errorf("The %s field must be a valid coordinate", field)
+		if message != "" {
+			err = errors.New(message)
+		}
+		if !isCoordinate(str) {
+			return err
+		}
+		return nil
+	})
+
+	// ValidateCSSColor check if provided field contains a valid CSS color code
+	AddCustomRule("css_color", func(field string, rule string, message string, value interface{}) error {
+		str := toString(value)
+		err := fmt.Errorf("The %s field must be a valid CSS color code", field)
+		if message != "" {
+			err = errors.New(message)
+		}
+		if !isCSSColor(str) {
+			return err
+		}
+		return nil
+	})
+
+	// Digits check the exact matching length of digit (0,9)
+	// Digits:5 means the field must have 5 digit of length.
+	// e.g: 12345 or 98997 etc
+	AddCustomRule("digits", func(field string, rule string, message string, value interface{}) error {
+		l, err := strconv.Atoi(strings.TrimPrefix(rule, "digits:"))
+		if err != nil {
+			panic(errStringToInt)
+		}
+		err = fmt.Errorf("The %s field must be %d digits", field, l)
+		if l == 1 {
+			err = fmt.Errorf("The %s field must be 1 digit", field)
+		}
+		if message != "" {
+			err = errors.New(message)
+		}
+		str := toString(value)
+		if len(str) != l || !isNumeric(str) {
+			return err
+		}
+
+		return nil
+	})
+
+	// DigitsBetween check if the field contains only digit and length between provided range
+	// e.g: digits_between:4,5 means the field can have value like: 8887 or 12345 etc
+	AddCustomRule("digits_between", func(field string, rule string, message string, value interface{}) error {
+		rng := strings.Split(strings.TrimPrefix(rule, "digits_between:"), ",")
+		if len(rng) != 2 {
+			panic(errInvalidArgument)
+		}
+		min, err := strconv.Atoi(rng[0])
+		if err != nil {
+			panic(errStringToInt)
+		}
+		max, err := strconv.Atoi(rng[1])
+		if err != nil {
+			panic(errStringToInt)
+		}
+		err = fmt.Errorf("The %s field must be digits between %d and %d", field, min, max)
+		if message != "" {
+			err = errors.New(message)
+		}
+		str := toString(value)
+		if !isNumeric(str) || !(len(str) >= min && len(str) <= max) {
+			return err
+		}
+
+		return nil
+	})
+
+	// Date check the provided field is valid Date
+	AddCustomRule("date", func(field string, rule string, message string, value interface{}) error {
+		str := toString(value)
+		if rule == "date:dd-mm-yyyy" {
+			if !isDateDDMMYY(str) {
+				if message != "" {
+					return errors.New(message)
+				}
+				return fmt.Errorf("The %s field must be a valid date format. e.g: dd-mm-yyyy, dd/mm/yyyy etc", field)
+			}
+		}
+		if !isDate(str) {
+			if message != "" {
+				return errors.New(message)
+			}
+			return fmt.Errorf("The %s field must be a valid date format. e.g: yyyy-mm-dd, yyyy/mm/dd etc", field)
+		}
+		return nil
+	})
+
+	// Email check the provided field is valid Email
+	AddCustomRule("email", func(field string, rule string, message string, value interface{}) error {
+		str := toString(value)
+		err := fmt.Errorf("The %s field must be a valid email address", field)
+		if message != "" {
+			err = errors.New(message)
+		}
+		if !isEmail(str) {
+			return err
+		}
+		return nil
+	})
+
+	// validFloat check the provided field is valid float number
+	AddCustomRule("float", func(field string, rule string, message string, value interface{}) error {
+		str := toString(value)
+		err := fmt.Errorf("The %s field must be a float number", field)
+		if message != "" {
+			err = errors.New(message)
+		}
+		if !isFloat(str) {
+			return err
+		}
+		return nil
+	})
+
+	// IP check if provided field is valid IP address
+	AddCustomRule("ip", func(field string, rule string, message string, value interface{}) error {
+		str := toString(value)
+		err := fmt.Errorf("The %s field must be a valid IP address", field)
+		if message != "" {
+			err = errors.New(message)
+		}
+		if !isIP(str) {
+			return err
+		}
+		return nil
+	})
+
+	// IP check if provided field is valid IP v4 address
+	AddCustomRule("ip_v4", func(field string, rule string, message string, value interface{}) error {
+		str := toString(value)
+		err := fmt.Errorf("The %s field must be a valid IPv4 address", field)
+		if message != "" {
+			err = errors.New(message)
+		}
+		if !isIPV4(str) {
+			return err
+		}
+		return nil
+	})
+
+	// IP check if provided field is valid IP v6 address
+	AddCustomRule("ip_v6", func(field string, rule string, message string, value interface{}) error {
+		str := toString(value)
+		err := fmt.Errorf("The %s field must be a valid IPv6 address", field)
+		if message != "" {
+			err = errors.New(message)
+		}
+		if !isIPV6(str) {
+			return err
+		}
+		return nil
+	})
+
+	// ValidateJSON check if provided field contains valid json string
+	AddCustomRule("json", func(field string, rule string, message string, value interface{}) error {
+		str := toString(value)
+		err := fmt.Errorf("The %s field must contain valid JSON string", field)
+		if message != "" {
+			err = errors.New(message)
+		}
+		if !isJSON(str) {
+			return err
+		}
+		return nil
+	})
+
+	/// Latitude check if provided field contains valid Latitude
+	AddCustomRule("lat", func(field string, rule string, message string, value interface{}) error {
+		str := toString(value)
+		err := fmt.Errorf("The %s field must contain valid latitude", field)
+		if message != "" {
+			err = errors.New(message)
+		}
+		if !isLatitude(str) {
+			return err
+		}
+		return nil
+	})
+
+	// Longitude check if provided field contains valid Longitude
+	AddCustomRule("lon", func(field string, rule string, message string, value interface{}) error {
+		str := toString(value)
+		err := fmt.Errorf("The %s field must contain valid longitude", field)
+		if message != "" {
+			err = errors.New(message)
+		}
+		if !isLongitude(str) {
+			return err
+		}
+		return nil
+	})
+
+	// Length check the field's character Length
+	AddCustomRule("len", func(field string, rule string, message string, value interface{}) error {
+		l, err := strconv.Atoi(strings.TrimPrefix(rule, "len:"))
+		if err != nil {
+			panic(errStringToInt)
+		}
+		err = fmt.Errorf("The %s field must be length of %d", field, l)
+		if message != "" {
+			err = errors.New(message)
+		}
+		rv := reflect.ValueOf(value)
+		switch rv.Kind() {
+		case reflect.String, reflect.Array, reflect.Map, reflect.Slice:
+			vLen := rv.Len()
+			if vLen != l {
+				return err
+			}
+		default:
+			str := toString(value) //force the value to be string
+			if len(str) != l {
+				return err
+			}
+		}
+
+		return nil
+	})
+
+	// Min check the field's minimum character length for string, value for int, float and size for array, map, slice
+	AddCustomRule("min", func(field string, rule string, message string, value interface{}) error {
+		mustLen := strings.TrimPrefix(rule, "min:")
+		lenInt, err := strconv.Atoi(mustLen)
+		if err != nil {
+			panic(errStringToInt)
+		}
+		lenFloat, err := strconv.ParseFloat(mustLen, 64)
+		if err != nil {
+			panic(errStringToFloat)
+		}
+		errMsg := fmt.Errorf("The %s field value can not be less than %d", field, lenInt)
+		if message != "" {
+			errMsg = errors.New(message)
+		}
+		errMsgFloat := fmt.Errorf("The %s field value can not be less than %f", field, lenFloat)
+		if message != "" {
+			errMsgFloat = errors.New(message)
+		}
+		rv := reflect.ValueOf(value)
+		switch rv.Kind() {
+		case reflect.String:
+			inLen := rv.Len()
+			if inLen < lenInt {
+				if message != "" {
+					return errors.New(message)
+				}
+				return fmt.Errorf("The %s field must be minimum %d char", field, lenInt)
+			}
+		case reflect.Array, reflect.Map, reflect.Slice:
+			inLen := rv.Len()
+			if inLen < lenInt {
+				if message != "" {
+					return errors.New(message)
+				}
+				return fmt.Errorf("The %s field must be minimum %d in size", field, lenInt)
+			}
+		case reflect.Int:
+			in := value.(int)
+			if in < lenInt {
+				return errMsg
+			}
+		case reflect.Int8:
+			in := int(value.(int8))
+			if in < lenInt {
+				return errMsg
+			}
+		case reflect.Int16:
+			in := int(value.(int16))
+			if in < lenInt {
+				return errMsg
+			}
+		case reflect.Int32:
+			in := int(value.(int32))
+			if in < lenInt {
+				return errMsg
+			}
+		case reflect.Int64:
+			in := int(value.(int64))
+			if in < lenInt {
+				return errMsg
+			}
+		case reflect.Uint:
+			in := int(value.(uint))
+			if in < lenInt {
+				return errMsg
+			}
+		case reflect.Uint8:
+			in := int(value.(uint8))
+			if in < lenInt {
+				return errMsg
+			}
+		case reflect.Uint16:
+			in := int(value.(uint16))
+			if in < lenInt {
+				return errMsg
+			}
+		case reflect.Uint32:
+			in := int(value.(uint32))
+			if in < lenInt {
+				return errMsg
+			}
+		case reflect.Uint64:
+			in := int(value.(uint64))
+			if in < lenInt {
+				return errMsg
+			}
+		case reflect.Uintptr:
+			in := int(value.(uintptr))
+			if in < lenInt {
+				return errMsg
+			}
+		case reflect.Float32:
+			in := value.(float32)
+			if in < float32(lenFloat) {
+				return errMsgFloat
+			}
+		case reflect.Float64:
+			in := value.(float64)
+			if in < lenFloat {
+				return errMsgFloat
+			}
+
+		}
+
+		return nil
+	})
+
+	// Max check the field's maximum character length for string, value for int, float and size for array, map, slice
+	AddCustomRule("max", func(field string, rule string, message string, value interface{}) error {
+		mustLen := strings.TrimPrefix(rule, "max:")
+		lenInt, err := strconv.Atoi(mustLen)
+		if err != nil {
+			panic(errStringToInt)
+		}
+		lenFloat, err := strconv.ParseFloat(mustLen, 64)
+		if err != nil {
+			panic(errStringToFloat)
+		}
+		errMsg := fmt.Errorf("The %s field value can not be greater than %d", field, lenInt)
+		if message != "" {
+			errMsg = errors.New(message)
+		}
+		errMsgFloat := fmt.Errorf("The %s field value can not be greater than %f", field, lenFloat)
+		if message != "" {
+			errMsgFloat = errors.New(message)
+		}
+		rv := reflect.ValueOf(value)
+		switch rv.Kind() {
+		case reflect.String:
+			inLen := rv.Len()
+			if inLen > lenInt {
+				if message != "" {
+					return errors.New(message)
+				}
+				return fmt.Errorf("The %s field must be maximum %d char", field, lenInt)
+			}
+		case reflect.Array, reflect.Map, reflect.Slice:
+			inLen := rv.Len()
+			if inLen > lenInt {
+				if message != "" {
+					return errors.New(message)
+				}
+				return fmt.Errorf("The %s field must be minimum %d in size", field, lenInt)
+			}
+		case reflect.Int:
+			in := value.(int)
+			if in > lenInt {
+				return errMsg
+			}
+		case reflect.Int8:
+			in := int(value.(int8))
+			if in > lenInt {
+				return errMsg
+			}
+		case reflect.Int16:
+			in := int(value.(int16))
+			if in > lenInt {
+				return errMsg
+			}
+		case reflect.Int32:
+			in := int(value.(int32))
+			if in > lenInt {
+				return errMsg
+			}
+		case reflect.Int64:
+			in := int(value.(int64))
+			if in > lenInt {
+				return errMsg
+			}
+		case reflect.Uint:
+			in := int(value.(uint))
+			if in > lenInt {
+				return errMsg
+			}
+		case reflect.Uint8:
+			in := int(value.(uint8))
+			if in > lenInt {
+				return errMsg
+			}
+		case reflect.Uint16:
+			in := int(value.(uint16))
+			if in > lenInt {
+				return errMsg
+			}
+		case reflect.Uint32:
+			in := int(value.(uint32))
+			if in > lenInt {
+				return errMsg
+			}
+		case reflect.Uint64:
+			in := int(value.(uint64))
+			if in > lenInt {
+				return errMsg
+			}
+		case reflect.Uintptr:
+			in := int(value.(uintptr))
+			if in > lenInt {
+				return errMsg
+			}
+		case reflect.Float32:
+			in := value.(float32)
+			if in > float32(lenFloat) {
+				return errMsgFloat
+			}
+		case reflect.Float64:
+			in := value.(float64)
+			if in > lenFloat {
+				return errMsgFloat
+			}
+
+		}
+
+		return nil
+	})
+
+	// Numeric check if the value of the field is Numeric
+	AddCustomRule("numeric", func(field string, rule string, message string, value interface{}) error {
+		str := toString(value)
+		err := fmt.Errorf("The %s field must be numeric", field)
+		if message != "" {
+			err = errors.New(message)
+		}
+		if !isNumeric(str) {
+			return err
+		}
+		return nil
+	})
+
+	// NumericBetween check if the value field numeric value range
+	// e.g: numeric_between:18, 65 means number value must be in between a numeric value 18 & 65
+	AddCustomRule("numeric_between", func(field string, rule string, message string, value interface{}) error {
+		rng := strings.Split(strings.TrimPrefix(rule, "numeric_between:"), ",")
+		if len(rng) != 2 {
+			panic(errInvalidArgument)
+		}
+		// check for integer value
+		_min, err := strconv.ParseFloat(rng[0], 64)
+		if err != nil {
+			panic(errStringToInt)
+		}
+		min := int(_min)
+		_max, err := strconv.ParseFloat(rng[1], 64)
+		if err != nil {
+			panic(errStringToInt)
+		}
+		max := int(_max)
+		errMsg := fmt.Errorf("The %s field must be numeric value between %d and %d", field, min, max)
+		if message != "" {
+			errMsg = errors.New(message)
+		}
+
+		val := toString(value)
+
+		if !strings.Contains(rng[0], ".") || !strings.Contains(rng[1], ".") {
+			digit, errs := strconv.Atoi(val)
+			if errs != nil {
+				return errMsg
+			}
+			if !(digit >= min && digit <= max) {
+				return errMsg
+			}
+		}
+		// check for float value
+		minFloat, err := strconv.ParseFloat(rng[0], 64)
+		if err != nil {
+			panic(errStringToFloat)
+		}
+		maxFloat, err := strconv.ParseFloat(rng[1], 64)
+		if err != nil {
+			panic(errStringToFloat)
+		}
+		errMsg = fmt.Errorf("The %s field must be numeric value between %f and %f", field, minFloat, maxFloat)
+		if message != "" {
+			errMsg = errors.New(message)
+		}
+
+		digit, err := strconv.ParseFloat(val, 64)
+		if err != nil {
+			return errMsg
+		}
+		if !(digit >= minFloat && digit <= maxFloat) {
+			return errMsg
+		}
+		return nil
+	})
+
+	// ValidateURL check if provided field is valid URL
+	AddCustomRule("url", func(field string, rule string, message string, value interface{}) error {
+		str := toString(value)
+		err := fmt.Errorf("The %s field format is invalid", field)
+		if message != "" {
+			err = errors.New(message)
+		}
+		if !isURL(str) {
+			return err
+		}
+		return nil
+	})
+
+	// UUID check if provided field contains valid UUID
+	AddCustomRule("uuid", func(field string, rule string, message string, value interface{}) error {
+		str := toString(value)
+		err := fmt.Errorf("The %s field must contain valid UUID", field)
+		if message != "" {
+			err = errors.New(message)
+		}
+		if !isUUID(str) {
+			return err
+		}
+		return nil
+	})
+
+	// UUID3 check if provided field contains valid UUID of version 3
+	AddCustomRule("uuid_v3", func(field string, rule string, message string, value interface{}) error {
+		str := toString(value)
+		err := fmt.Errorf("The %s field must contain valid UUID V3", field)
+		if message != "" {
+			err = errors.New(message)
+		}
+		if !isUUID3(str) {
+			return err
+		}
+		return nil
+	})
+
+	// UUID4 check if provided field contains valid UUID of version 4
+	AddCustomRule("uuid_v4", func(field string, rule string, message string, value interface{}) error {
+		str := toString(value)
+		err := fmt.Errorf("The %s field must contain valid UUID V4", field)
+		if message != "" {
+			err = errors.New(message)
+		}
+		if !isUUID4(str) {
+			return err
+		}
+		return nil
+	})
+
+	// UUID5 check if provided field contains valid UUID of version 5
+	AddCustomRule("uuid_v5", func(field string, rule string, message string, value interface{}) error {
+		str := toString(value)
+		err := fmt.Errorf("The %s field must contain valid UUID V5", field)
+		if message != "" {
+			err = errors.New(message)
+		}
+		if !isUUID5(str) {
+			return err
+		}
+		return nil
+	})
+
+	// In check if provided field equals one of the values specified in the rule
+	AddCustomRule("in", func(field string, rule string, message string, value interface{}) error {
+		rng := strings.Split(strings.TrimPrefix(rule, "in:"), ",")
+		if len(rng) == 0 {
+			panic(errInvalidArgument)
+		}
+		str := toString(value)
+		err := fmt.Errorf("The %s field must be one of %v", field, strings.Join(rng, ", "))
+		if message != "" {
+			err = errors.New(message)
+		}
+		if !isIn(rng, str) {
+			return err
+		}
+		return nil
+	})
+
+	// In check if provided field equals one of the values specified in the rule
+	AddCustomRule("not_in", func(field string, rule string, message string, value interface{}) error {
+		rng := strings.Split(strings.TrimPrefix(rule, "not_in:"), ",")
+		if len(rng) == 0 {
+			panic(errInvalidArgument)
+		}
+		str := toString(value)
+		err := fmt.Errorf("The %s field must not be any of %v", field, strings.Join(rng, ", "))
+		if message != "" {
+			err = errors.New(message)
+		}
+		if isIn(rng, str) {
+			return err
+		}
+		return nil
+	})
+}
diff --git a/validationmdl/validationcore/rules_test.go b/validationmdl/validationcore/rules_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..7de69d7bfed1bb497713fda178f580a1702ef801
--- /dev/null
+++ b/validationmdl/validationcore/rules_test.go
@@ -0,0 +1,1973 @@
+package govalidator
+
+import (
+	"bytes"
+	"encoding/json"
+	"fmt"
+	"net/http"
+	"net/url"
+	"testing"
+)
+
+func Test_AddCustomRule(t *testing.T) {
+	AddCustomRule("__x__", func(f string, rule string, message string, v interface{}) error {
+		if v.(string) != "xyz" {
+			return fmt.Errorf("The %s field must be xyz", f)
+		}
+		return nil
+	})
+	if len(rulesFuncMap) <= 0 {
+		t.Error("AddCustomRule failed to add new rule")
+	}
+}
+
+func Test_AddCustomRule_panic(t *testing.T) {
+	defer func() {
+		if r := recover(); r == nil {
+			t.Errorf("AddCustomRule failed to panic")
+		}
+	}()
+	AddCustomRule("__x__", func(f string, rule string, message string, v interface{}) error {
+		if v.(string) != "xyz" {
+			return fmt.Errorf("The %s field must be xyz", f)
+		}
+		return nil
+	})
+}
+
+func Test_validateExtraRules(t *testing.T) {
+	errsBag := url.Values{}
+	validateCustomRules("f_field", "__x__", "a", "", errsBag)
+	if len(errsBag) != 1 {
+		t.Error("validateExtraRules failed")
+	}
+}
+
+//================================= rules =================================
+func Test_Required(t *testing.T) {
+	type tRequired struct {
+		Str       string  `json:"_str"`
+		Int       int     `json:"_int"`
+		Int8      int8    `json:"_int8"`
+		Int16     int16   `json:"_int16"`
+		Int32     int32   `json:"_int32"`
+		Int64     int64   `json:"_int64"`
+		Uint      uint    `json:"_uint"`
+		Uint8     uint8   `json:"_uint8"`
+		Uint16    uint16  `json:"_uint16"`
+		Uint32    uint32  `json:"_uint32"`
+		Uint64    uint64  `json:"_uint64"`
+		Uintptr   uintptr `json:"_uintptr"`
+		Flaot32   float32 `json:"_float32"`
+		Flaot64   float64 `json:"_float64"`
+		Integer   Int     `json:"integer"`
+		Integer64 Int64   `json:"integer64"`
+		Fpoint32  Float32 `json:"float32"`
+		Fpoint64  Float64 `json:"float64"`
+		Boolean   Bool    `json:"boolean"`
+	}
+
+	rules := MapData{
+		"_str":      []string{"required"},
+		"_int":      []string{"required"},
+		"_int8":     []string{"required"},
+		"_int16":    []string{"required"},
+		"_int32":    []string{"required"},
+		"_int64":    []string{"required"},
+		"_uint":     []string{"required"},
+		"_uint8":    []string{"required"},
+		"_uint16":   []string{"required"},
+		"_uint32":   []string{"required"},
+		"_uint64":   []string{"required"},
+		"_uintptr":  []string{"required"},
+		"_float32":  []string{"required"},
+		"_float64":  []string{"required"},
+		"integer":   []string{"required"},
+		"integer64": []string{"required"},
+		"float32":   []string{"required"},
+		"float64":   []string{"required"},
+		"boolean":   []string{"required"},
+	}
+
+	postRequired := map[string]string{}
+
+	var trequired tRequired
+
+	body, _ := json.Marshal(postRequired)
+	req, _ := http.NewRequest("POST", "http://www.example.com", bytes.NewReader(body))
+
+	messages := MapData{
+		"_str": []string{"required:custom_message"},
+	}
+
+	opts := Options{
+		Request:  req,
+		Data:     &trequired,
+		Rules:    rules,
+		Messages: messages,
+	}
+
+	vd := New(opts)
+	validationErr := vd.ValidateJSON()
+	if len(validationErr) != 19 {
+		t.Log(validationErr)
+		t.Error("required validation failed!")
+	}
+
+	if validationErr.Get("_str") != "custom_message" {
+		t.Error("required rule custom message failed")
+	}
+}
+
+func Test_Regex(t *testing.T) {
+	type tRegex struct {
+		Name string `json:"name"`
+	}
+
+	postRegex := tRegex{Name: "john"}
+	var tregex tRegex
+
+	body, _ := json.Marshal(postRegex)
+	req, _ := http.NewRequest("POST", "http://www.example.com", bytes.NewReader(body))
+
+	messages := MapData{
+		"name": []string{"regex:custom_message"},
+	}
+
+	rules := MapData{
+		"name": []string{"regex:^[0-9]+$"},
+	}
+
+	opts := Options{
+		Request:  req,
+		Data:     &tregex,
+		Rules:    rules,
+		Messages: messages,
+	}
+
+	vd := New(opts)
+	validationErr := vd.ValidateJSON()
+	if len(validationErr) != 1 {
+		t.Error("regex validation failed!")
+	}
+
+	if validationErr.Get("name") != "custom_message" {
+		t.Error("regex rule custom message failed")
+	}
+
+}
+
+func Test_Alpha(t *testing.T) {
+	type user struct {
+		Name string `json:"name"`
+	}
+
+	postUser := user{Name: "9080"}
+	var userObj user
+
+	body, _ := json.Marshal(postUser)
+	req, _ := http.NewRequest("POST", "http://www.example.com", bytes.NewReader(body))
+
+	messages := MapData{
+		"name": []string{"alpha:custom_message"},
+	}
+
+	rules := MapData{
+		"name": []string{"alpha"},
+	}
+
+	opts := Options{
+		Request:  req,
+		Data:     &userObj,
+		Rules:    rules,
+		Messages: messages,
+	}
+
+	vd := New(opts)
+	validationErr := vd.ValidateJSON()
+	if len(validationErr) != 1 {
+		t.Error("alpha validation failed!")
+	}
+
+	if validationErr.Get("name") != "custom_message" {
+		t.Error("alpha custom message failed!")
+	}
+}
+
+func Test_AlphaDash(t *testing.T) {
+	type user struct {
+		Name string `json:"name"`
+	}
+
+	postUser := user{Name: "9090$"}
+	var userObj user
+
+	body, _ := json.Marshal(postUser)
+	req, _ := http.NewRequest("POST", "http://www.example.com", bytes.NewReader(body))
+
+	messages := MapData{
+		"name": []string{"alpha_dash:custom_message"},
+	}
+
+	rules := MapData{
+		"name": []string{"alpha_dash"},
+	}
+
+	opts := Options{
+		Request:  req,
+		Data:     &userObj,
+		Rules:    rules,
+		Messages: messages,
+	}
+
+	vd := New(opts)
+	validationErr := vd.ValidateJSON()
+	if len(validationErr) != 1 {
+		t.Log(validationErr)
+		t.Error("alpha_dash validation failed!")
+	}
+
+	if validationErr.Get("name") != "custom_message" {
+		t.Error("alpha dash custom message failed!")
+	}
+}
+
+func Test_AlphaNumeric(t *testing.T) {
+	type user struct {
+		Name string `json:"name"`
+	}
+
+	postUser := user{Name: "aE*Sb$"}
+	var userObj user
+
+	body, _ := json.Marshal(postUser)
+	req, _ := http.NewRequest("POST", "http://www.example.com", bytes.NewReader(body))
+
+	rules := MapData{
+		"name": []string{"alpha_num"},
+	}
+
+	messages := MapData{
+		"name": []string{"alpha_num:custom_message"},
+	}
+
+	opts := Options{
+		Request:  req,
+		Data:     &userObj,
+		Rules:    rules,
+		Messages: messages,
+	}
+
+	vd := New(opts)
+	validationErr := vd.ValidateJSON()
+	if len(validationErr) != 1 {
+		t.Log(validationErr)
+		t.Error("alpha_num validation failed!")
+	}
+
+	if validationErr.Get("name") != "custom_message" {
+		t.Error("alpha num custom message failed!")
+	}
+}
+
+func Test_Boolean(t *testing.T) {
+	type Bools struct {
+		BoolStr     string  `json:"boolStr"`
+		BoolInt     int     `json:"boolInt"`
+		BoolInt8    int8    `json:"boolInt8"`
+		BoolInt16   int16   `json:"boolInt16"`
+		BoolInt32   int32   `json:"boolInt32"`
+		BoolInt64   int64   `json:"boolInt64"`
+		BoolUint    uint    `json:"boolUint"`
+		BoolUint8   uint8   `json:"boolUint8"`
+		BoolUint16  uint16  `json:"boolUint16"`
+		BoolUint32  uint32  `json:"boolUint32"`
+		BoolUint64  uint64  `json:"boolUint64"`
+		BoolUintptr uintptr `json:"boolUintptr"`
+		Bool        bool    `json:"_bool"`
+	}
+
+	postBools := Bools{
+		BoolStr:     "abc",
+		BoolInt:     90,
+		BoolInt8:    10,
+		BoolInt16:   22,
+		BoolInt32:   76,
+		BoolInt64:   9,
+		BoolUint:    5,
+		BoolUint8:   9,
+		BoolUint16:  9,
+		BoolUint32:  9,
+		BoolUint64:  8,
+		BoolUintptr: 9,
+	}
+	var boolObj Bools
+
+	body, _ := json.Marshal(postBools)
+	req, _ := http.NewRequest("POST", "http://www.example.com", bytes.NewReader(body))
+
+	rules := MapData{
+		"boolStr":     []string{"bool"},
+		"boolInt":     []string{"bool"},
+		"boolInt8":    []string{"bool"},
+		"boolInt16":   []string{"bool"},
+		"boolInt32":   []string{"bool"},
+		"boolInt64":   []string{"bool"},
+		"boolUint":    []string{"bool"},
+		"boolUint8":   []string{"bool"},
+		"boolUint16":  []string{"bool"},
+		"boolUint32":  []string{"bool"},
+		"boolUint64":  []string{"bool"},
+		"boolUintptr": []string{"bool"},
+	}
+
+	messages := MapData{
+		"boolStr":  []string{"bool:custom_message"},
+		"boolInt":  []string{"bool:custom_message"},
+		"boolUint": []string{"bool:custom_message"},
+	}
+
+	opts := Options{
+		Request:  req,
+		Data:     &boolObj,
+		Rules:    rules,
+		Messages: messages,
+	}
+
+	vd := New(opts)
+	validationErr := vd.ValidateJSON()
+	if len(validationErr) != 12 {
+		t.Error("bool validation failed!")
+	}
+
+	if validationErr.Get("boolStr") != "custom_message" ||
+		validationErr.Get("boolInt") != "custom_message" ||
+		validationErr.Get("boolUint") != "custom_message" {
+		t.Error("bool custom message failed!")
+	}
+}
+
+func Test_Between(t *testing.T) {
+	type user struct {
+		Str     string  `json:"str"`
+		Int     int     `json:"_int"`
+		Int8    int8    `json:"_int8"`
+		Int16   int16   `json:"_int16"`
+		Int32   int32   `json:"_int32"`
+		Int64   int64   `json:"_int64"`
+		Uint    uint    `json:"_uint"`
+		Uint8   uint8   `json:"_uint8"`
+		Uint16  uint16  `json:"_uint16"`
+		Uint32  uint32  `json:"_uint32"`
+		Uint64  uint64  `json:"_uint64"`
+		Uintptr uintptr `json:"_uintptr"`
+		Float32 float32 `json:"_float32"`
+		Float64 float64 `json:"_float64"`
+		Slice   []int   `json:"_slice"`
+	}
+
+	postUser := user{}
+	var userObj user
+
+	body, _ := json.Marshal(postUser)
+	req, _ := http.NewRequest("POST", "http://www.example.com", bytes.NewReader(body))
+
+	rules := MapData{
+		"str":      []string{"between:3,5"},
+		"_int":     []string{"between:3,5"},
+		"_int8":    []string{"between:3,5"},
+		"_int16":   []string{"between:3,5"},
+		"_int32":   []string{"between:3,5"},
+		"_int64":   []string{"between:3,5"},
+		"_uint":    []string{"between:3,5"},
+		"_uint8":   []string{"between:3,5"},
+		"_uint16":  []string{"between:3,5"},
+		"_uint32":  []string{"between:3,5"},
+		"_uint64":  []string{"between:3,5"},
+		"_uintptr": []string{"between:3,5"},
+		"_float32": []string{"between:3.5,5.9"},
+		"_float64": []string{"between:3.3,6.2"},
+		"_slice":   []string{"between:3,5"},
+	}
+
+	opts := Options{
+		Request: req,
+		Data:    &userObj,
+		Rules:   rules,
+	}
+
+	vd := New(opts)
+	vd.SetDefaultRequired(true)
+	validationErr := vd.ValidateJSON()
+	if len(validationErr) != 15 {
+		t.Error("between validation failed!")
+	}
+}
+
+func Test_CreditCard(t *testing.T) {
+	type user struct {
+		CreditCard string `json:"credit_card"`
+	}
+
+	postUser := user{CreditCard: "87080"}
+	var userObj user
+
+	body, _ := json.Marshal(postUser)
+	req, _ := http.NewRequest("POST", "http://www.example.com", bytes.NewReader(body))
+
+	messages := MapData{
+		"credit_card": []string{"credit_card:custom_message"},
+	}
+
+	rules := MapData{
+		"credit_card": []string{"credit_card"},
+	}
+
+	opts := Options{
+		Request:  req,
+		Data:     &userObj,
+		Rules:    rules,
+		Messages: messages,
+	}
+
+	vd := New(opts)
+	validationErr := vd.ValidateJSON()
+	if len(validationErr) != 1 {
+		t.Error("credit card validation failed!")
+	}
+
+	if validationErr.Get("credit_card") != "custom_message" {
+		t.Error("credit_card custom message failed!")
+	}
+}
+
+func Test_Coordinate(t *testing.T) {
+	type user struct {
+		Coordinate string `json:"coordinate"`
+	}
+
+	postUser := user{Coordinate: "8080"}
+	var userObj user
+
+	body, _ := json.Marshal(postUser)
+	req, _ := http.NewRequest("POST", "http://www.example.com", bytes.NewReader(body))
+
+	messages := MapData{
+		"coordinate": []string{"coordinate:custom_message"},
+	}
+
+	rules := MapData{
+		"coordinate": []string{"coordinate"},
+	}
+
+	opts := Options{
+		Request:  req,
+		Data:     &userObj,
+		Rules:    rules,
+		Messages: messages,
+	}
+
+	vd := New(opts)
+	validationErr := vd.ValidateJSON()
+	if len(validationErr) != 1 {
+		t.Error("coordinate validation failed!")
+	}
+
+	if validationErr.Get("coordinate") != "custom_message" {
+		t.Error("coordinate custom message failed!")
+	}
+}
+
+func Test_CSSColor(t *testing.T) {
+	type user struct {
+		Color string `json:"color"`
+	}
+
+	postUser := user{Color: "8080"}
+	var userObj user
+
+	body, _ := json.Marshal(postUser)
+	req, _ := http.NewRequest("POST", "http://www.example.com", bytes.NewReader(body))
+
+	rules := MapData{
+		"color": []string{"css_color"},
+	}
+
+	messages := MapData{
+		"color": []string{"css_color:custom_message"},
+	}
+
+	opts := Options{
+		Request:  req,
+		Data:     &userObj,
+		Rules:    rules,
+		Messages: messages,
+	}
+
+	vd := New(opts)
+	validationErr := vd.ValidateJSON()
+	if len(validationErr) != 1 {
+		t.Error("CSS color validation failed!")
+	}
+
+	if validationErr.Get("color") != "custom_message" {
+		t.Error("css_color custom message failed!")
+	}
+}
+
+func Test_Digits(t *testing.T) {
+	type user struct {
+		Zip   string `json:"zip"`
+		Level string `json:"level"`
+	}
+
+	postUser := user{Zip: "8322", Level: "10"}
+	var userObj user
+
+	body, _ := json.Marshal(postUser)
+	req, _ := http.NewRequest("POST", "http://www.example.com", bytes.NewReader(body))
+
+	rules := MapData{
+		"zip":   []string{"digits:5"},
+		"level": []string{"digits:1"},
+	}
+
+	opts := Options{
+		Request: req,
+		Data:    &userObj,
+		Rules:   rules,
+	}
+
+	vd := New(opts)
+	validationErr := vd.ValidateJSON()
+	if len(validationErr) != 2 {
+		t.Error("Digits validation failed!")
+	}
+}
+
+func Test_DigitsBetween(t *testing.T) {
+	type user struct {
+		Zip   string `json:"zip"`
+		Level string `json:"level"`
+	}
+
+	postUser := user{Zip: "8322", Level: "10"}
+	var userObj user
+
+	body, _ := json.Marshal(postUser)
+	req, _ := http.NewRequest("POST", "http://www.example.com", bytes.NewReader(body))
+
+	rules := MapData{
+		"zip":   []string{"digits_between:5,10"},
+		"level": []string{"digits_between:5,10"},
+	}
+
+	messages := MapData{
+		"zip":   []string{"digits_between:custom_message"},
+		"level": []string{"digits_between:custom_message"},
+	}
+
+	opts := Options{
+		Request:  req,
+		Data:     &userObj,
+		Rules:    rules,
+		Messages: messages,
+	}
+
+	vd := New(opts)
+	validationErr := vd.ValidateJSON()
+	if len(validationErr) != 2 {
+		t.Error("digits between validation failed!")
+	}
+
+	if validationErr.Get("zip") != "custom_message" ||
+		validationErr.Get("level") != "custom_message" {
+		t.Error("digits_between custom message failed!")
+	}
+}
+
+func Test_DigitsBetweenPanic(t *testing.T) {
+	defer func() {
+		if r := recover(); r == nil {
+			t.Errorf("Digits between failed to panic!")
+		}
+	}()
+	type user struct {
+		Zip   string `json:"zip"`
+		Level string `json:"level"`
+	}
+
+	postUser := user{Zip: "8322", Level: "10"}
+	var userObj user
+
+	body, _ := json.Marshal(postUser)
+	req, _ := http.NewRequest("POST", "http://www.example.com", bytes.NewReader(body))
+
+	rules := MapData{
+		"zip":   []string{"digits_between:5"},
+		"level": []string{"digits_between:i,k"},
+	}
+
+	opts := Options{
+		Request: req,
+		Data:    &userObj,
+		Rules:   rules,
+	}
+
+	vd := New(opts)
+	validationErr := vd.ValidateJSON()
+	if len(validationErr) != 2 {
+		t.Error("Digits between panic failed!")
+	}
+}
+
+func Test_Date(t *testing.T) {
+	type user struct {
+		DOB         string `json:"dob"`
+		JoiningDate string `json:"joining_date"`
+	}
+
+	postUser := user{DOB: "invalida date", JoiningDate: "10"}
+	var userObj user
+
+	body, _ := json.Marshal(postUser)
+	req, _ := http.NewRequest("POST", "http://www.example.com", bytes.NewReader(body))
+
+	rules := MapData{
+		"dob":          []string{"date"},
+		"joining_date": []string{"date:dd-mm-yyyy"},
+	}
+
+	opts := Options{
+		Request: req,
+		Data:    &userObj,
+		Rules:   rules,
+	}
+
+	vd := New(opts)
+	validationErr := vd.ValidateJSON()
+	if len(validationErr) != 2 {
+		t.Log(validationErr)
+		t.Error("Date validation failed!")
+	}
+}
+
+func Test_Date_message(t *testing.T) {
+	type user struct {
+		DOB         string `json:"dob"`
+		JoiningDate string `json:"joining_date"`
+	}
+
+	postUser := user{DOB: "invalida date", JoiningDate: "10"}
+	var userObj user
+
+	body, _ := json.Marshal(postUser)
+	req, _ := http.NewRequest("POST", "http://www.example.com", bytes.NewReader(body))
+
+	rules := MapData{
+		"dob":          []string{"date"},
+		"joining_date": []string{"date:dd-mm-yyyy"},
+	}
+
+	messages := MapData{
+		"dob":          []string{"date:custom_message"},
+		"joining_date": []string{"date:dd-mm-yyyy:custom_message"},
+	}
+
+	opts := Options{
+		Request:  req,
+		Data:     &userObj,
+		Rules:    rules,
+		Messages: messages,
+	}
+
+	vd := New(opts)
+	validationErr := vd.ValidateJSON()
+	if validationErr.Get("dob") != "custom_message" {
+		t.Error("Date custom message validation failed!")
+	}
+	if k := validationErr.Get("dob"); k != "custom_message" {
+		t.Error("Date date:dd-mm-yyyy custom message validation failed!")
+	}
+}
+
+func Test_Email(t *testing.T) {
+	type user struct {
+		Email string `json:"email"`
+	}
+
+	postUser := user{Email: "invalid email"}
+	var userObj user
+
+	body, _ := json.Marshal(postUser)
+	req, _ := http.NewRequest("POST", "http://www.example.com", bytes.NewReader(body))
+
+	rules := MapData{
+		"email": []string{"email"},
+	}
+
+	opts := Options{
+		Request: req,
+		Data:    &userObj,
+		Rules:   rules,
+	}
+
+	vd := New(opts)
+	validationErr := vd.ValidateJSON()
+	if len(validationErr) != 1 {
+		t.Log(validationErr)
+		t.Error("Email validation failed!")
+	}
+}
+
+func Test_Email_message(t *testing.T) {
+	type user struct {
+		Email string `json:"email"`
+	}
+
+	postUser := user{Email: "invalid email"}
+	var userObj user
+
+	body, _ := json.Marshal(postUser)
+	req, _ := http.NewRequest("POST", "http://www.example.com", bytes.NewReader(body))
+
+	rules := MapData{
+		"email": []string{"email"},
+	}
+
+	messages := MapData{
+		"email": []string{"email:custom_message"},
+	}
+	opts := Options{
+		Request:  req,
+		Data:     &userObj,
+		Rules:    rules,
+		Messages: messages,
+	}
+
+	vd := New(opts)
+	validationErr := vd.ValidateJSON()
+	if validationErr.Get("email") != "custom_message" {
+		t.Error("Email message validation failed!")
+	}
+}
+
+func Test_Float(t *testing.T) {
+	type user struct {
+		CGPA string `json:"cgpa"`
+	}
+
+	postUser := user{CGPA: "invalid cgpa"}
+	var userObj user
+
+	body, _ := json.Marshal(postUser)
+	req, _ := http.NewRequest("POST", "http://www.example.com", bytes.NewReader(body))
+
+	rules := MapData{
+		"cgpa": []string{"float"},
+	}
+
+	opts := Options{
+		Request: req,
+		Data:    &userObj,
+		Rules:   rules,
+	}
+
+	vd := New(opts)
+	validationErr := vd.ValidateJSON()
+	if len(validationErr) != 1 {
+		t.Log(validationErr)
+		t.Error("Float validation failed!")
+	}
+}
+
+func Test_Float_message(t *testing.T) {
+	type user struct {
+		CGPA string `json:"cgpa"`
+	}
+
+	postUser := user{CGPA: "invalid cgpa"}
+	var userObj user
+
+	body, _ := json.Marshal(postUser)
+	req, _ := http.NewRequest("POST", "http://www.example.com", bytes.NewReader(body))
+
+	rules := MapData{
+		"cgpa": []string{"float"},
+	}
+
+	messages := MapData{
+		"cgpa": []string{"float:custom_message"},
+	}
+
+	opts := Options{
+		Request:  req,
+		Data:     &userObj,
+		Rules:    rules,
+		Messages: messages,
+	}
+
+	vd := New(opts)
+	validationErr := vd.ValidateJSON()
+	if validationErr.Get("cgpa") != "custom_message" {
+		t.Error("Float custom message failed!")
+	}
+}
+
+func Test_IP(t *testing.T) {
+	type user struct {
+		IP string `json:"ip"`
+	}
+
+	postUser := user{IP: "invalid IP"}
+	var userObj user
+
+	body, _ := json.Marshal(postUser)
+	req, _ := http.NewRequest("POST", "http://www.example.com", bytes.NewReader(body))
+
+	rules := MapData{
+		"ip": []string{"ip"},
+	}
+
+	opts := Options{
+		Request: req,
+		Data:    &userObj,
+		Rules:   rules,
+	}
+
+	vd := New(opts)
+	validationErr := vd.ValidateJSON()
+	if len(validationErr) != 1 {
+		t.Log(validationErr)
+		t.Error("IP validation failed!")
+	}
+}
+
+func Test_IP_message(t *testing.T) {
+	type user struct {
+		IP string `json:"ip"`
+	}
+
+	postUser := user{IP: "invalid IP"}
+	var userObj user
+
+	body, _ := json.Marshal(postUser)
+	req, _ := http.NewRequest("POST", "http://www.example.com", bytes.NewReader(body))
+
+	messages := MapData{
+		"ip": []string{"ip:custom_message"},
+	}
+
+	rules := MapData{
+		"ip": []string{"ip"},
+	}
+
+	opts := Options{
+		Request:  req,
+		Data:     &userObj,
+		Rules:    rules,
+		Messages: messages,
+	}
+
+	vd := New(opts)
+	validationErr := vd.ValidateJSON()
+	if validationErr.Get("ip") != "custom_message" {
+		t.Error("IP custom message failed!")
+	}
+}
+
+func Test_IPv4(t *testing.T) {
+	type user struct {
+		IP string `json:"ip"`
+	}
+
+	postUser := user{IP: "invalid IP"}
+	var userObj user
+
+	body, _ := json.Marshal(postUser)
+	req, _ := http.NewRequest("POST", "http://www.example.com", bytes.NewReader(body))
+
+	rules := MapData{
+		"ip": []string{"ip_v4"},
+	}
+
+	opts := Options{
+		Request: req,
+		Data:    &userObj,
+		Rules:   rules,
+	}
+
+	vd := New(opts)
+	validationErr := vd.ValidateJSON()
+	if len(validationErr) != 1 {
+		t.Log(validationErr)
+		t.Error("IP v4 validation failed!")
+	}
+}
+
+func Test_IPv4_message(t *testing.T) {
+	type user struct {
+		IP string `json:"ip"`
+	}
+
+	postUser := user{IP: "invalid IP"}
+	var userObj user
+
+	body, _ := json.Marshal(postUser)
+	req, _ := http.NewRequest("POST", "http://www.example.com", bytes.NewReader(body))
+
+	messages := MapData{
+		"ip": []string{"ip_v4:custom_message"},
+	}
+
+	rules := MapData{
+		"ip": []string{"ip_v4"},
+	}
+
+	opts := Options{
+		Request:  req,
+		Data:     &userObj,
+		Rules:    rules,
+		Messages: messages,
+	}
+
+	vd := New(opts)
+	validationErr := vd.ValidateJSON()
+	if validationErr.Get("ip") != "custom_message" {
+		t.Error("IP v4 custom message failed!")
+	}
+}
+
+func Test_IPv6(t *testing.T) {
+	type user struct {
+		IP string `json:"ip"`
+	}
+
+	postUser := user{IP: "invalid IP"}
+	var userObj user
+
+	body, _ := json.Marshal(postUser)
+	req, _ := http.NewRequest("POST", "http://www.example.com", bytes.NewReader(body))
+
+	rules := MapData{
+		"ip": []string{"ip_v6"},
+	}
+
+	opts := Options{
+		Request: req,
+		Data:    &userObj,
+		Rules:   rules,
+	}
+
+	vd := New(opts)
+	validationErr := vd.ValidateJSON()
+	if len(validationErr) != 1 {
+		t.Log(validationErr)
+		t.Error("IP v6 validation failed!")
+	}
+}
+
+func Test_IPv6_message(t *testing.T) {
+	type user struct {
+		IP string `json:"ip"`
+	}
+
+	postUser := user{IP: "invalid IP"}
+	var userObj user
+
+	body, _ := json.Marshal(postUser)
+	req, _ := http.NewRequest("POST", "http://www.example.com", bytes.NewReader(body))
+
+	messages := MapData{
+		"ip": []string{"ip_v6:custom_message"},
+	}
+
+	rules := MapData{
+		"ip": []string{"ip_v6"},
+	}
+
+	opts := Options{
+		Request:  req,
+		Data:     &userObj,
+		Rules:    rules,
+		Messages: messages,
+	}
+
+	vd := New(opts)
+	validationErr := vd.ValidateJSON()
+	if validationErr.Get("ip") != "custom_message" {
+		t.Error("IP v6 custom message failed!")
+	}
+}
+
+func Test_JSON(t *testing.T) {
+	type user struct {
+		Settings string `json:"settings"`
+	}
+
+	postUser := user{Settings: "invalid json"}
+	var userObj user
+
+	body, _ := json.Marshal(postUser)
+	req, _ := http.NewRequest("POST", "http://www.example.com", bytes.NewReader(body))
+
+	rules := MapData{
+		"settings": []string{"json"},
+	}
+
+	opts := Options{
+		Request: req,
+		Data:    &userObj,
+		Rules:   rules,
+	}
+
+	vd := New(opts)
+	validationErr := vd.ValidateJSON()
+	if len(validationErr) != 1 {
+		t.Log(validationErr)
+		t.Error("JSON validation failed!")
+	}
+}
+
+func Test_JSON_valid(t *testing.T) {
+	type user struct {
+		Settings string `json:"settings"`
+	}
+
+	postUser := user{Settings: `{"name": "John Doe", "age": 30}`}
+	var userObj user
+
+	body, _ := json.Marshal(postUser)
+	req, _ := http.NewRequest("POST", "http://www.example.com", bytes.NewReader(body))
+
+	rules := MapData{
+		"settings": []string{"json"},
+	}
+
+	opts := Options{
+		Request: req,
+		Data:    &userObj,
+		Rules:   rules,
+	}
+
+	vd := New(opts)
+	validationErr := vd.ValidateJSON()
+	if len(validationErr) != 0 {
+		t.Log(validationErr)
+		t.Error("Validation failed for valid JSON")
+	}
+}
+
+func Test_JSON_message(t *testing.T) {
+	type user struct {
+		Settings string `json:"settings"`
+	}
+
+	postUser := user{Settings: "invalid json"}
+	var userObj user
+
+	body, _ := json.Marshal(postUser)
+	req, _ := http.NewRequest("POST", "http://www.example.com", bytes.NewReader(body))
+
+	messages := MapData{
+		"settings": []string{"json:custom_message"},
+	}
+
+	rules := MapData{
+		"settings": []string{"json"},
+	}
+
+	opts := Options{
+		Request:  req,
+		Data:     &userObj,
+		Rules:    rules,
+		Messages: messages,
+	}
+
+	vd := New(opts)
+	validationErr := vd.ValidateJSON()
+	if validationErr.Get("settings") != "custom_message" {
+		t.Error("JSON custom message failed!")
+	}
+}
+
+func Test_LatLon(t *testing.T) {
+	type Location struct {
+		Latitude  string `json:"lat"`
+		Longitude string `json:"lon"`
+	}
+
+	postLocation := Location{Latitude: "invalid lat", Longitude: "invalid lon"}
+	var loc Location
+
+	body, _ := json.Marshal(postLocation)
+	req, _ := http.NewRequest("POST", "http://www.example.com", bytes.NewReader(body))
+
+	rules := MapData{
+		"lat": []string{"lat"},
+		"lon": []string{"lon"},
+	}
+
+	opts := Options{
+		Request: req,
+		Data:    &loc,
+		Rules:   rules,
+	}
+
+	vd := New(opts)
+	validationErr := vd.ValidateJSON()
+	if len(validationErr) != 2 {
+		t.Log(validationErr)
+		t.Error("Lat Lon validation failed!")
+	}
+}
+
+func Test_LatLon_valid(t *testing.T) {
+	type Location struct {
+		Latitude  string `json:"lat"`
+		Longitude string `json:"lon"`
+	}
+
+	postLocation := Location{Latitude: "23.810332", Longitude: "90.412518"}
+	var loc Location
+
+	body, _ := json.Marshal(postLocation)
+	req, _ := http.NewRequest("POST", "http://www.example.com", bytes.NewReader(body))
+
+	rules := MapData{
+		"lat": []string{"lat"},
+		"lon": []string{"lon"},
+	}
+
+	opts := Options{
+		Request: req,
+		Data:    &loc,
+		Rules:   rules,
+	}
+
+	vd := New(opts)
+	validationErr := vd.ValidateJSON()
+	if len(validationErr) != 0 {
+		t.Log(validationErr)
+		t.Error("Valid Lat Lon validation failed!")
+	}
+}
+
+func Test_LatLon_message(t *testing.T) {
+	type Location struct {
+		Latitude  string `json:"lat"`
+		Longitude string `json:"lon"`
+	}
+
+	postLocation := Location{Latitude: "invalid lat", Longitude: "invalid lon"}
+	var loc Location
+
+	body, _ := json.Marshal(postLocation)
+	req, _ := http.NewRequest("POST", "http://www.example.com", bytes.NewReader(body))
+
+	messages := MapData{
+		"lat": []string{"lat:custom_message"},
+		"lon": []string{"lon:custom_message"},
+	}
+
+	rules := MapData{
+		"lat": []string{"lat"},
+		"lon": []string{"lon"},
+	}
+
+	opts := Options{
+		Request:  req,
+		Data:     &loc,
+		Rules:    rules,
+		Messages: messages,
+	}
+
+	vd := New(opts)
+	validationErr := vd.ValidateJSON()
+	if validationErr.Get("lat") != "custom_message" ||
+		validationErr.Get("lon") != "custom_message" {
+		t.Error("Lat lon custom message failed")
+	}
+}
+
+func Test_Len(t *testing.T) {
+	type user struct {
+		Name        string   `json:"name"`
+		Roll        int      `json:"roll"`
+		Permissions []string `json:"permissions"`
+	}
+
+	postUser := user{
+		Name:        "john",
+		Roll:        11,
+		Permissions: []string{"create", "delete", "update"},
+	}
+	var userObj user
+
+	body, _ := json.Marshal(postUser)
+	req, _ := http.NewRequest("POST", "http://www.example.com", bytes.NewReader(body))
+
+	rules := MapData{
+		"name":        []string{"len:5"},
+		"roll":        []string{"len:5"},
+		"permissions": []string{"len:10"},
+	}
+
+	opts := Options{
+		Request: req,
+		Data:    &userObj,
+		Rules:   rules,
+	}
+
+	vd := New(opts)
+	validationErr := vd.ValidateJSON()
+	if len(validationErr) != 3 {
+		t.Log(validationErr)
+		t.Error("Len validation failed!")
+	}
+}
+
+func Test_Len_message(t *testing.T) {
+	type user struct {
+		Name        string   `json:"name"`
+		Roll        int      `json:"roll"`
+		Permissions []string `json:"permissions"`
+	}
+
+	postUser := user{
+		Name:        "john",
+		Roll:        11,
+		Permissions: []string{"create", "delete", "update"},
+	}
+	var userObj user
+
+	body, _ := json.Marshal(postUser)
+	req, _ := http.NewRequest("POST", "http://www.example.com", bytes.NewReader(body))
+
+	messages := MapData{
+		"name":        []string{"len:custom_message"},
+		"roll":        []string{"len:custom_message"},
+		"permissions": []string{"len:custom_message"},
+	}
+
+	rules := MapData{
+		"name":        []string{"len:5"},
+		"roll":        []string{"len:5"},
+		"permissions": []string{"len:10"},
+	}
+
+	opts := Options{
+		Request:  req,
+		Data:     &userObj,
+		Rules:    rules,
+		Messages: messages,
+	}
+
+	vd := New(opts)
+	validationErr := vd.ValidateJSON()
+	if validationErr.Get("name") != "custom_message" ||
+		validationErr.Get("roll") != "custom_message" ||
+		validationErr.Get("permissions") != "custom_message" {
+		t.Error("len custom message failed")
+	}
+}
+
+func Test_Numeric(t *testing.T) {
+	type user struct {
+		NID string `json:"nid"`
+	}
+
+	postUser := user{NID: "invalid nid"}
+	var userObj user
+
+	body, _ := json.Marshal(postUser)
+	req, _ := http.NewRequest("POST", "http://www.example.com", bytes.NewReader(body))
+
+	rules := MapData{
+		"nid": []string{"numeric"},
+	}
+
+	messages := MapData{
+		"nid": []string{"numeric:custom_message"},
+	}
+
+	opts := Options{
+		Request:  req,
+		Data:     &userObj,
+		Rules:    rules,
+		Messages: messages,
+	}
+
+	vd := New(opts)
+	validationErr := vd.ValidateJSON()
+	if len(validationErr) != 1 {
+		t.Log(validationErr)
+		t.Error("Numeric validation failed!")
+	}
+
+	if validationErr.Get("nid") != "custom_message" {
+		t.Error("Numeric custom message failed!")
+	}
+}
+
+func Test_Numeric_valid(t *testing.T) {
+	type user struct {
+		NID string `json:"nid"`
+	}
+
+	postUser := user{NID: "109922"}
+	var userObj user
+
+	body, _ := json.Marshal(postUser)
+	req, _ := http.NewRequest("POST", "http://www.example.com", bytes.NewReader(body))
+
+	rules := MapData{
+		"nid": []string{"numeric"},
+	}
+
+	messages := MapData{
+		"nid": []string{"numeric:custom_message"},
+	}
+
+	opts := Options{
+		Request:  req,
+		Data:     &userObj,
+		Rules:    rules,
+		Messages: messages,
+	}
+
+	vd := New(opts)
+	validationErr := vd.ValidateJSON()
+	if len(validationErr) != 0 {
+		t.Log(validationErr)
+		t.Error("Valid numeric validation failed!")
+	}
+}
+
+func Test_NumericBetween(t *testing.T) {
+	type user struct {
+		Age  int    `json:"age"`
+		CGPA string `json:"cgpa"`
+	}
+
+	postUser := user{Age: 77, CGPA: "2.90"}
+	var userObj user
+
+	body, _ := json.Marshal(postUser)
+	req, _ := http.NewRequest("POST", "http://www.example.com", bytes.NewReader(body))
+
+	rules := MapData{
+		"age":  []string{"numeric_between:18,60"},
+		"cgpa": []string{"numeric_between:3.5,4.9"},
+	}
+
+	messages := MapData{
+		"age":  []string{"numeric_between:custom_message"},
+		"cgpa": []string{"numeric_between:custom_message"},
+	}
+
+	opts := Options{
+		Request:  req,
+		Data:     &userObj,
+		Rules:    rules,
+		Messages: messages,
+	}
+
+	vd := New(opts)
+	validationErr := vd.ValidateJSON()
+	if len(validationErr) != 2 {
+		t.Error("numeric_between validation failed!")
+	}
+
+	if validationErr.Get("age") != "custom_message" ||
+		validationErr.Get("cgpa") != "custom_message" {
+		t.Error("numeric_between custom message failed!")
+	}
+}
+
+func Test_URL(t *testing.T) {
+	type user struct {
+		Web string `json:"web"`
+	}
+
+	postUser := user{Web: "invalid url"}
+	var userObj user
+
+	body, _ := json.Marshal(postUser)
+	req, _ := http.NewRequest("POST", "http://www.example.com", bytes.NewReader(body))
+
+	rules := MapData{
+		"web": []string{"url"},
+	}
+
+	messages := MapData{
+		"web": []string{"url:custom_message"},
+	}
+
+	opts := Options{
+		Request:  req,
+		Data:     &userObj,
+		Rules:    rules,
+		Messages: messages,
+	}
+
+	vd := New(opts)
+	validationErr := vd.ValidateJSON()
+	if len(validationErr) != 1 {
+		t.Log(validationErr)
+		t.Error("URL validation failed!")
+	}
+
+	if validationErr.Get("web") != "custom_message" {
+		t.Error("URL custom message failed!")
+	}
+}
+
+func Test_UR_valid(t *testing.T) {
+	type user struct {
+		Web string `json:"web"`
+	}
+
+	postUser := user{Web: "www.google.com"}
+	var userObj user
+
+	body, _ := json.Marshal(postUser)
+	req, _ := http.NewRequest("POST", "http://www.example.com", bytes.NewReader(body))
+
+	rules := MapData{
+		"web": []string{"url"},
+	}
+
+	messages := MapData{
+		"web": []string{"url:custom_message"},
+	}
+
+	opts := Options{
+		Request:  req,
+		Data:     &userObj,
+		Rules:    rules,
+		Messages: messages,
+	}
+
+	vd := New(opts)
+	validationErr := vd.ValidateJSON()
+	if len(validationErr) != 0 {
+		t.Error("Valid URL validation failed!")
+	}
+}
+
+func Test_UUIDS(t *testing.T) {
+	type user struct {
+		UUID   string `json:"uuid"`
+		UUIDV3 string `json:"uuid3"`
+		UUIDV4 string `json:"uuid4"`
+		UUIDV5 string `json:"uuid5"`
+	}
+
+	postUser := user{
+		UUID:   "invalid uuid",
+		UUIDV3: "invalid uuid",
+		UUIDV4: "invalid uuid",
+		UUIDV5: "invalid uuid",
+	}
+	var userObj user
+
+	body, _ := json.Marshal(postUser)
+	req, _ := http.NewRequest("POST", "http://www.example.com", bytes.NewReader(body))
+
+	rules := MapData{
+		"uuid":  []string{"uuid"},
+		"uuid3": []string{"uuid_v3"},
+		"uuid4": []string{"uuid_v4"},
+		"uuid5": []string{"uuid_v5"},
+	}
+
+	messages := MapData{
+		"uuid":  []string{"uuid:custom_message"},
+		"uuid3": []string{"uuid_v3:custom_message"},
+		"uuid4": []string{"uuid_v4:custom_message"},
+		"uuid5": []string{"uuid_v5:custom_message"},
+	}
+
+	opts := Options{
+		Request:  req,
+		Data:     &userObj,
+		Rules:    rules,
+		Messages: messages,
+	}
+
+	vd := New(opts)
+	validationErr := vd.ValidateJSON()
+	if len(validationErr) != 4 {
+		t.Error("UUID validation failed!")
+	}
+
+	if validationErr.Get("uuid") != "custom_message" ||
+		validationErr.Get("uuid3") != "custom_message" ||
+		validationErr.Get("uuid4") != "custom_message" ||
+		validationErr.Get("uuid5") != "custom_message" {
+		t.Error("UUID custom message failed!")
+	}
+
+}
+
+func Test_min(t *testing.T) {
+	type Body struct {
+		Str     string   `json:"_str"`
+		Slice   []string `json:"_slice"`
+		Int     int      `json:"_int"`
+		Int8    int8     `json:"_int8"`
+		Int16   int16    `json:"_int16"`
+		Int32   int32    `json:"_int32"`
+		Int64   int64    `json:"_int64"`
+		Uint    uint     `json:"_uint"`
+		Uint8   uint8    `json:"_uint8"`
+		Uint16  uint16   `json:"_uint16"`
+		Uint32  uint32   `json:"_uint32"`
+		Uint64  uint64   `json:"_uint64"`
+		Uintptr uintptr  `json:"_uintptr"`
+		Float32 float32  `json:"_float32"`
+		Float64 float64  `json:"_float64"`
+	}
+
+	postBody := Body{
+		Str:     "xyz",
+		Slice:   []string{"x", "y"},
+		Int:     2,
+		Int8:    2,
+		Int16:   2,
+		Int32:   2,
+		Int64:   2,
+		Uint:    2,
+		Uint8:   2,
+		Uint16:  2,
+		Uint32:  2,
+		Uint64:  2,
+		Uintptr: 2,
+		Float32: 2.4,
+		Float64: 3.2,
+	}
+
+	var bodyObj Body
+
+	body, _ := json.Marshal(postBody)
+	req, _ := http.NewRequest("POST", "http://www.example.com", bytes.NewReader(body))
+
+	rules := MapData{
+		"_str":     []string{"min:5"},
+		"_slice":   []string{"min:5"},
+		"_int":     []string{"min:5"},
+		"_int8":    []string{"min:5"},
+		"_int16":   []string{"min:5"},
+		"_int32":   []string{"min:5"},
+		"_int64":   []string{"min:5"},
+		"_uint":    []string{"min:5"},
+		"_uint8":   []string{"min:5"},
+		"_uint16":  []string{"min:5"},
+		"_uint32":  []string{"min:5"},
+		"_uint64":  []string{"min:5"},
+		"_uintptr": []string{"min:5"},
+		"_float32": []string{"min:5"},
+		"_float64": []string{"min:5"},
+	}
+
+	messages := MapData{
+		"_str":     []string{"min:custom_message"},
+		"_slice":   []string{"min:custom_message"},
+		"_int":     []string{"min:custom_message"},
+		"_uint":    []string{"min:custom_message"},
+		"_float32": []string{"min:custom_message"},
+	}
+
+	opts := Options{
+		Request:  req,
+		Data:     &bodyObj,
+		Rules:    rules,
+		Messages: messages,
+	}
+
+	vd := New(opts)
+	validationErr := vd.ValidateJSON()
+	if len(validationErr) != 15 {
+		t.Error("min validation failed!")
+	}
+
+	if validationErr.Get("_str") != "custom_message" ||
+		validationErr.Get("_slice") != "custom_message" ||
+		validationErr.Get("_int") != "custom_message" ||
+		validationErr.Get("_uint") != "custom_message" ||
+		validationErr.Get("_float32") != "custom_message" {
+		t.Error("min custom message failed!")
+	}
+}
+
+func Test_max(t *testing.T) {
+	type Body struct {
+		Str     string   `json:"_str"`
+		Slice   []string `json:"_slice"`
+		Int     int      `json:"_int"`
+		Int8    int8     `json:"_int8"`
+		Int16   int16    `json:"_int16"`
+		Int32   int32    `json:"_int32"`
+		Int64   int64    `json:"_int64"`
+		Uint    uint     `json:"_uint"`
+		Uint8   uint8    `json:"_uint8"`
+		Uint16  uint16   `json:"_uint16"`
+		Uint32  uint32   `json:"_uint32"`
+		Uint64  uint64   `json:"_uint64"`
+		Uintptr uintptr  `json:"_uintptr"`
+		Float32 float32  `json:"_float32"`
+		Float64 float64  `json:"_float64"`
+	}
+
+	postBody := Body{
+		Str:     "xyzabc",
+		Slice:   []string{"x", "y", "z"},
+		Int:     20,
+		Int8:    20,
+		Int16:   20,
+		Int32:   20,
+		Int64:   20,
+		Uint:    20,
+		Uint8:   20,
+		Uint16:  20,
+		Uint32:  20,
+		Uint64:  20,
+		Uintptr: 20,
+		Float32: 20.4,
+		Float64: 30.2,
+	}
+
+	var bodyObj Body
+
+	body, _ := json.Marshal(postBody)
+	req, _ := http.NewRequest("POST", "http://www.example.com", bytes.NewReader(body))
+
+	rules := MapData{
+		"_str":     []string{"max:5"},
+		"_slice":   []string{"max:2"},
+		"_int":     []string{"max:5"},
+		"_int8":    []string{"max:5"},
+		"_int16":   []string{"max:5"},
+		"_int32":   []string{"max:5"},
+		"_int64":   []string{"max:5"},
+		"_uint":    []string{"max:5"},
+		"_uint8":   []string{"max:5"},
+		"_uint16":  []string{"max:5"},
+		"_uint32":  []string{"max:5"},
+		"_uint64":  []string{"max:5"},
+		"_uintptr": []string{"max:5"},
+		"_float32": []string{"max:5"},
+		"_float64": []string{"max:5"},
+	}
+
+	messages := MapData{
+		"_str":     []string{"max:custom_message"},
+		"_slice":   []string{"max:custom_message"},
+		"_int":     []string{"max:custom_message"},
+		"_uint":    []string{"max:custom_message"},
+		"_float32": []string{"max:custom_message"},
+	}
+
+	opts := Options{
+		Request:  req,
+		Data:     &bodyObj,
+		Rules:    rules,
+		Messages: messages,
+	}
+
+	vd := New(opts)
+	validationErr := vd.ValidateJSON()
+	if len(validationErr) != 15 {
+		t.Error(validationErr)
+		t.Error("max validation failed!")
+	}
+
+	if validationErr.Get("_str") != "custom_message" ||
+		validationErr.Get("_slice") != "custom_message" ||
+		validationErr.Get("_int") != "custom_message" ||
+		validationErr.Get("_uint") != "custom_message" ||
+		validationErr.Get("_float32") != "custom_message" {
+		t.Error("max custom message failed!")
+	}
+}
+
+func Test_In(t *testing.T) {
+	type user struct {
+		Input string `json:"input"`
+	}
+
+	postUser := user{Input: "4"}
+	var userObj user
+
+	body, _ := json.Marshal(postUser)
+	req, _ := http.NewRequest("POST", "http://www.example.com", bytes.NewReader(body))
+
+	messages := MapData{
+		"input": []string{"in:custom_message"},
+	}
+
+	rules := MapData{
+		"input": []string{"in:1,2,3"},
+	}
+
+	opts := Options{
+		Request:  req,
+		Data:     &userObj,
+		Rules:    rules,
+		Messages: messages,
+	}
+
+	vd := New(opts)
+	validationErr := vd.ValidateJSON()
+	if len(validationErr) != 1 {
+		t.Error("in validation failed!")
+	}
+
+	if validationErr.Get("input") != "custom_message" {
+		t.Error("in custom message failed!")
+	}
+}
+
+func Test_In_valid(t *testing.T) {
+	type user struct {
+		Input string `json:"input"`
+	}
+
+	postUser := user{Input: "1"}
+	var userObj user
+
+	body, _ := json.Marshal(postUser)
+	req, _ := http.NewRequest("POST", "http://www.example.com", bytes.NewReader(body))
+
+	messages := MapData{
+		"input": []string{"in:custom_message"},
+	}
+
+	rules := MapData{
+		"input": []string{"in:1,2,3"},
+	}
+
+	opts := Options{
+		Request:  req,
+		Data:     &userObj,
+		Rules:    rules,
+		Messages: messages,
+	}
+
+	vd := New(opts)
+	validationErr := vd.ValidateJSON()
+	if len(validationErr) != 0 {
+		t.Error("in validation was triggered when valid!")
+	}
+}
+
+func Test_In_string(t *testing.T) {
+	type user struct {
+		Input string `json:"input"`
+	}
+
+	postUser := user{Input: "bob"}
+	var userObj user
+
+	body, _ := json.Marshal(postUser)
+	req, _ := http.NewRequest("POST", "http://www.example.com", bytes.NewReader(body))
+
+	messages := MapData{
+		"input": []string{"in:custom_message"},
+	}
+
+	rules := MapData{
+		"input": []string{"in:tom,dick,harry"},
+	}
+
+	opts := Options{
+		Request:  req,
+		Data:     &userObj,
+		Rules:    rules,
+		Messages: messages,
+	}
+
+	vd := New(opts)
+	validationErr := vd.ValidateJSON()
+	if len(validationErr) != 1 {
+		t.Error("in validation failed!")
+	}
+
+	if validationErr.Get("input") != "custom_message" {
+		t.Error("in custom message failed!")
+	}
+}
+
+func Test_In_string_valid(t *testing.T) {
+	type user struct {
+		Input string `json:"input"`
+	}
+
+	postUser := user{Input: "dick"}
+	var userObj user
+
+	body, _ := json.Marshal(postUser)
+	req, _ := http.NewRequest("POST", "http://www.example.com", bytes.NewReader(body))
+
+	messages := MapData{
+		"input": []string{"in:custom_message"},
+	}
+
+	rules := MapData{
+		"input": []string{"in:tom,dick,harry"},
+	}
+
+	opts := Options{
+		Request:  req,
+		Data:     &userObj,
+		Rules:    rules,
+		Messages: messages,
+	}
+
+	vd := New(opts)
+	validationErr := vd.ValidateJSON()
+	if len(validationErr) != 0 {
+		t.Error("in validation was triggered when valid!")
+	}
+}
+
+func Test_NotIn(t *testing.T) {
+	type user struct {
+		Input string `json:"input"`
+	}
+
+	postUser := user{Input: "2"}
+	var userObj user
+
+	body, _ := json.Marshal(postUser)
+	req, _ := http.NewRequest("POST", "http://www.example.com", bytes.NewReader(body))
+
+	messages := MapData{
+		"input": []string{"not_in:custom_message"},
+	}
+
+	rules := MapData{
+		"input": []string{"not_in:1,2,3"},
+	}
+
+	opts := Options{
+		Request:  req,
+		Data:     &userObj,
+		Rules:    rules,
+		Messages: messages,
+	}
+
+	vd := New(opts)
+	validationErr := vd.ValidateJSON()
+	if len(validationErr) != 1 {
+		t.Error("not_in validation failed!")
+	}
+
+	if validationErr.Get("input") != "custom_message" {
+		t.Error("not_in custom message failed!")
+	}
+}
+
+func Test_NotIn_valid(t *testing.T) {
+	type user struct {
+		Input string `json:"input"`
+	}
+
+	postUser := user{Input: "4"}
+	var userObj user
+
+	body, _ := json.Marshal(postUser)
+	req, _ := http.NewRequest("POST", "http://www.example.com", bytes.NewReader(body))
+
+	messages := MapData{
+		"input": []string{"not_in:custom_message"},
+	}
+
+	rules := MapData{
+		"input": []string{"not_in:1,2,3"},
+	}
+
+	opts := Options{
+		Request:  req,
+		Data:     &userObj,
+		Rules:    rules,
+		Messages: messages,
+	}
+
+	vd := New(opts)
+	validationErr := vd.ValidateJSON()
+	if len(validationErr) != 0 {
+		t.Error("not_in validation was triggered when valid!")
+	}
+}
+
+func Test_NotIn_string(t *testing.T) {
+	type user struct {
+		Input string `json:"input"`
+	}
+
+	postUser := user{Input: "harry"}
+	var userObj user
+
+	body, _ := json.Marshal(postUser)
+	req, _ := http.NewRequest("POST", "http://www.example.com", bytes.NewReader(body))
+
+	messages := MapData{
+		"input": []string{"not_in:custom_message"},
+	}
+
+	rules := MapData{
+		"input": []string{"not_in:tom,dick,harry"},
+	}
+
+	opts := Options{
+		Request:  req,
+		Data:     &userObj,
+		Rules:    rules,
+		Messages: messages,
+	}
+
+	vd := New(opts)
+	validationErr := vd.ValidateJSON()
+	if len(validationErr) != 1 {
+		t.Error("not_in validation failed!")
+	}
+
+	if validationErr.Get("input") != "custom_message" {
+		t.Error("not_in custom message failed!")
+	}
+}
+
+func Test_NotIn_string_valid(t *testing.T) {
+	type user struct {
+		Input string `json:"input"`
+	}
+
+	postUser := user{Input: "bob"}
+	var userObj user
+
+	body, _ := json.Marshal(postUser)
+	req, _ := http.NewRequest("POST", "http://www.example.com", bytes.NewReader(body))
+
+	messages := MapData{
+		"input": []string{"not_in:custom_message"},
+	}
+
+	rules := MapData{
+		"input": []string{"not_in:tom,dick,harry"},
+	}
+
+	opts := Options{
+		Request:  req,
+		Data:     &userObj,
+		Rules:    rules,
+		Messages: messages,
+	}
+
+	vd := New(opts)
+	validationErr := vd.ValidateJSON()
+	if len(validationErr) != 0 {
+		t.Error("not_in validation was triggered when valid!")
+	}
+}
diff --git a/validationmdl/validationcore/type.go b/validationmdl/validationcore/type.go
new file mode 100644
index 0000000000000000000000000000000000000000..3f5109b7106da6300ce08a70c26dba68b25884b7
--- /dev/null
+++ b/validationmdl/validationcore/type.go
@@ -0,0 +1,133 @@
+package govalidator
+
+import (
+	"bytes"
+	"encoding/json"
+)
+
+// Int describes a custom type of built-in int data type
+type Int struct {
+	Value int  `json:"value"`
+	IsSet bool `json:"isSet"`
+}
+
+var null = []byte("null")
+
+// UnmarshalJSON ...
+func (i *Int) UnmarshalJSON(data []byte) error {
+	if bytes.Compare(data, null) == 0 {
+		return nil
+	}
+	i.IsSet = true
+	var temp int
+	if err := json.Unmarshal(data, &temp); err != nil {
+		return err
+	}
+	i.Value = temp
+	return nil
+}
+
+// MarshalJSON ...
+func (i *Int) MarshalJSON() ([]byte, error) {
+	return json.Marshal(i.Value)
+}
+
+// Int64 describes a custom type of built-in int64 data type
+type Int64 struct {
+	Value int64 `json:"value"`
+	IsSet bool  `json:"isSet"`
+}
+
+// UnmarshalJSON ...
+func (i *Int64) UnmarshalJSON(data []byte) error {
+	if bytes.Compare(data, null) == 0 {
+		return nil
+	}
+	i.IsSet = true
+	var temp int64
+	if err := json.Unmarshal(data, &temp); err != nil {
+		return err
+	}
+	i.Value = temp
+	return nil
+}
+
+// MarshalJSON ...
+func (i *Int64) MarshalJSON() ([]byte, error) {
+	return json.Marshal(i.Value)
+}
+
+// Float32 describes a custom type of built-in float32 data type
+type Float32 struct {
+	Value float32 `json:"value"`
+	IsSet bool    `json:"isSet"`
+}
+
+// UnmarshalJSON ...
+func (i *Float32) UnmarshalJSON(data []byte) error {
+	if bytes.Compare(data, null) == 0 {
+		return nil
+	}
+	i.IsSet = true
+	var temp float32
+	if err := json.Unmarshal(data, &temp); err != nil {
+		return err
+	}
+	i.Value = temp
+	return nil
+}
+
+// MarshalJSON ...
+func (i *Float32) MarshalJSON() ([]byte, error) {
+	return json.Marshal(i.Value)
+}
+
+// Float64 describes a custom type of built-in float64 data type
+type Float64 struct {
+	Value float64 `json:"value"`
+	IsSet bool    `json:"isSet"`
+}
+
+// UnmarshalJSON ...
+func (i *Float64) UnmarshalJSON(data []byte) error {
+	if bytes.Compare(data, null) == 0 {
+		return nil
+	}
+	i.IsSet = true
+	var temp float64
+	if err := json.Unmarshal(data, &temp); err != nil {
+		return err
+	}
+	i.Value = temp
+	return nil
+}
+
+// MarshalJSON ...
+func (i *Float64) MarshalJSON() ([]byte, error) {
+	return json.Marshal(i.Value)
+}
+
+// Bool describes a custom type of built-in bool data type
+type Bool struct {
+	Value bool `json:"value"`
+	IsSet bool `json:"isSet"`
+}
+
+// UnmarshalJSON ...
+func (i *Bool) UnmarshalJSON(data []byte) error {
+	if bytes.Compare(data, null) == 0 {
+		return nil
+	}
+	i.IsSet = true
+	var temp bool
+	if err := json.Unmarshal(data, &temp); err != nil {
+		return err
+	}
+	i.Value = temp
+	return nil
+}
+
+// MarshalJSON ...
+func (i *Bool) MarshalJSON() ([]byte, error) {
+	return json.Marshal(i.Value)
+}
diff --git a/validationmdl/validationcore/utils.go b/validationmdl/validationcore/utils.go
new file mode 100644
index 0000000000000000000000000000000000000000..f8a271577dbba592e8964b6b666942cfbcc64d81
--- /dev/null
+++ b/validationmdl/validationcore/utils.go
@@ -0,0 +1,57 @@
+package govalidator
+
+import (
+	"fmt"
+	"reflect"
+	"strings"
+)
+
+// containsRequiredField check rules contain any required field
+func isContainRequiredField(rules []string) bool {
+	for _, rule := range rules {
+		if rule == "required" {
+			return true
+		}
+	}
+	return false
+}
+
+// isRuleExist check if the provided rule name is exist or not
+func isRuleExist(rule string) bool {
+	if strings.Contains(rule, ":") {
+		rule = strings.Split(rule, ":")[0]
+	}
+	extendedRules := []string{"size", "mime", "ext"}
+	for _, r := range extendedRules {
+		if r == rule {
+			return true
+		}
+	}
+	if _, ok := rulesFuncMap[rule]; ok {
+		return true
+	}
+	return false
+}
+
+// toString force data to be string
+func toString(v interface{}) string {
+	str, ok := v.(string)
+	if !ok {
+		str = fmt.Sprintf("%#v", v)
+	}
+	return str
+}
+
+// isEmpty check a type is Zero
+func isEmpty(x interface{}) bool {
+	rt := reflect.TypeOf(x)
+	if rt == nil {
+		return true
+	}
+	rv := reflect.ValueOf(x)
+	switch rv.Kind() {
+	case reflect.Array, reflect.Map, reflect.Slice:
+		return rv.Len() == 0
+	}
+	return reflect.DeepEqual(x, reflect.Zero(rt).Interface())
+}
diff --git a/validationmdl/validationcore/utils110.go b/validationmdl/validationcore/utils110.go
new file mode 100644
index 0000000000000000000000000000000000000000..8742d7482eb7b90eafb2e812a67f548a4ec99d20
--- /dev/null
+++ b/validationmdl/validationcore/utils110.go
@@ -0,0 +1,55 @@
+// +build go1.10
+
+package govalidator
+
+import (
+	"io"
+	"net/http"
+	"path/filepath"
+	"strings"
+)
+
+// getFileInfo read file from request and return file name, extension, mime and size
+func getFileInfo(r *http.Request, field string) (bool, string, string, string, int64, error) {
+	file, multipartFileHeader, err := r.FormFile(field)
+	if err != nil {
+		return false, "", "", "", 0, err
+	}
+	// Create a buffer to store the header of the file in
+	fileHeader := make([]byte, 512)
+
+	// Copy the headers into the FileHeader buffer
+	if _, err := file.Read(fileHeader); err != nil {
+		if err != io.EOF {
+			return false, "", "", "", 0, err
+		}
+	}
+
+	// set position back to start.
+	if _, err := file.Seek(0, 0); err != nil {
+		return false, "", "", "", 0, err
+	}
+
+	mime := http.DetectContentType(fileHeader)
+	if subs := "; charset=utf-8"; strings.Contains(mime, subs) {
+		mime = strings.Replace(mime, subs, "", -1)
+	}
+	if subs := ";charset=utf-8"; strings.Contains(mime, subs) {
+		mime = strings.Replace(mime, subs, "", -1)
+	}
+	if subs := "; charset=UTF-8"; strings.Contains(mime, subs) {
+		mime = strings.Replace(mime, subs, "", -1)
+	}
+	if subs := ";charset=UTF-8"; strings.Contains(mime, subs) {
+		mime = strings.Replace(mime, subs, "", -1)
+	}
+	fExist := false
+	if file != nil {
+		fExist = true
+	}
+	return fExist, multipartFileHeader.Filename,
+		strings.TrimPrefix(filepath.Ext(multipartFileHeader.Filename), "."),
+		strings.TrimSpace(mime),
+		multipartFileHeader.Size,
+		nil
+}
diff --git a/validationmdl/validationcore/utils_pre110.go b/validationmdl/validationcore/utils_pre110.go
new file mode 100644
index 0000000000000000000000000000000000000000..58ce6cad8ac27d68c2d008837a738d8d83a4a30e
--- /dev/null
+++ b/validationmdl/validationcore/utils_pre110.go
@@ -0,0 +1,60 @@
+// +build !go1.10
+
+package govalidator
+
+import (
+	"io"
+	"net/http"
+	"path/filepath"
+	"strings"
+)
+
+// Sizer interface
+type Sizer interface {
+	Size() int64
+}
+
+// getFileInfo read file from request and return file name, extension, mime and size
+func getFileInfo(r *http.Request, field string) (bool, string, string, string, int64, error) {
+	file, multipartFileHeader, err := r.FormFile(field)
+	if err != nil {
+		return false, "", "", "", 0, err
+	}
+	// Create a buffer to store the header of the file in
+	fileHeader := make([]byte, 512)
+
+	// Copy the headers into the FileHeader buffer
+	if _, err := file.Read(fileHeader); err != nil {
+		if err != io.EOF {
+			return false, "", "", "", 0, err
+		}
+	}
+
+	// set position back to start.
+	if _, err := file.Seek(0, 0); err != nil {
+		return false, "", "", "", 0, err
+	}
+
+	mime := http.DetectContentType(fileHeader)
+	if subs := "; charset=utf-8"; strings.Contains(mime, subs) {
+		mime = strings.Replace(mime, subs, "", -1)
+	}
+	if subs := ";charset=utf-8"; strings.Contains(mime, subs) {
+		mime = strings.Replace(mime, subs, "", -1)
+	}
+	if subs := "; charset=UTF-8"; strings.Contains(mime, subs) {
+		mime = strings.Replace(mime, subs, "", -1)
+	}
+	if subs := ";charset=UTF-8"; strings.Contains(mime, subs) {
+		mime = strings.Replace(mime, subs, "", -1)
+	}
+	fExist := false
+	if file != nil {
+		fExist = true
+	}
+	return fExist, multipartFileHeader.Filename,
+		strings.TrimPrefix(filepath.Ext(multipartFileHeader.Filename), "."),
+		strings.TrimSpace(mime),
+		file.(Sizer).Size(),
+		nil
+}
diff --git a/validationmdl/validationcore/utils_test.go b/validationmdl/validationcore/utils_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..4ef77a19f0e998ff4dc43a0a921af2bf5f9764d4
--- /dev/null
+++ b/validationmdl/validationcore/utils_test.go
@@ -0,0 +1,100 @@
+package govalidator
+
+import (
+	"reflect"
+	"strings"
+	"testing"
+)
+
+func Test_isContainRequiredField(t *testing.T) {
+	if !isContainRequiredField([]string{"required", "email"}) {
+		t.Error("isContainRequiredField failed!")
+	}
+
+	if isContainRequiredField([]string{"numeric", "min:5"}) {
+		t.Error("isContainRequiredField failed!")
+	}
+}
+
+func Benchmark_isContainRequiredField(b *testing.B) {
+	for n := 0; n < b.N; n++ {
+		isContainRequiredField([]string{"required", "email"})
+	}
+}
+
+type person struct{}
+
+func (person) Details() string {
+	return "John Doe"
+}
+
+func (person) Age(age string) string {
+	return "Age: " + age
+}
+
+func Test_isRuleExist(t *testing.T) {
+	if !isRuleExist("required") {
+		t.Error("isRuleExist failed for valid rule")
+	}
+	if isRuleExist("not exist") {
+		t.Error("isRuleExist failed for invalid rule")
+	}
+	if !isRuleExist("mime") {
+		t.Error("extended rules failed")
+	}
+}
+
+func Test_toString(t *testing.T) {
+	Int := 100
+	str := toString(Int)
+	typ := reflect.ValueOf(str).Kind()
+	if typ != reflect.String {
+		t.Error("toString failed!")
+	}
+}
+
+func Test_isEmpty(t *testing.T) {
+	var Int int
+	var Int8 int
+	var Float32 float32
+	var Str string
+	var Slice []int
+	var e interface{}
+	list := map[string]interface{}{
+		"_int":             Int,
+		"_int8":            Int8,
+		"_float32":         Float32,
+		"_str":             Str,
+		"_slice":           Slice,
+		"_empty_interface": e,
+	}
+	for k, v := range list {
+		if !isEmpty(v) {
+			t.Errorf("%v failed", k)
+		}
+	}
+}
+
+func Test_getFileInfo(t *testing.T) {
+	req, err := buildMocFormReq()
+	if err != nil {
+		t.Error("request failed", err)
+	}
+	fExist, fn, ext, mime, size, _ := getFileInfo(req, "file")
+	if !fExist {
+		t.Error("file does not exist")
+	}
+	if fn != "BENCHMARK.md" {
+		t.Error("failed to get file name")
+	}
+	if ext != "md" {
+		t.Error("failed to get file extension")
+	}
+	if !strings.Contains(mime, "text/plain") {
+		t.Log(mime)
+		t.Error("failed to get file mime")
+	}
+	if size <= 0 {
+		t.Error("failed to get file size")
+	}
+}
diff --git a/validationmdl/validationcore/validate_file.go b/validationmdl/validationcore/validate_file.go
new file mode 100644
index 0000000000000000000000000000000000000000..cedf4ed53a14342d673cf5ff3a5424ebc4106ae6
--- /dev/null
+++ b/validationmdl/validationcore/validate_file.go
@@ -0,0 +1,73 @@
+package govalidator
+
+import (
+	"fmt"
+	"net/http"
+	"net/url"
+	"strconv"
+	"strings"
+)
+
+// validateFiles validate file size, mimes, extension etc
+func validateFiles(r *http.Request, field, rule, msg string, errsBag url.Values) {
+	_, _, ext, mime, size, fErr := getFileInfo(r, field)
+	// check size
+	if strings.HasPrefix(rule, "size:") {
+		l, err := strconv.ParseInt(strings.TrimPrefix(rule, "size:"), 10, 64)
+		if err != nil {
+			panic(errStringToInt)
+		}
+		if size > l {
+			if msg != "" {
+				errsBag.Add(field, msg)
+			} else {
+				errsBag.Add(field, fmt.Sprintf("The %s field size is can not be greater than %d bytes", field, l))
+			}
+		}
+		if fErr != nil {
+			errsBag.Add(field, fmt.Sprintf("The %s field failed to read file when fetching size", field))
+		}
+	}
+
+	// check extension
+	if strings.HasPrefix(rule, "ext:") {
+		exts := strings.Split(strings.TrimPrefix(rule, "ext:"), ",")
+		f := false
+		for _, e := range exts {
+			if e == ext {
+				f = true
+			}
+		}
+		if !f {
+			if msg != "" {
+				errsBag.Add(field, msg)
+			} else {
+				errsBag.Add(field, fmt.Sprintf("The %s field file extension %s is invalid", field, ext))
+			}
+		}
+		if fErr != nil {
+			errsBag.Add(field, fmt.Sprintf("The %s field failed to read file when fetching extension", field))
+		}
+	}
+
+	// check mimes
+	if strings.HasPrefix(rule, "mime:") {
+		mimes := strings.Split(strings.TrimPrefix(rule, "mime:"), ",")
+		f := false
+		for _, m := range mimes {
+			if m == mime {
+				f = true
+			}
+		}
+		if !f {
+			if msg != "" {
+				errsBag.Add(field, msg)
+			} else {
+				errsBag.Add(field, fmt.Sprintf("The %s field file mime %s is invalid", field, mime))
+			}
+		}
+		if fErr != nil {
+			errsBag.Add(field, fmt.Sprintf("The %s field failed to read file when fetching mime", field))
+		}
+	}
+}
diff --git a/validationmdl/validationcore/validate_file_test.go b/validationmdl/validationcore/validate_file_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..1f122876b6cebfb8d4f3f59b8aae7e05f2553956
--- /dev/null
+++ b/validationmdl/validationcore/validate_file_test.go
@@ -0,0 +1,141 @@
+package govalidator
+
+import (
+	"bytes"
+	"io"
+	"mime/multipart"
+	"net/http"
+	"os"
+	"path/filepath"
+	"testing"
+)
+
+// buildMocFormReq prepare a moc form data request with a test file
+func buildMocFormReq() (*http.Request, error) {
+	fPath := "doc/BENCHMARK.md"
+	body := &bytes.Buffer{}
+	writer := multipart.NewWriter(body)
+	file, err := os.Open(fPath)
+	if err != nil {
+		return nil, err
+	}
+	part, err := writer.CreateFormFile("file", filepath.Base(fPath))
+	if err != nil {
+		return nil, err
+	}
+	io.Copy(part, file)
+	file.Close()
+	err = writer.Close()
+	if err != nil {
+		return nil, err
+	}
+
+	req, err := http.NewRequest("POST", "www.example.com", body)
+	if err != nil {
+		return nil, err
+	}
+	req.Header.Set("Content-Type", writer.FormDataContentType())
+	return req, nil
+}
+
+func Test_validateFiles(t *testing.T) {
+	req, err := buildMocFormReq()
+	if err != nil {
+		t.Error("request failed", err)
+	}
+	rules := MapData{
+		"file:file": []string{"ext:jpg,pdf", "size:10", "mime:application/pdf", "required"},
+	}
+
+	opts := Options{
+		Request: req,
+		Rules:   rules,
+	}
+
+	vd := New(opts)
+	validationErr := vd.Validate()
+	if len(validationErr) != 1 {
+		t.Error("file validation failed!")
+	}
+}
+
+func Test_validateFiles_message(t *testing.T) {
+	req, err := buildMocFormReq()
+	if err != nil {
+		t.Error("request failed", err)
+	}
+	rules := MapData{
+		"file:file": []string{"ext:jpg,pdf", "size:10", "mime:application/pdf", "required"},
+	}
+
+	msgs := MapData{
+		"file:file": []string{"ext:custom_message"},
+	}
+
+	opts := Options{
+		Request:  req,
+		Rules:    rules,
+		Messages: msgs,
+	}
+
+	vd := New(opts)
+	validationErr := vd.Validate()
+	if len(validationErr) != 1 {
+		t.Error("file validation failed!")
+	}
+	if validationErr.Get("file") != "custom_message" {
+		t.Log(validationErr)
+		t.Error("failed custom message for file validation")
+	}
+}
+
+func Test_validateFiles_CustomRule(t *testing.T) {
+	req, err := buildMocFormReq()
+	if err != nil {
+		t.Error("request failed", err)
+	}
+
+	customRule1WasExecuted := false
+	isMultipartFile := false
+	AddCustomRule("customRule1", func(field string, rule string, message string, value interface{}) error {
+		customRule1WasExecuted = true
+		_, isMultipartFile = value.(multipart.File)
+		return nil
+	})
+
+	customRule2WasExecuted := false
+	isValueNil := false
+	AddCustomRule("customRule2", func(field string, rule string, message string, value interface{}) error {
+		customRule2WasExecuted = true
+		isValueNil = value == nil
+		return nil
+	})
+
+	rules := MapData{
+		"file:file":   []string{"customRule1"},
+		"file:avatar": []string{"customRule2"},
+	}
+
+	opts := Options{
+		Request: req,
+		Rules:   rules,
+	}
+
+	vd := New(opts)
+	vd.Validate()
+	if !customRule1WasExecuted {
+		t.Error("file validation performed without custom rule!")
+	}
+
+	if !isMultipartFile {
+		t.Error("passed to custom rule value is not file!")
+	}
+
+	if !customRule2WasExecuted {
+		t.Error("file validation performed without custom rule!")
+	}
+
+	if !isValueNil {
+		t.Error("passed to custom rule value is not nil!")
+	}
+}
diff --git a/validationmdl/validationcore/validator.go b/validationmdl/validationcore/validator.go
new file mode 100644
index 0000000000000000000000000000000000000000..503339040da07db6b64b1edb354258910b67850d
--- /dev/null
+++ b/validationmdl/validationcore/validator.go
@@ -0,0 +1,294 @@
+package govalidator
+
+import (
+	"encoding/json"
+	"fmt"
+	"net/http"
+	"net/url"
+	"reflect"
+	"strings"
+)
+
+const (
+	tagIdentifier         = "json" //tagName idetify the struct tag for govalidator
+	tagSeparator          = "|"    //tagSeparator use to separate tags in struct
+	defaultFormSize int64 = 1024 * 1024 * 1
+)
+
+type (
+	// MapData represents basic data structure for govalidator Rules and Messages
+	MapData map[string][]string
+
+	// Options describes configuration option for validator
+	Options struct {
+		Data            interface{} // Data represents structure for JSON body
+		Request         *http.Request
+		RequiredDefault bool    // RequiredDefault represents if all the fields are by default required or not
+		Rules           MapData // Rules represents rules for form-data/x-url-encoded/query params data
+		Messages        MapData // Messages represents custom/localize message for rules
+		TagIdentifier   string  // TagIdentifier represents struct tag identifier, e.g: json or validate etc
+		FormSize        int64   //Form represents the multipart forom data max memory size in bytes
+		JSONData        []byte  // For validating JSON data
+	}
+
+	// Validator represents a validator with options
+	Validator struct {
+		Opts Options // Opts contains all the options for validator
+	}
+)
+
+// New return a new validator object using provided options
+func New(opts Options) *Validator {
+	return &Validator{Opts: opts}
+}
+
+// getMessage return if a custom message exist against the field name and rule
+// if not available it return an empty string
+func (v *Validator) getCustomMessage(field, rule string) string {
+	tmp := rule + ":"
+	if msgList, ok := v.Opts.Messages[field]; ok {
+		for _, m := range msgList {
+			//if rules has params, remove params. e.g: between:3,5 would be between
+			if strings.Contains(rule, ":") {
+				rule = strings.Split(rule, ":")[0]
+			}
+			if strings.HasPrefix(m, tmp) {
+				return strings.TrimPrefix(m, tmp)
+			}
+		}
+	}
+	return ""
+}
+
+// SetDefaultRequired change the required behavior of fields
+// Default value if false
+// If SetDefaultRequired set to true then it will mark all the field in the rules list as required
+func (v *Validator) SetDefaultRequired(required bool) {
+	v.Opts.RequiredDefault = required
+}
+
+// SetTagIdentifier change the default tag identifier (json) to your custom tag.
+func (v *Validator) SetTagIdentifier(identifier string) {
+	v.Opts.TagIdentifier = identifier
+}
+
+// Validate validate request data like form-data, x-www-form-urlencoded and query params
+// see example in README.md file
+// ref: https://github.com/thedevsaddam/govalidator#example
+func (v *Validator) Validate() url.Values {
+	// if request object and rules not passed rise a panic
+	if len(v.Opts.Rules) == 0 || v.Opts.Request == nil {
+		panic(errValidateArgsMismatch)
+	}
+	errsBag := url.Values{}
+
+	// get non required rules
+	nr := v.getNonRequiredFields()
+
+	for field, rules := range v.Opts.Rules {
+		if _, ok := nr[field]; ok {
+			continue
+		}
+		for _, rule := range rules {
+			if !isRuleExist(rule) {
+				panic(fmt.Errorf("govalidator: %s is not a valid rule", rule))
+			}
+			msg := v.getCustomMessage(field, rule)
+			// validate file
+			if strings.HasPrefix(field, "file:") {
+				fld := strings.TrimPrefix(field, "file:")
+				file, fh, _ := v.Opts.Request.FormFile(fld)
+				if file != nil && fh.Filename != "" {
+					validateFiles(v.Opts.Request, fld, rule, msg, errsBag)
+					validateCustomRules(fld, rule, msg, file, errsBag)
+				} else {
+					validateCustomRules(fld, rule, msg, nil, errsBag)
+				}
+			} else {
+				// validate if custom rules exist
+				reqVal := strings.TrimSpace(v.Opts.Request.Form.Get(field))
+				validateCustomRules(field, rule, msg, reqVal, errsBag)
+			}
+		}
+	}
+
+	return errsBag
+}
+
+// getNonRequiredFields remove non required rules fields from rules if requiredDefault field is false
+// and if the input data is empty for this field
+func (v *Validator) getNonRequiredFields() map[string]struct{} {
+	if v.Opts.FormSize > 0 {
+		v.Opts.Request.ParseMultipartForm(v.Opts.FormSize)
+	} else {
+		v.Opts.Request.ParseMultipartForm(defaultFormSize)
+	}
+
+	inputs := v.Opts.Request.Form
+	nr := make(map[string]struct{})
+	if !v.Opts.RequiredDefault {
+		for k, r := range v.Opts.Rules {
+			isFile := strings.HasPrefix(k, "file:")
+			if _, ok := inputs[k]; !ok && !isFile {
+				if !isContainRequiredField(r) {
+					nr[k] = struct{}{}
+				}
+			}
+		}
+	}
+	return nr
+}
+
+// ValidateJSON validate request data from JSON body to Go struct
+// see example in README.md file
+func (v *Validator) ValidateJSON() url.Values {
+	if len(v.Opts.Rules) == 0 {
+		panic(errValidateArgsMismatch)
+	}
+	if len(v.Opts.Rules) == 0 || v.Opts.Request == nil {
+		panic(errValidateArgsMismatch)
+	}
+	if reflect.TypeOf(v.Opts.Data).Kind() != reflect.Ptr {
+		panic(errRequirePtr)
+	}
+	errsBag := url.Values{}
+
+	defer v.Opts.Request.Body.Close()
+	err := json.NewDecoder(v.Opts.Request.Body).Decode(v.Opts.Data)
+	if err != nil {
+		errsBag.Add("_error", err.Error())
+		return errsBag
+	}
+	r := roller{}
+	r.setTagIdentifier(tagIdentifier)
+	if v.Opts.TagIdentifier != "" {
+		r.setTagIdentifier(v.Opts.TagIdentifier)
+	}
+	r.setTagSeparator(tagSeparator)
+	r.start(v.Opts.Data)
+
+	//clean if the key is not exist or value is empty or zero value
+	nr := v.getNonRequiredJSONFields(r.getFlatMap())
+
+	for field, rules := range v.Opts.Rules {
+		if _, ok := nr[field]; ok {
+			continue
+		}
+		value, _ := r.getFlatVal(field)
+		for _, rule := range rules {
+			if !isRuleExist(rule) {
+				panic(fmt.Errorf("govalidator: %s is not a valid rule", rule))
+			}
+			msg := v.getCustomMessage(field, rule)
+			validateCustomRules(field, rule, msg, value, errsBag)
+		}
+	}
+
+	return errsBag
+}
+
+// getNonRequiredJSONFields get non required rules fields from rules if requiredDefault field is false
+// and if the input data is empty for this field
+func (v *Validator) getNonRequiredJSONFields(inputs map[string]interface{}) map[string]struct{} {
+	nr := make(map[string]struct{})
+	if !v.Opts.RequiredDefault {
+		for k, r := range v.Opts.Rules {
+			if val := inputs[k]; isEmpty(val) {
+				if !isContainRequiredField(r) {
+					nr[k] = struct{}{}
+				}
+			}
+		}
+	}
+	return nr
+}
+
+//ValidateJSONData method
+func (v *Validator) ValidateJSONData() url.Values {
+
+	if len(v.Opts.Rules) == 0 {
+		panic(errValidateArgsMismatch)
+	}
+
+	errsBag := url.Values{}
+
+	//This code is working - Do not delete
+	unmarshalError := json.Unmarshal(v.Opts.JSONData, &v.Opts.Data)
+	if unmarshalError != nil {
+		errsBag.Add("_error", unmarshalError.Error())
+		return errsBag
+	}
+
+	// data := make(map[string]interface{}, 0)
+	// v.Opts.Data = &data
+
+	// decodeError := json.NewDecoder(bytes.NewBuffer(v.Opts.JSONData)).Decode(v.Opts.Data)
+	// if decodeError != nil {
+	// 	errsBag.Add("_error", decodeError.Error())
+	// 	return errsBag
+	// }
+
+	r := roller{}
+	r.setTagIdentifier(tagIdentifier)
+	if v.Opts.TagIdentifier != "" {
+		r.setTagIdentifier(v.Opts.TagIdentifier)
+	}
+	r.setTagSeparator(tagSeparator)
+	r.start(v.Opts.Data)
+
+	//clean if the key is not exist or value is empty or zero value
+	nr := v.getNonRequiredJSONFields(r.getFlatMap())
+
+	for field, rules := range v.Opts.Rules {
+		if _, ok := nr[field]; ok {
+			continue
+		}
+		value, _ := r.getFlatVal(field)
+		for _, rule := range rules {
+			if !isRuleExist(rule) {
+				panic(fmt.Errorf("govalidator: %s is not a valid rule", rule))
+			}
+			msg := v.getCustomMessage(field, rule)
+			validateCustomRules(field, rule, msg, value, errsBag)
+		}
+	}
+
+	return errsBag
+}
+
+//ValidateJSONData method
+func (v *Validator) ValidateJSONString() url.Values {
+
+	if len(v.Opts.Rules) == 0 {
+		panic(errValidateArgsMismatch)
+	}
+
+	errsBag := url.Values{}
+
+	r := roller{}
+	r.setTagIdentifier(tagIdentifier)
+	if v.Opts.TagIdentifier != "" {
+		r.setTagIdentifier(v.Opts.TagIdentifier)
+	}
+	r.setTagSeparator(tagSeparator)
+	r.start(v.Opts.Data)
+
+	//clean if the key is not exist or value is empty or zero value
+	nr := v.getNonRequiredJSONFields(r.getFlatMap())
+
+	for field, rules := range v.Opts.Rules {
+		if _, ok := nr[field]; ok {
+			continue
+		}
+		value, _ := r.getFlatVal(field)
+		for _, rule := range rules {
+			if !isRuleExist(rule) {
+				panic(fmt.Errorf("govalidator: %s is not a valid rule", rule))
+			}
+			msg := v.getCustomMessage(field, rule)
+			validateCustomRules(field, rule, msg, value, errsBag)
+		}
+	}
+
+	return errsBag
+}
diff --git a/validationmdl/validationcore/validator_test.go b/validationmdl/validationcore/validator_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..6d1397f0a09c8a24c5f0469a4ef320dce19ba519
--- /dev/null
+++ b/validationmdl/validationcore/validator_test.go
@@ -0,0 +1,186 @@
+package govalidator
+
+import (
+	"bytes"
+	"encoding/json"
+	"net/http"
+	"net/url"
+	"testing"
+)
+
+func TestValidator_SetDefaultRequired(t *testing.T) {
+	v := New(Options{})
+	v.SetDefaultRequired(true)
+	if !v.Opts.RequiredDefault {
+		t.Error("SetDefaultRequired failed")
+	}
+}
+
+func TestValidator_Validate(t *testing.T) {
+	var URL *url.URL
+	URL, _ = url.Parse("http://www.example.com")
+	params := url.Values{}
+	params.Add("name", "John Doe")
+	params.Add("username", "jhondoe")
+	params.Add("email", "john@mail.com")
+	params.Add("zip", "8233")
+	URL.RawQuery = params.Encode()
+	r, _ := http.NewRequest("GET", URL.String(), nil)
+	rulesList := MapData{
+		"name":  []string{"required"},
+		"age":   []string{"between:5,16"},
+		"email": []string{"email"},
+		"zip":   []string{"digits:4"},
+	}
+
+	opts := Options{
+		Request: r,
+		Rules:   rulesList,
+	}
+	v := New(opts)
+	validationError := v.Validate()
+	if len(validationError) > 0 {
+		t.Error("Validate failed to validate correct inputs!")
+	}
+
+	defer func() {
+		if r := recover(); r == nil {
+			t.Errorf("Validate did not panic")
+		}
+	}()
+
+	v1 := New(Options{Rules: MapData{}})
+	v1.Validate()
+}
+
+func Benchmark_Validate(b *testing.B) {
+	var URL *url.URL
+	URL, _ = url.Parse("http://www.example.com")
+	params := url.Values{}
+	params.Add("name", "John Doe")
+	params.Add("age", "27")
+	params.Add("email", "john@mail.com")
+	params.Add("zip", "8233")
+	URL.RawQuery = params.Encode()
+	r, _ := http.NewRequest("GET", URL.String(), nil)
+	rulesList := MapData{
+		"name":  []string{"required"},
+		"age":   []string{"numeric_between:18,60"},
+		"email": []string{"email"},
+		"zip":   []string{"digits:4"},
+	}
+
+	opts := Options{
+		Request: r,
+		Rules:   rulesList,
+	}
+	v := New(opts)
+	for n := 0; n < b.N; n++ {
+		v.Validate()
+	}
+}
+
+//============ validate json test ====================
+
+func TestValidator_ValidateJSON(t *testing.T) {
+	type User struct {
+		Name    string `json:"name"`
+		Email   string `json:"email"`
+		Address string `json:"address"`
+		Age     int    `json:"age"`
+		Zip     string `json:"zip"`
+		Color   int    `json:"color"`
+	}
+
+	postUser := User{
+		Name:    "",
+		Email:   "inalid email",
+		Address: "",
+		Age:     1,
+		Zip:     "122",
+		Color:   5,
+	}
+
+	rules := MapData{
+		"name":    []string{"required"},
+		"email":   []string{"email"},
+		"address": []string{"required", "between:3,5"},
+		"age":     []string{"bool"},
+		"zip":     []string{"len:4"},
+		"color":   []string{"min:10"},
+	}
+
+	var user User
+
+	body, _ := json.Marshal(postUser)
+	req, _ := http.NewRequest("POST", "http://www.example.com", bytes.NewReader(body))
+
+	opts := Options{
+		Request: req,
+		Data:    &user,
+		Rules:   rules,
+	}
+
+	vd := New(opts)
+	vd.SetTagIdentifier("json")
+	validationErr := vd.ValidateJSON()
+	if len(validationErr) != 5 {
+		t.Error("ValidateJSON failed")
+	}
+}
+
+func TestValidator_ValidateJSON_NULLValue(t *testing.T) {
+	type User struct {
+		Name   string `json:"name"`
+		Count  Int    `json:"count"`
+		Option Int    `json:"option"`
+		Active Bool   `json:"active"`
+	}
+
+	rules := MapData{
+		"name":   []string{"required"},
+		"count":  []string{"required"},
+		"option": []string{"required"},
+		"active": []string{"required"},
+	}
+
+	postUser := map[string]interface{}{
+		"name":   "John Doe",
+		"count":  0,
+		"option": nil,
+		"active": nil,
+	}
+
+	var user User
+	body, _ := json.Marshal(postUser)
+	req, _ := http.NewRequest("POST", "http://www.example.com", bytes.NewReader(body))
+
+	opts := Options{
+		Request: req,
+		Data:    &user,
+		Rules:   rules,
+	}
+
+	vd := New(opts)
+	vd.SetTagIdentifier("json")
+	validationErr := vd.ValidateJSON()
+	if len(validationErr) != 2 {
+		t.Error("ValidateJSON failed")
+	}
+}
+
+func TestValidator_ValidateJSON_panic(t *testing.T) {
+	defer func() {
+		if r := recover(); r == nil {
+			t.Errorf("ValidateJSON did not panic")
+		}
+	}()
+
+	opts := Options{}
+
+	vd := New(opts)
+	validationErr := vd.ValidateJSON()
+	if len(validationErr) != 5 {
+		t.Error("ValidateJSON failed")
+	}
+}
diff --git a/validationmdl/validationmdl.go b/validationmdl/validationmdl.go
index 3e84dec45515e2d71ac6aa5f7b01e329b179fdc5..c11f1e13ed6aff7b823be4db40f864e67c0ba6e0 100644
--- a/validationmdl/validationmdl.go
+++ b/validationmdl/validationmdl.go
@@ -1,47 +1,115 @@
 package validationmdl
 
 import (
-	"errors"
-	"net/http"
 	"net/url"
 
-	"corelab.mkcl.org/MKCLOS/coredevelopmentplatform/corepkgv2/errormdl"
-	govalidator "github.com/asaskevich/govalidator"
-	requestValidator "github.com/thedevsaddam/govalidator"
+	"github.com/tidwall/gjson"
+
+	"corelab.mkcl.org/MKCLOS/coredevelopmentplatform/corepkgv2/loggermdl"
+
+	requestValidator "corelab.mkcl.org/MKCLOS/coredevelopmentplatform/corepkgv2/validationmdl/validationcore"
 )
 
-//ValidateRequest func validates the given model
-func ValidateRequest(httpRequest *http.Request, validationRules, validationMessages requestValidator.MapData) map[string]interface{} {
+// var cnt int
+
+// //ValidateRequest func validates the given model
+// func ValidateRequest(httpRequest *http.Request, validationRules, validationMessages requestValidator.MapData) map[string]interface{} {
+
+// 	cnt++
+// 	//Get the content type of the request as validations for content types are different
+// 	contentType := httpRequest.Header.Get("Content-Type")
+
+// 	//Initialize the validation errors as blank
+// 	var validationErrors url.Values
+
+// 	//Set validator options
+// 	opts := requestValidator.Options{
+// 		Request: httpRequest,
+// 		Rules:   validationRules,
+// 	}
+
+// 	//Set custom validation messages if sent from user
+// 	if validationMessages != nil {
+// 		opts.Messages = validationMessages
+// 	}
+
+// 	if contentType == "application/json" || contentType == "text/plain" {
+// 		//Validate request type json and text (RAW data from request)
+// 		data := make(map[string]interface{}, 0)
+// 		opts.Data = &data
+// 		validator := requestValidator.New(opts)
+// 		validationErrors = validator.ValidateJSON()
+
+// 	} else {
+// 		//Validate request type form-data, form-urlencoded
+// 		validator := requestValidator.New(opts)
+// 		validationErrors = validator.Validate()
+// 	}
+
+// 	if len(validationErrors) > 0 {
+// 		errs := map[string]interface{}{"validationErrors": validationErrors}
+// 		return errs
+// 	}
+// 	return nil
+// }
+
+// // ValidateStruct validates the structures with govalidator
+// func ValidateStruct(structToValidate interface{}) error {
+// 	validationResult, err := govalidator.ValidateStruct(structToValidate)
+// 	if err != nil {
+// 		return err
+// 	}
+// 	if !errormdl.CheckBool(validationResult) {
+// 		return errors.New("ERROR:ValidateStruct function error")
+// 	}
+// 	return nil
+// }
+
+// //ValidateJSONData to validate JSON data
+// func ValidateJSONData(jsonData []byte, validationRules, validationMessages requestValidator.MapData) map[string]interface{} {
+
+// 	//Initialize the validation errors as blank
+// 	var validationErrors url.Values
+
+// 	//Set validator options
+// 	opts := requestValidator.Options{
+// 		Rules:    validationRules,
+// 		JSONData: jsonData,
+// 	}
 
-	//Get the content type of the request as validations for content types are different
-	contentType := httpRequest.Header.Get("Content-Type")
+// 	//Set custom validation messages if sent from user
+// 	if validationMessages != nil {
+// 		opts.Messages = validationMessages
+// 	}
+
+// 	validator := requestValidator.New(opts)
+// 	validationErrors = validator.ValidateJSONData()
+
+// 	if len(validationErrors) > 0 {
+// 		errs := map[string]interface{}{"validationErrors": validationErrors}
+// 		return errs
+// 	}
+
+// 	return nil
+// }
+
+// ValidateJSONString to validate JSON data
+func ValidateJSONString(jsonString string, validationRules, validationMessages requestValidator.MapData) map[string]interface{} {
 
-	//Initialize the validation errors as blank
 	var validationErrors url.Values
 
-	//Set validator options
 	opts := requestValidator.Options{
-		Request: httpRequest,
-		Rules:   validationRules,
+		Rules: validationRules,
 	}
-
-	//Set custom validation messages if sent from user
-	if validationMessages != nil {
-		opts.Messages = validationMessages
+	data, ok := gjson.Parse(jsonString).Value().(map[string]interface{})
+	if !ok {
+		loggermdl.LogError("can not cast to map")
+		return nil
 	}
+	opts.Data = data
 
-	if contentType == "application/json" || contentType == "text/plain" {
-		//Validate request type json and text (RAW data from request)
-		data := make(map[string]interface{}, 0)
-		opts.Data = &data
-		validator := requestValidator.New(opts)
-		validationErrors = validator.ValidateJSON()
-
-	} else {
-		//Validate request type form-data, form-urlencoded
-		validator := requestValidator.New(opts)
-		validationErrors = validator.Validate()
-	}
+	validator := requestValidator.New(opts)
+	validationErrors = validator.ValidateJSONString()
 
 	if len(validationErrors) > 0 {
 		errs := map[string]interface{}{"validationErrors": validationErrors}
@@ -50,14 +118,25 @@ func ValidateRequest(httpRequest *http.Request, validationRules, validationMessa
 	return nil
 }
 
-// ValidateStruct validates the structures with govalidator
-func ValidateStruct(structToValidate interface{}) error {
-	validationResult, err := govalidator.ValidateStruct(structToValidate)
-	if err != nil {
-		return err
+// ValidateGJSONResult to validate JSON data
+func ValidateGJSONResult(rs *gjson.Result, validationRules, validationMessages requestValidator.MapData) map[string]interface{} {
+
+	var validationErrors url.Values
+	opts := requestValidator.Options{
+		Rules: validationRules,
 	}
-	if !errormdl.CheckBool(validationResult) {
-		return errors.New("ERROR:ValidateStruct function error")
+	data, ok := rs.Value().(map[string]interface{})
+	if !ok {
+		loggermdl.LogError("can not cast to map")
+		return nil
+	}
+	opts.Data = data
+
+	validator := requestValidator.New(opts)
+	validationErrors = validator.ValidateJSONString()
+	if len(validationErrors) > 0 {
+		errs := map[string]interface{}{"validationErrors": validationErrors}
+		return errs
 	}
 	return nil
 }
diff --git a/validationmdl/validationmdl_test.go b/validationmdl/validationmdl_test.go
index 46bbdbb5cc41f90974d10a7123dfca08fd0025da..03230890080198ab6ad8efd19ae3634801bd0c62 100644
--- a/validationmdl/validationmdl_test.go
+++ b/validationmdl/validationmdl_test.go
@@ -1,18 +1,10 @@
 package validationmdl
 
 import (
-	"bytes"
-	"net/http"
-	"net/url"
-	"reflect"
-	"strings"
 	"testing"
 
-	"corelab.mkcl.org/MKCLOS/coredevelopmentplatform/corepkgv2/errormdl"
-	"github.com/caibirdme/yql"
-	"github.com/pquerna/ffjson/ffjson"
-	"github.com/stretchr/testify/assert"
-	requestValidator "github.com/thedevsaddam/govalidator"
+	"corelab.mkcl.org/MKCLOS/coredevelopmentplatform/corepkgv2/loggermdl"
+	requestValidator "corelab.mkcl.org/MKCLOS/coredevelopmentplatform/corepkgv2/validationmdl/validationcore"
 )
 
 type RequestBodyData struct {
@@ -32,295 +24,401 @@ var validationMessages = requestValidator.MapData{
 	"password": []string{"required:Password required"},
 }
 
-func TestValidateRequest(t *testing.T) {
-
-	//Cases for sending raw data in request
-	//Case 1: Http request for sunny day scenario
-	sunnyDayData := RequestBodyData{Email: "test@mkcl.org", Password: "test"}
-	sunnyDayByteArray, _ := ffjson.Marshal(&sunnyDayData)
-	sunnyDayHTTPRequest, _ := http.NewRequest("POST", "test.com", bytes.NewBufferString(string(sunnyDayByteArray)))
-	sunnyDayHTTPRequest.Header.Set("Content-Type", "application/json")
-
-	//Case 2 : Http request for blank email
-	blankEmailData := RequestBodyData{Email: "", Password: "test"}
-	blankEmailByteArray, _ := ffjson.Marshal(&blankEmailData)
-	blankEmailHTTPRequest, _ := http.NewRequest("POST", "test.com", bytes.NewBufferString(string(blankEmailByteArray)))
-	blankEmailHTTPRequest.Header.Set("Content-Type", "application/json")
-	blankEmailExpectedResult := map[string]interface{}{
-		"validationErrors": url.Values{
-			"email": []string{"Email required", "Email min len", "Invalid email"},
-		},
-	}
+// func TestValidateRequest(t *testing.T) {
+
+// 	//Cases for sending raw data in request
+// 	//Case 1: Http request for sunny day scenario
+// 	sunnyDayData := RequestBodyData{Email: "test@mkcl.org", Password: "test"}
+// 	sunnyDayByteArray, _ := ffjson.Marshal(&sunnyDayData)
+// 	sunnyDayHTTPRequest, _ := http.NewRequest("POST", "test.com", bytes.NewBufferString(string(sunnyDayByteArray)))
+// 	sunnyDayHTTPRequest.Header.Set("Content-Type", "application/json")
+
+// 	//Case 2 : Http request for blank email
+// 	blankEmailData := RequestBodyData{Email: "", Password: "test"}
+// 	blankEmailByteArray, _ := ffjson.Marshal(&blankEmailData)
+// 	blankEmailHTTPRequest, _ := http.NewRequest("POST", "test.com", bytes.NewBufferString(string(blankEmailByteArray)))
+// 	blankEmailHTTPRequest.Header.Set("Content-Type", "application/json")
+// 	blankEmailExpectedResult := map[string]interface{}{
+// 		"validationErrors": url.Values{
+// 			"email": []string{"Email required", "Email min len", "Invalid email"},
+// 		},
+// 	}
+
+// 	//Case 3 : Http request for blank password
+// 	blankPasswordData := RequestBodyData{Email: "test@mkcl.org", Password: ""}
+// 	blankPasswordByteArray, _ := ffjson.Marshal(&blankPasswordData)
+// 	blankPasswordHTTPRequest, _ := http.NewRequest("POST", "test.com", bytes.NewBufferString(string(blankPasswordByteArray)))
+// 	blankPasswordHTTPRequest.Header.Set("Content-Type", "application/json")
+// 	blankPasswordExpectedResult := map[string]interface{}{
+// 		"validationErrors": url.Values{
+// 			"password": []string{"Password required"},
+// 		},
+// 	}
+
+// 	//Case 4 : Http request for email with shorter length than required
+// 	shortEmailLengthData := RequestBodyData{Email: "a@c.v", Password: "test"}
+// 	shortEmailLengthByteArray, _ := ffjson.Marshal(&shortEmailLengthData)
+// 	shortEmailLengthHTTPRequest, _ := http.NewRequest("POST", "test.com", bytes.NewBufferString(string(shortEmailLengthByteArray)))
+// 	shortEmailLengthHTTPRequest.Header.Set("Content-Type", "application/json")
+// 	shortEmailLengthExpectedResult := map[string]interface{}{
+// 		"validationErrors": url.Values{
+// 			"email": []string{"Email min len"},
+// 		},
+// 	}
+
+// 	//Case 5 : Http request for email with longer length than required
+// 	longEmailLengthData := RequestBodyData{Email: "testEmail@Testcompany.testdomain", Password: "test"}
+// 	longEmailLengthByteArray, _ := ffjson.Marshal(&longEmailLengthData)
+// 	longEmailLengthHTTPRequest, _ := http.NewRequest("POST", "test.com", bytes.NewBufferString(string(longEmailLengthByteArray)))
+// 	longEmailLengthHTTPRequest.Header.Set("Content-Type", "application/json")
+// 	longEmailLengthExpectedResult := map[string]interface{}{
+// 		"validationErrors": url.Values{
+// 			"email": []string{"Email max len"},
+// 		},
+// 	}
+
+// 	//Case 6 : Http request for invalid email id
+// 	invalidEmailData := RequestBodyData{Email: "testemail", Password: "test"}
+// 	invalidEmailByteArray, _ := ffjson.Marshal(&invalidEmailData)
+// 	invalidEmailHTTPRequest, _ := http.NewRequest("POST", "test.com", bytes.NewBufferString(string(invalidEmailByteArray)))
+// 	invalidEmailHTTPRequest.Header.Set("Content-Type", "application/json")
+// 	invalidEmailExpectedResult := map[string]interface{}{
+// 		"validationErrors": url.Values{
+// 			"email": []string{"Invalid email"},
+// 		},
+// 	}
+
+// 	//Case 7 : Http request for blank email using form encoding
+// 	sunnyDayForm := url.Values{}
+// 	sunnyDayForm.Add("email", "")
+// 	sunnyDayForm.Add("password", "password")
+// 	sunnyDayHTTPRequestFormEnc, _ := http.NewRequest("POST", "test.com", strings.NewReader(sunnyDayForm.Encode()))
+// 	sunnyDayHTTPRequestFormEnc.PostForm = sunnyDayForm
+// 	sunnyDayHTTPRequestFormEnc.Header.Set("Content-Type", "application/x-www-form-urlencoded")
+// 	sunnyDayExpectedResultFormEnc := map[string]interface{}{
+// 		"validationErrors": url.Values{
+// 			"email": []string{"Email required", "Email min len", "Invalid email"},
+// 		},
+// 	}
+
+// 	//Case 8 : Http request for blank email using form encoding
+// 	blankEmailForm := url.Values{}
+// 	blankEmailForm.Add("email", "")
+// 	blankEmailForm.Add("password", "password")
+// 	blankEmailHTTPRequestFormEnc, _ := http.NewRequest("POST", "test.com", strings.NewReader(blankEmailForm.Encode()))
+// 	blankEmailHTTPRequestFormEnc.PostForm = blankEmailForm
+// 	blankEmailHTTPRequestFormEnc.Header.Set("Content-Type", "application/x-www-form-urlencoded")
+// 	blankEmailExpectedResultFormEnc := map[string]interface{}{
+// 		"validationErrors": url.Values{
+// 			"email": []string{"Email required", "Email min len", "Invalid email"},
+// 		},
+// 	}
+
+// 	//Case 9 : Http request for blank password using form encoding
+// 	blankPasswordForm := url.Values{}
+// 	blankPasswordForm.Add("email", "test@mkcl.org")
+// 	blankPasswordForm.Add("password", "")
+// 	blankPasswordHTTPRequestFormEnc, _ := http.NewRequest("POST", "test.com", strings.NewReader(blankPasswordForm.Encode()))
+// 	blankPasswordHTTPRequestFormEnc.PostForm = blankPasswordForm
+// 	blankPasswordHTTPRequestFormEnc.Header.Set("Content-Type", "application/x-www-form-urlencoded")
+// 	blankPasswordExpectedResultFormEnc := map[string]interface{}{
+// 		"validationErrors": url.Values{
+// 			"password": []string{"Password required"},
+// 		},
+// 	}
+
+// 	//Case 10 : Http request for email with shorter length than required using form encoding
+// 	shortEmailLengthForm := url.Values{}
+// 	shortEmailLengthForm.Add("email", "a@v.c")
+// 	shortEmailLengthForm.Add("password", "testPass")
+// 	shortEmailLengthHTTPRequestFormEnc, _ := http.NewRequest("POST", "test.com", strings.NewReader(shortEmailLengthForm.Encode()))
+// 	shortEmailLengthHTTPRequestFormEnc.PostForm = shortEmailLengthForm
+// 	shortEmailLengthHTTPRequestFormEnc.Header.Set("Content-Type", "application/x-www-form-urlencoded")
+// 	shortEmailLengthExpectedResultFormEnc := map[string]interface{}{
+// 		"validationErrors": url.Values{
+// 			"email": []string{"Email min len"},
+// 		},
+// 	}
+
+// 	//Case 11 : Http request for email with longer length than required using form encoding
+// 	longEmailLengthForm := url.Values{}
+// 	longEmailLengthForm.Add("email", "testEmail@Testcompany.testdomain")
+// 	longEmailLengthForm.Add("password", "testPass")
+// 	longEmailLengthHTTPRequestFormEnc, _ := http.NewRequest("POST", "test.com", strings.NewReader(longEmailLengthForm.Encode()))
+// 	longEmailLengthHTTPRequestFormEnc.PostForm = longEmailLengthForm
+// 	longEmailLengthHTTPRequestFormEnc.Header.Set("Content-Type", "application/x-www-form-urlencoded")
+// 	longEmailLengthExpectedResultFormEnc := map[string]interface{}{
+// 		"validationErrors": url.Values{
+// 			"email": []string{"Email max len"},
+// 		},
+// 	}
+
+// 	//Case 12 : Http request for invalid email using form encoding
+// 	invalidEmailLengthForm := url.Values{}
+// 	invalidEmailLengthForm.Add("email", "testasdfasdf")
+// 	invalidEmailLengthForm.Add("password", "test")
+// 	invalidEmailLengthHTTPRequestFormEnc, _ := http.NewRequest("POST", "test.com", strings.NewReader(invalidEmailLengthForm.Encode()))
+// 	invalidEmailLengthHTTPRequestFormEnc.PostForm = invalidEmailLengthForm
+// 	invalidEmailLengthHTTPRequestFormEnc.Header.Set("Content-Type", "application/x-www-form-urlencoded")
+// 	invalidEmailLengthExpectedResultFormEnc := map[string]interface{}{
+// 		"validationErrors": url.Values{
+// 			"email": []string{"Invalid email"},
+// 		},
+// 	}
+
+// 	type args struct {
+// 		httpRequest        *http.Request
+// 		validationRules    requestValidator.MapData
+// 		validationMessages requestValidator.MapData
+// 	}
+// 	tests := []struct {
+// 		name string
+// 		args args
+// 		want map[string]interface{}
+// 	}{
+// 		{"TestSunnyDay", args{sunnyDayHTTPRequest, validationRules, validationMessages}, nil},
+// 		{"BlankEmailValidation", args{blankEmailHTTPRequest, validationRules, validationMessages}, blankEmailExpectedResult},
+// 		{"BlankPasswordValidation", args{blankPasswordHTTPRequest, validationRules, validationMessages}, blankPasswordExpectedResult},
+// 		{"ShortEmailLengthValidation", args{shortEmailLengthHTTPRequest, validationRules, validationMessages}, shortEmailLengthExpectedResult},
+// 		{"LongEmailLengthValidation", args{longEmailLengthHTTPRequest, validationRules, validationMessages}, longEmailLengthExpectedResult},
+// 		{"InvalidEmailValidation", args{invalidEmailHTTPRequest, validationRules, validationMessages}, invalidEmailExpectedResult},
+// 		{"SunnyDayFormEnc", args{sunnyDayHTTPRequestFormEnc, validationRules, validationMessages}, sunnyDayExpectedResultFormEnc},
+// 		{"BlankEmailValidationFormEnc", args{blankEmailHTTPRequestFormEnc, validationRules, validationMessages}, blankEmailExpectedResultFormEnc},
+// 		{"BlankPasswordValidationFormEnc", args{blankPasswordHTTPRequestFormEnc, validationRules, validationMessages}, blankPasswordExpectedResultFormEnc},
+// 		{"ShortEmailLengthValidationFormEnc", args{shortEmailLengthHTTPRequestFormEnc, validationRules, validationMessages}, shortEmailLengthExpectedResultFormEnc},
+// 		{"LongEmailLengthValidationFormEnc", args{longEmailLengthHTTPRequestFormEnc, validationRules, validationMessages}, longEmailLengthExpectedResultFormEnc},
+// 		{"InvalidEmailLengthValidationFormEnc", args{invalidEmailLengthHTTPRequestFormEnc, validationRules, validationMessages}, invalidEmailLengthExpectedResultFormEnc},
+// 	}
+// 	for _, tt := range tests {
+// 		t.Run(tt.name, func(t *testing.T) {
+// 			if got := ValidateRequest(tt.args.httpRequest, tt.args.validationRules, tt.args.validationMessages); !reflect.DeepEqual(got, tt.want) {
+// 				t.Errorf("ValidateRequest() = %v, want %v", got, tt.want)
+// 			}
+// 		})
+// 	}
+
+// }
+
+// func BenchmarkValidateRequest(b *testing.B) {
+
+// 	//Validation rules
+// 	validationRules := requestValidator.MapData{
+// 		"email":    []string{"required", "min:5", "max:20", "email"},
+// 		"password": []string{"required"},
+// 	}
+// 	//Validation messages
+// 	validationMessages := requestValidator.MapData{
+// 		"email":    []string{"required:Email Id is required", "min:Min length 5 required", "max:Max length 20 allowed", "email:Enter a valid email"},
+// 		"password": []string{"required:Password is required"},
+// 	}
+
+// 	sunnyDayData := RequestBodyData{Email: "test@mkcl.org", Password: "test"}
+// 	sunnyDayByteArray, _ := ffjson.Marshal(&sunnyDayData)
+// 	sunnyDayHTTPRequest, _ := http.NewRequest("POST", "test.com", bytes.NewBufferString(string(sunnyDayByteArray)))
+// 	sunnyDayHTTPRequest.Header.Set("Content-Type", "application/json")
+
+// 	for i := 0; i < b.N; i++ {
+
+// 		ValidateRequest(sunnyDayHTTPRequest, validationRules, validationMessages)
+
+// 	}
+// }
+
+// func BenchmarkYQLTestAgainstValidator(b *testing.B) {
+
+// 	for i := 0; i < b.N; i++ {
+
+// 		rawYQL := `age>=23`
+// 		yql.Match(rawYQL, map[string]interface{}{
+// 			"age": int64(24),
+// 		})
+// 	}
+// }
+
+// func BenchmarkValidationTestAgainstYQL(b *testing.B) {
+
+// 	type TestData struct {
+// 		Age int64 `json:"age"`
+// 	}
+
+// 	validationRules := requestValidator.MapData{
+// 		"age": []string{"required", "min:23"},
+// 	}
+
+// 	sunnyDayData := TestData{Age: 24}
+// 	sunnyDayByteArray, _ := ffjson.Marshal(&sunnyDayData)
+// 	sunnyDayHTTPRequest, _ := http.NewRequest("POST", "test.com", bytes.NewBufferString(string(sunnyDayByteArray)))
+// 	sunnyDayHTTPRequest.Header.Set("Content-Type", "application/json")
+
+// 	for i := 0; i < b.N; i++ {
+// 		ValidateRequest(sunnyDayHTTPRequest, validationRules, nil)
+// 	}
+// }
 
-	//Case 3 : Http request for blank password
-	blankPasswordData := RequestBodyData{Email: "test@mkcl.org", Password: ""}
-	blankPasswordByteArray, _ := ffjson.Marshal(&blankPasswordData)
-	blankPasswordHTTPRequest, _ := http.NewRequest("POST", "test.com", bytes.NewBufferString(string(blankPasswordByteArray)))
-	blankPasswordHTTPRequest.Header.Set("Content-Type", "application/json")
-	blankPasswordExpectedResult := map[string]interface{}{
-		"validationErrors": url.Values{
-			"password": []string{"Password required"},
-		},
-	}
+type StructToValidate struct {
+	Name   string `json:"name" valid:"required,alpha,length(4|8)"`
+	Email  string `json:"email" valid:"required,email"`
+	Age    int    `json:"age" valid:"required,range(18|50)"`
+	Mobile string `json:"mobile" valid:"required"`
+}
 
-	//Case 4 : Http request for email with shorter length than required
-	shortEmailLengthData := RequestBodyData{Email: "a@c.v", Password: "test"}
-	shortEmailLengthByteArray, _ := ffjson.Marshal(&shortEmailLengthData)
-	shortEmailLengthHTTPRequest, _ := http.NewRequest("POST", "test.com", bytes.NewBufferString(string(shortEmailLengthByteArray)))
-	shortEmailLengthHTTPRequest.Header.Set("Content-Type", "application/json")
-	shortEmailLengthExpectedResult := map[string]interface{}{
-		"validationErrors": url.Values{
-			"email": []string{"Email min len"},
-		},
-	}
+func GetProperStruct() StructToValidate {
+	structToValidate := StructToValidate{}
+	structToValidate.Name = "testmkcl"
+	structToValidate.Email = "test@mkcl.org"
+	structToValidate.Age = 40
+	structToValidate.Mobile = "1234567890"
+	return structToValidate
+}
 
-	//Case 5 : Http request for email with longer length than required
-	longEmailLengthData := RequestBodyData{Email: "testEmail@Testcompany.testdomain", Password: "test"}
-	longEmailLengthByteArray, _ := ffjson.Marshal(&longEmailLengthData)
-	longEmailLengthHTTPRequest, _ := http.NewRequest("POST", "test.com", bytes.NewBufferString(string(longEmailLengthByteArray)))
-	longEmailLengthHTTPRequest.Header.Set("Content-Type", "application/json")
-	longEmailLengthExpectedResult := map[string]interface{}{
-		"validationErrors": url.Values{
-			"email": []string{"Email max len"},
-		},
-	}
+func GetErrorStruct() StructToValidate {
+	structToValidate := StructToValidate{}
+	structToValidate.Name = ""
+	structToValidate.Email = "testmkcl.org"
+	structToValidate.Age = 40
+	structToValidate.Mobile = "1234567890"
+	return structToValidate
+}
+func GetEmptyStruct() StructToValidate {
+	structToValidate := StructToValidate{}
+	return structToValidate
+}
 
-	//Case 6 : Http request for invalid email id
-	invalidEmailData := RequestBodyData{Email: "testemail", Password: "test"}
-	invalidEmailByteArray, _ := ffjson.Marshal(&invalidEmailData)
-	invalidEmailHTTPRequest, _ := http.NewRequest("POST", "test.com", bytes.NewBufferString(string(invalidEmailByteArray)))
-	invalidEmailHTTPRequest.Header.Set("Content-Type", "application/json")
-	invalidEmailExpectedResult := map[string]interface{}{
-		"validationErrors": url.Values{
-			"email": []string{"Invalid email"},
-		},
-	}
+// func TestValidateStruct(t *testing.T) {
+// 	structToValidate := GetProperStruct()
+// 	err := ValidateStruct(structToValidate)
+// 	assert.NoError(t, err, "This should not return error")
+// }
+// func TestValidateStructEmptyStruct(t *testing.T) {
+// 	errormdl.IsTestingNegetiveCaseOnCheckBool = true
+// 	structToValidate := GetEmptyStruct()
+// 	err := ValidateStruct(structToValidate)
+// 	errormdl.IsTestingNegetiveCaseOnCheckBool = false
+// 	assert.Error(t, err, "This should return error")
+// }
 
-	//Case 7 : Http request for blank email using form encoding
-	sunnyDayForm := url.Values{}
-	sunnyDayForm.Add("email", "")
-	sunnyDayForm.Add("password", "password")
-	sunnyDayHTTPRequestFormEnc, _ := http.NewRequest("POST", "test.com", strings.NewReader(sunnyDayForm.Encode()))
-	sunnyDayHTTPRequestFormEnc.PostForm = sunnyDayForm
-	sunnyDayHTTPRequestFormEnc.Header.Set("Content-Type", "application/x-www-form-urlencoded")
-	sunnyDayExpectedResultFormEnc := map[string]interface{}{
-		"validationErrors": url.Values{
-			"email": []string{"Email required", "Email min len", "Invalid email"},
-		},
-	}
+// func TestValidateStructInvalidStruct(t *testing.T) {
+// 	errormdl.IsTestingNegetiveCaseOnCheckBool = true
+// 	structToValidate := GetErrorStruct()
+// 	err := ValidateStruct(structToValidate)
+// 	errormdl.IsTestingNegetiveCaseOnCheckBool = false
+// 	assert.Error(t, err, "This should return error")
+// }
+// func TestValidateStructTypeCheck(t *testing.T) {
+// 	errormdl.IsTestingNegetiveCaseOnCheckBool = true
+// 	structToValidate := GetProperStruct()
+// 	err := ValidateStruct(structToValidate)
+// 	errormdl.IsTestingNegetiveCaseOnCheckBool = false
+// 	assert.Error(t, err, "This should return error")
+// }
 
-	//Case 8 : Http request for blank email using form encoding
-	blankEmailForm := url.Values{}
-	blankEmailForm.Add("email", "")
-	blankEmailForm.Add("password", "password")
-	blankEmailHTTPRequestFormEnc, _ := http.NewRequest("POST", "test.com", strings.NewReader(blankEmailForm.Encode()))
-	blankEmailHTTPRequestFormEnc.PostForm = blankEmailForm
-	blankEmailHTTPRequestFormEnc.Header.Set("Content-Type", "application/x-www-form-urlencoded")
-	blankEmailExpectedResultFormEnc := map[string]interface{}{
-		"validationErrors": url.Values{
-			"email": []string{"Email required", "Email min len", "Invalid email"},
-		},
-	}
+// func BenchmarkValidateStruct(b *testing.B) {
+// 	structToValidate := GetProperStruct()
+// 	for i := 0; i < b.N; i++ {
+// 		ValidateStruct(structToValidate)
+// 	}
+// }
 
-	//Case 9 : Http request for blank password using form encoding
-	blankPasswordForm := url.Values{}
-	blankPasswordForm.Add("email", "test@mkcl.org")
-	blankPasswordForm.Add("password", "")
-	blankPasswordHTTPRequestFormEnc, _ := http.NewRequest("POST", "test.com", strings.NewReader(blankPasswordForm.Encode()))
-	blankPasswordHTTPRequestFormEnc.PostForm = blankPasswordForm
-	blankPasswordHTTPRequestFormEnc.Header.Set("Content-Type", "application/x-www-form-urlencoded")
-	blankPasswordExpectedResultFormEnc := map[string]interface{}{
-		"validationErrors": url.Values{
-			"password": []string{"Password required"},
-		},
-	}
+// func TestNewJsonValidation(t *testing.T) {
 
-	//Case 10 : Http request for email with shorter length than required using form encoding
-	shortEmailLengthForm := url.Values{}
-	shortEmailLengthForm.Add("email", "a@v.c")
-	shortEmailLengthForm.Add("password", "testPass")
-	shortEmailLengthHTTPRequestFormEnc, _ := http.NewRequest("POST", "test.com", strings.NewReader(shortEmailLengthForm.Encode()))
-	shortEmailLengthHTTPRequestFormEnc.PostForm = shortEmailLengthForm
-	shortEmailLengthHTTPRequestFormEnc.Header.Set("Content-Type", "application/x-www-form-urlencoded")
-	shortEmailLengthExpectedResultFormEnc := map[string]interface{}{
-		"validationErrors": url.Values{
-			"email": []string{"Email min len"},
-		},
-	}
+// 	// json.NewDecoder(v.Opts.Request.Body).Decode(v.Opts.Data)
 
-	//Case 11 : Http request for email with longer length than required using form encoding
-	longEmailLengthForm := url.Values{}
-	longEmailLengthForm.Add("email", "testEmail@Testcompany.testdomain")
-	longEmailLengthForm.Add("password", "testPass")
-	longEmailLengthHTTPRequestFormEnc, _ := http.NewRequest("POST", "test.com", strings.NewReader(longEmailLengthForm.Encode()))
-	longEmailLengthHTTPRequestFormEnc.PostForm = longEmailLengthForm
-	longEmailLengthHTTPRequestFormEnc.Header.Set("Content-Type", "application/x-www-form-urlencoded")
-	longEmailLengthExpectedResultFormEnc := map[string]interface{}{
-		"validationErrors": url.Values{
-			"email": []string{"Email max len"},
-		},
-	}
+// 	requestBodyData := RequestBodyData{Email: "test@mkcl.org", Password: "test"}
 
-	//Case 12 : Http request for invalid email using form encoding
-	invalidEmailLengthForm := url.Values{}
-	invalidEmailLengthForm.Add("email", "testasdfasdf")
-	invalidEmailLengthForm.Add("password", "test")
-	invalidEmailLengthHTTPRequestFormEnc, _ := http.NewRequest("POST", "test.com", strings.NewReader(invalidEmailLengthForm.Encode()))
-	invalidEmailLengthHTTPRequestFormEnc.PostForm = invalidEmailLengthForm
-	invalidEmailLengthHTTPRequestFormEnc.Header.Set("Content-Type", "application/x-www-form-urlencoded")
-	invalidEmailLengthExpectedResultFormEnc := map[string]interface{}{
-		"validationErrors": url.Values{
-			"email": []string{"Invalid email"},
-		},
-	}
+// 	dataByteArray, _ := ffjson.Marshal(&requestBodyData)
 
-	type args struct {
-		httpRequest        *http.Request
-		validationRules    requestValidator.MapData
-		validationMessages requestValidator.MapData
-	}
-	tests := []struct {
-		name string
-		args args
-		want map[string]interface{}
-	}{
-		{"TestSunnyDay", args{sunnyDayHTTPRequest, validationRules, validationMessages}, nil},
-		{"BlankEmailValidation", args{blankEmailHTTPRequest, validationRules, validationMessages}, blankEmailExpectedResult},
-		{"BlankPasswordValidation", args{blankPasswordHTTPRequest, validationRules, validationMessages}, blankPasswordExpectedResult},
-		{"ShortEmailLengthValidation", args{shortEmailLengthHTTPRequest, validationRules, validationMessages}, shortEmailLengthExpectedResult},
-		{"LongEmailLengthValidation", args{longEmailLengthHTTPRequest, validationRules, validationMessages}, longEmailLengthExpectedResult},
-		{"InvalidEmailValidation", args{invalidEmailHTTPRequest, validationRules, validationMessages}, invalidEmailExpectedResult},
-		{"SunnyDayFormEnc", args{sunnyDayHTTPRequestFormEnc, validationRules, validationMessages}, sunnyDayExpectedResultFormEnc},
-		{"BlankEmailValidationFormEnc", args{blankEmailHTTPRequestFormEnc, validationRules, validationMessages}, blankEmailExpectedResultFormEnc},
-		{"BlankPasswordValidationFormEnc", args{blankPasswordHTTPRequestFormEnc, validationRules, validationMessages}, blankPasswordExpectedResultFormEnc},
-		{"ShortEmailLengthValidationFormEnc", args{shortEmailLengthHTTPRequestFormEnc, validationRules, validationMessages}, shortEmailLengthExpectedResultFormEnc},
-		{"LongEmailLengthValidationFormEnc", args{longEmailLengthHTTPRequestFormEnc, validationRules, validationMessages}, longEmailLengthExpectedResultFormEnc},
-		{"InvalidEmailLengthValidationFormEnc", args{invalidEmailLengthHTTPRequestFormEnc, validationRules, validationMessages}, invalidEmailLengthExpectedResultFormEnc},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			if got := ValidateRequest(tt.args.httpRequest, tt.args.validationRules, tt.args.validationMessages); !reflect.DeepEqual(got, tt.want) {
-				t.Errorf("ValidateRequest() = %v, want %v", got, tt.want)
-			}
-		})
-	}
+// 	opts := requestValidator.Options{
+// 		Rules:    validationRules,
+// 		JSONData: dataByteArray,
+// 	}
 
-}
+// 	validator := requestValidator.New(opts)
+// 	validationErrors := validator.ValidateJSONData()
 
-func BenchmarkValidateRequest(b *testing.B) {
+// 	loggermdl.LogSpot("Validation error : ", validationErrors)
+// }
 
-	//Validation rules
-	validationRules := requestValidator.MapData{
-		"email":    []string{"required", "min:5", "max:20", "email"},
-		"password": []string{"required"},
-	}
-	//Validation messages
-	validationMessages := requestValidator.MapData{
-		"email":    []string{"required:Email Id is required", "min:Min length 5 required", "max:Max length 20 allowed", "email:Enter a valid email"},
-		"password": []string{"required:Password is required"},
-	}
+// func TestNewJsonValidationMDL(t *testing.T) {
 
-	sunnyDayData := RequestBodyData{Email: "test@mkcl.org", Password: "test"}
-	sunnyDayByteArray, _ := ffjson.Marshal(&sunnyDayData)
-	sunnyDayHTTPRequest, _ := http.NewRequest("POST", "test.com", bytes.NewBufferString(string(sunnyDayByteArray)))
-	sunnyDayHTTPRequest.Header.Set("Content-Type", "application/json")
+// 	// json.NewDecoder(v.Opts.Request.Body).Decode(v.Opts.Data)
 
-	for i := 0; i < b.N; i++ {
+// 	// jsonData := RequestBodyData{Email: "test@mkcl.org", Password: "test"}
+// 	// dataByteArray, _ := ffjson.Marshal(&jsonData)
 
-		ValidateRequest(sunnyDayHTTPRequest, validationRules, validationMessages)
+// 	jsonString := `{"email":"test@mkcl.org","password":"test"}`
 
-	}
-}
+// 	// fmt.Println("json string : ", string(dataByteArray))
 
-func BenchmarkYQLTestAgainstValidator(b *testing.B) {
+// 	validationErrors := ValidateJSONString(jsonString, validationRules, validationMessages)
 
-	for i := 0; i < b.N; i++ {
+// 	loggermdl.LogSpot("Validation error : ", validationErrors)
+// }
 
-		rawYQL := `age>=23`
-		yql.Match(rawYQL, map[string]interface{}{
-			"age": int64(24),
-		})
-	}
-}
+//Benchmarking method to test JSON validation without using http request
+// func BenchmarkValidateJSON(b *testing.B) {
 
-func BenchmarkValidationTestAgainstYQL(b *testing.B) {
+// 	jsonData := RequestBodyData{Email: "test@mkcl.org", Password: "test"}
+// 	dataByteArray, _ := ffjson.Marshal(&jsonData)
 
-	type TestData struct {
-		Age int64 `json:"age"`
-	}
+// 	for i := 0; i < b.N; i++ {
+// 		ValidateJSONData(dataByteArray, validationRules, validationMessages)
+// 	}
 
-	validationRules := requestValidator.MapData{
-		"age": []string{"required", "min:23"},
-	}
+// 	// loggermdl.LogError("Count : ", requestValidator)
+// }
 
-	sunnyDayData := TestData{Age: 24}
-	sunnyDayByteArray, _ := ffjson.Marshal(&sunnyDayData)
-	sunnyDayHTTPRequest, _ := http.NewRequest("POST", "test.com", bytes.NewBufferString(string(sunnyDayByteArray)))
-	sunnyDayHTTPRequest.Header.Set("Content-Type", "application/json")
+//Benchmarking method to test JSON validtion using http request
+// func BenchmarkValidateJSONRequest(b *testing.B) {
+
+// 	sunnyDayData := RequestBodyData{Email: "test@mkcl.org", Password: "test"}
+// 	sunnyDayByteArray, _ := ffjson.Marshal(&sunnyDayData)
+// 	sunnyDayHTTPRequest, _ := http.NewRequest("POST", "test.com", bytes.NewBufferString(string(sunnyDayByteArray)))
+// 	sunnyDayHTTPRequest.Header.Set("Content-Type", "application/json")
+
+// 	for i := 0; i < b.N; i++ {
+// 		ValidateRequest(sunnyDayHTTPRequest, validationRules, validationMessages)
+// 	}
+// 	// loggermdl.LogError("Count : ", requestValidator.Cnt)
+// }
+
+// //Benckmarking method to testing JSON string validation
+
+func BenchmarkValidateJSONString(b *testing.B) {
+
+	jsonString := `{"email":"tessdcet@mkcl.org"}`
+	// jsonString := `{"email":"test@mkcl.org","password":"test"}`
+
+	var validationRules = requestValidator.MapData{
+		"email": []string{"required", "email"},
+		// "password": []string{"required"},
+	}
 
 	for i := 0; i < b.N; i++ {
-		ValidateRequest(sunnyDayHTTPRequest, validationRules, nil)
+		ValidateJSONString(jsonString, validationRules, validationMessages)
 	}
 }
 
-type StructToValidate struct {
-	Name   string `json:"name" valid:"required,alpha,length(4|8)"`
-	Email  string `json:"email" valid:"required,email"`
-	Age    int    `json:"age" valid:"required,range(18|50)"`
-	Mobile string `json:"mobile" valid:"required"`
-}
+func TestValidateJSONString(t *testing.T) {
+	jsonString := `{"email": "xcvbnm,./dfghjkl"}`
+	// jsonString1 := `{"password":"testrfew@mkcl.org"}`
+	// jsonString := `{"email":"test@mkcl.org","password":"test"}`
 
-func GetProperStruct() StructToValidate {
-	structToValidate := StructToValidate{}
-	structToValidate.Name = "testmkcl"
-	structToValidate.Email = "test@mkcl.org"
-	structToValidate.Age = 40
-	structToValidate.Mobile = "1234567890"
-	return structToValidate
-}
+	var validationRules1 = requestValidator.MapData{
+		"email": []string{"required"},
+		// "name": []string{"required"},
+	}
 
-func GetErrorStruct() StructToValidate {
-	structToValidate := StructToValidate{}
-	structToValidate.Name = ""
-	structToValidate.Email = "testmkcl.org"
-	structToValidate.Age = 40
-	structToValidate.Mobile = "1234567890"
-	return structToValidate
-}
-func GetEmptyStruct() StructToValidate {
-	structToValidate := StructToValidate{}
-	return structToValidate
-}
-func TestValidateStruct(t *testing.T) {
-	structToValidate := GetProperStruct()
-	err := ValidateStruct(structToValidate)
-	assert.NoError(t, err, "This should not return error")
-}
-func TestValidateStructEmptyStruct(t *testing.T) {
-	errormdl.IsTestingNegetiveCaseOnCheckBool = true
-	structToValidate := GetEmptyStruct()
-	err := ValidateStruct(structToValidate)
-	errormdl.IsTestingNegetiveCaseOnCheckBool = false
-	assert.Error(t, err, "This should return error")
-}
+	// var validationRules2 = requestValidator.MapData{
+	// 	"password": []string{"required"},
+	// 	"email":    []string{"required"},
+	// }
 
-func TestValidateStructInvalidStruct(t *testing.T) {
-	errormdl.IsTestingNegetiveCaseOnCheckBool = true
-	structToValidate := GetErrorStruct()
-	err := ValidateStruct(structToValidate)
-	errormdl.IsTestingNegetiveCaseOnCheckBool = false
-	assert.Error(t, err, "This should return error")
-}
-func TestValidateStructTypeCheck(t *testing.T) {
-	errormdl.IsTestingNegetiveCaseOnCheckBool = true
-	structToValidate := GetProperStruct()
-	err := ValidateStruct(structToValidate)
-	errormdl.IsTestingNegetiveCaseOnCheckBool = false
-	assert.Error(t, err, "This should return error")
-}
-func BenchmarkValidateStruct(b *testing.B) {
-	structToValidate := GetProperStruct()
-	for i := 0; i < b.N; i++ {
-		ValidateStruct(structToValidate)
+	mapErr := ValidateJSONString(jsonString, validationRules1, validationMessages)
+	if mapErr != nil {
+		loggermdl.LogError(mapErr)
 	}
+	// mapErr = ValidateJSONString(jsonString1, validationRules2, validationMessages)
+	// if mapErr != nil {
+	// 	loggermdl.LogError(mapErr)
+	// }
 }