oeCloud - Property Level Validations

Server side validations are crucial in any application development. This guide demonstrates how oeCloud framework supports the same by attaching “Property level validations” to a model.

Various Property Level Validations:

The property of a model alongside its metadata can have property level validations (i.e. Primitive validations) such as:

ValidationType AllowedValues/DataType Description Fail Condition
min Number/String Requires the property length to be more than or equal to the specified ‘min’ value if the property type is “string”. In case the property is of type “number” it will check for its value. Length or value of the property depending on its type, is less than the specified ‘min’ value.
max Number/String Requires the property length to be less than or equal to the specified ‘max’ value if the property type is “string”. In case the property is of type “number” it will check for its value. Length or value of the property depending on its type, exceeds specified ‘max’ value.
is Number/String Requires the property length to be equal to the specified ‘is’ value if the property type is “string”.In case the property is of type “number” it will check for its value. Length or value of the property depending on its type, is more than or less than the specified ‘is’ value.
required Boolean Requires a model to include a property to be considered valid. Validated field is blank.
absence Boolean Requires a model to not include a property to be considered valid. Validated field is not blank.
in Array Requires a value for property to be in the specified array. value for the property not in the ‘in’ array.
notin Array Requires a value for property not to be in the specified array. value for the property in ’notin’ array.
numericality ‘integer’/’number’ integer: Requires a value for the property to be an integer and not a decimal number. number: Requires a value for the property to be a number. integer: value for the property is not an integer. number: value for the property is not a number.
format RegEx Requires a value for the property to confer to the specified RegEx. nonconformance to the RegEx.
unique Boolean/Object Ensures the value of the property is unique for the model.It is also possible to make a property unique w.r.t another property.This can be achieved by using scopedTo(e.g. “unique”: {“scopedTo”: [property1, property2]}, this makes the current property unique w.r.t property1 and property2) value is not unique for the model.

What you’ll learn

By the end of this guide you will learn to

  • create a Model called Product with the following property validations:

code : required, unique

name : minimum length should be 5, Maximum length can be 10

category : notin (should not be ‘special’)

price : numericality (should be a number)

active :in (active or inactive)

description : is (length should be 25)

  • use the automatically created CRUD REST API of the Product Model to add valid data.

What You’ll need:

  • an understanding of what a Model is in the context of Loopback, which is the basis of the oeCloud Framework. You can get this by using the documentation here
  • an understanding of Model creation. You can get this here.
  • a running NodeJS application built using the oeCloud Framework.
  • a working REST client. You can use the Linux cURL command as a REST client if you have access to a Linux machine or have Git Bash installed on your Windows machine. REST addons for browsers, like Postman for Firefox or Google Chrome also can be used to complete this guide

How to complete this guide:

You can start from scratch and complete each step, or you can bypass basic setup steps that are already familiar to you.

To start from the scratch go to Getting Started

Once you have started the server, open a browser link: http://localhost:3000/explorer/.

Create a Model with Property Level Validations

If you have already created Product model following previous guides you can modify the Product Model. To do this, you can follow the guide Manage a Model. The Modified model should have below schema:

{
    "name": "Product",
    "base": "BaseEntity",
    "plural": "Products",
    "properties": {
        "code": {
            "type": "string",
			"required": true,
			"unique": true
        },
        "name": {
            "type": "string",
			"min": 5,
			"max": 10
        },
        "category": {
            "type": "string",
			"notin": ["Special"]
        },
        "price": {
            "type": "number",
			"numericality": "integer"
        },
        "offeredSince": {
            "type": "date"
        },
        "active": {
            "type": "string",
			"in": ["Active", "Inactive"]
        },
        "description": {
            "type": "string",
			"is": 25
        }
    }
}

If you don’t have the Product Model created then create the Product model with the code, name, category, price, offeredSince, active and description properties along with validations. To do this, you can follow the guide Create a Model with Properties Guide. The Product Model should have above schema.

Verify the Validations

You can verify various property level validations for the Product model by posting the data at following API:

http://localhost:3000/api/Products

POSTing Valid data

Request URL: POST http://localhost:3000/api/Products
Request body:

{
	"code": "EX1001",
	"name": "Espresso..",
	"category": "other",
	"price": 10,
	"offeredSince": "01-01-2012",
	"active": "Active"
}

Response status code: 200
Response body:

{
   "code": "EX1001",
	"name": "Espresso..",
	"category": "other",
	"price": 10,
	"offeredSince": "01-01-2012",
	"active": "Active",
   "id":"57568bbec5ceaf88260eca9d",
   "_isDeleted":false,
   "_type":"Product",
   "_createdBy":"demouser",
   "_modifiedBy":"demouser",
   "_createdOn":"2016-06-07T08:54:22.169Z",
   "_modifiedOn":"2016-06-07T08:54:22.169Z",
   "_version":"e0b58ac6-d1e5-4de2-a3ce-d7f5c75005fd"
}

Verify “min” validation:

{
	"code": "EX1002",
	"name": "Tea",
	"description": "Strong Blend Espresso....",
	"category": "",
	"price": 10,
	"offeredSince": "01-01-2012"
}

Response status code: 422
Response body:

{
  "error": {
    "status": 422,
    "txnId": "82570f70-391c-11e6-a993-8dacb618da3d",
    "errors": [
      {
        "code": "validation-err-001",
        "message": " minimum value criteria for this field is not met",
        "path": "Product->name"
      }
    ]
  }
}

Here the data was not POSTed as length of Product Name has a length 3 which is not matching with the minimum length criteria.

Verify “max” validation:

{
	"code": "EX1002",
	"name": "Caffe Latte",
	"description": "Strong Blend Espresso....",
	"category": "",
	"price": 10,
	"offeredSince": "01-01-2012"
}

Response status code: 422
Response body:

{
  "error": {
    "status": 422,
    "txnId": "e14e9570-391c-11e6-a993-8dacb618da3d",
    "errors": [
      {
        "code": "validation-err-002",
        "message": " maximum value criteria for this field is not met",
        "path": "Product->name"
      }
    ]
  }
}

Here the data was not POSTed as length of Product Name has a length 12 which is not matching with the maximum length criteria.

Verify “is” validation:

{
	"code": "EX1002",
	"name": "Coffee",
	"description": "Strong blend of Espresso..",
	"category": "",
	"price": 10
}

Response status code: 422
Response body:

{
  "error": {
    "status": 422,
    "txnId": "164abb50-391d-11e6-a993-8dacb618da3d",
    "errors": [
      {
        "code": "validation-err-003",
        "message": " length is wrong",
        "path": "Product->description"
      }
    ]
  }
}

Here the data was not POSTed as Product description doesn’t have a length of 25.

Verify “required” validation:

{
	"name": "Coffee",
	"description": "Strong Blend Espresso....",
	"category": "other",
	"price": 10,
	"active": "Active"
}

Response status code: 422
Response body:

{
  "error": {
    "status": 422,
    "txnId": "b9f254c0-391d-11e6-a993-8dacb618da3d",
    "errors": [
      {
        "code": "validation-err-004",
        "message": " field is mandatory",
        "path": "Product->code"
      }
    ]
  }
}

Here the data will not be POSTed as code is required and it’s missing from the data which we are POSTing.

Verify “in” validation:

{
	"code": "EX1002",
	"name": "Coffee",
	"description": "Strong Blend Espresso....",
	"category": "other",
	"price": 10,
	"active": "True"
}

Response status code: 422
Response body:

{
  "error": {
    "status": 422,
    "txnId": "6a4cf7d0-391e-11e6-a993-8dacb618da3d",
    "errors": [
      {
        "code": "validation-err-006",
        "message": "is not included in the list",
        "path": "Product->active"
      }
    ]
  }
}

This data will not be POSTed as active field’s value should be in the list [Active, Inactive] and we are giving the value as “True”.

Verify “notin” validation:

{
	"code": "EX1002",
	"name": "Coffee",
	"description": "Strong Blend Espresso....",
	"category": "Special",
	"price": 10
}

Response status code: 422
Response body:

{
  "error": {
    "status": 422,
    "txnId": "d7405b20-391e-11e6-a993-8dacb618da3d",
    "errors": [
      {
        "code": "validation-err-007",
        "message": "is reserved",
        "path": "Product->category"
      }
    ]
  }
}

This data will not be POSTed as category field’s value should not be in [“special”] and here we have given the value as “special” only.

Verify “numericality” validation:

{
	"code": "EX1002",
	"name": "Coffee",
	"description": "Strong Blend Espresso....",
	"category": "other",
	"price": 10.5,
	"active": "Active"
}

Response status code: 422
Response body:

{
  "error": {
    "status": 422,
    "txnId": "5336f9a0-391f-11e6-a993-8dacb618da3d",
    "errors": [
      {
        "code": "validation-err-009",
        "message": "is not an integer",
        "path": "Product->price"
      }
    ]
  }
}

This data will not be POSTed successfully as price field’s value should be number(Integer) while te value which we are giving is not integer.

Verify “unique” validation:

{
	"code": "EX1001",
	"name": "Coffee",
	"description": "Strong Blend Espresso....",
	"category": "other",
	"price": 11,
	"active": "Active"
}

Response status code: 422
Response body:

{
  "error": {
    "status": 422,
    "txnId": "9d041a40-391f-11e6-a993-8dacb618da3d",
    "errors": [
      {
        "code": "validation-err-011",
        "message": "duplicate value exist - data already exists",
        "path": "Product->code"
      }
    ]
  }
}

This data will not be POSTed successfully as code field’s value should be unique and we already POSTed the data previously with the code EX1001.

Summary

We have seen now how to apply property level validations and validate the data across these validations.