oeCloud - Custom Validation Using Expression Language

This guide helps you to understand the concept of custom validation using Expression Language.

What you’ll learn

By the end of this project you will learn to

  • You’ll build a Location model and add some valid data to it.
  • You’ll build a model Product with some properties.
  • You’ll add custom validation to the Product model which uses Location model for validating data.

What You’ll need:

To complete this guide, you will need the following -

  • an understanding of what a Model is in the context of Loopback, which is the basis of the oeCloud Framework. You can go through the loopback documentation for the same by clicking here
  • an understanding of Model creation. You can go through the How to create a model for the same.
  • 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. You can use API explorer also to complete this guide.
  • an understanding of basic property validations. you can go through the guides for the same. - optional.
  • You should know the basic of usage of Expression Language.

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

Let’s create a model Location using the schema mentioned below.

Location :

{
	"name": "Location",
	"base": "BaseEntity",
	"idInjection": false,
	"strict": "validate",
	"options": {
	    "validateUpsert": true
	},
	"properties": {
	    "companyCode": {
	        "type": "string",
	        "required": true
	    },
	    "locationCode": {
	        "type": "string",
	        "required": true,
	        "max" : 200
	    }
	}
}

Now add some valid data to the Location model.

[
    {
        "companyCode": "WayneInds1301",
        "locationCode": "Gotham2001"
    },
    {
        "companyCode": "StarkInds1402",
        "locationCode": "NewYork2130"
    },
    {
    	"companyCode":"LexCorp666",
    	"locationCode": "Metropolis1234"
	}
]

Let’s create a model Product using the schema mentioned below.

Product :

{
	"name": "Product",
	"base": "BaseEntity",
	"strict": false,
	"plural": "Products",
	"idInjection": true,
	"options": {
		"validateUpsert": true
	},
	"properties": {
		"code": {
			"type": "string",
			"required": true,
			"unique": true
		},
		"name": {
			"type": "string"
		},
		"category": {
			"type": "string",
			"in": ["Premium", "Luxury", "Regular"]
		},
		"buyerCompanyCode": {
            "type": "string",
            "required": true
        },
        "requestedBillingLocation": {
            "type": "Location",
            "required": true
        },
		"price": {
			"type": "number",
			"numericality": "integer"
		},
		"offeredSince": {
			"type": "date"
		},
		"active": {
			"type": "string",
			"in": ["Active", "Inactive"]
		},
		"description": {
			"type": "string"
		}
	},
	 "oeValidations": {
        "productExpiry": {
            "validateWhen": "@i.buyerCompanyCode !== undefined",
            "type": "custom",
            "expression": "(@mLocation.companyCode where locationCode = @i.requestedBillingLocation.locationCode and companyCode = @i.buyerCompanyCode) == @i.buyerCompanyCode"
        }
    }
}

Note : validateWhen used in oeValidations above should be a string specifying a condition.This condition will evaluate to a boolean value, if the value is true then only the oeValidation rule will trigger else it will be skipped(e.g. oeValidation rule productExpiry as per above example will get evaluated only if buyerCompanyCode is not undefined).For more information on validateWhen please refer conditional validation

Let’s use the below mentioned api and post some data to the Product model.

http://localhost:3000/explorer/Product
  • Let’s post some data with valid buyerComapnyCode and requestedBillingLocation
{
	"code": "EX1001",
	"name": "Kryptonium",
	"description": "Fataly injure Superman",
	"category": "Premium",
	"buyerCompanyCode": "LexCorp666" ,
    "requestedBillingLocation" : {
        "companyCode" : "LexCorp666",
        "locationCode" : "Metropolis1234"
    },
	"price": 10000000,
	"offeredSince": "01-01-2002"
}

Results in a valid response with status code 200.

  • Let’s post some data with valid non-matching companyCode and locationCode
{
	"code": "EX1002",
	"name": "Bat-Mobile",
	"description": "Wheeled, self-powered, armoured fighting motor vehicle, frequently used by Batman - manufactured by Wayne Industries",
	"category": "Luxury",
	"buyerCompanyCode": "WayneInds1301" ,
    "requestedBillingLocation" : {
        "companyCode" : "WayneInds1301",
        "locationCode" : "Metropolis1234"
    },
	"price": 1000000,
	"offeredSince": "01-01-2012"
}

Fails with a status code of 422 as the data doesn’t adhere to the applied custom validation constraint.

Summary

Congratulations! You’ve just completed a custom validation example using an application powered by oeCloud.