Validating JSON in Oracle Mobile Cloud

Jeff Davies
Aug 8, 2017 · 5 min read

I was working with a customer the other day, trouble shooting an API that did not seem to be working when it was access by a MAX application. When he tested the API in MCS (Oracle Mobile Cloud Service), everything liked fine. When he access that API call from MAX, the list control was empty and the message “No data found” was displayed instead.

Fortunately, this customer noticed a small discrepancy between the JSON that was being returned by the API and the expected format of the JSON as specified by the schema. The API’s schema for the returned JSON value was different than the actual return value and that was the root of the problem.

MCS Does Not Validate Your Data

By default, MCS does not validate any of the data that you pass through it. Developers often assume that since MCS allows you to specify the schema, or limits,patterns or ranges on arguments, that MCS is validating these value. It does not. You can see this for yourself by test the HelloValidation API, which specified a 4 digit number in the simple greeting request. Use a 2 digit number instead and MCS will happily provide you with the example data.
There are two main reasons for the lack of automatic validation:
1) Validation takes time and would slow down service response times.
2) If you create a REST service that can take multiple request types and provides multiple response types (application/json, application/x-www-form-urlencoded or multipart/form-data) automating the validation of the payloads is nearly impossible.

However, as developers we know that slower response times are worth the trouble when we are creating new services. In the development phase we need visibility into how the services are running, not execution speed. Fortunately, MCS and Node.js do allow for validation and you can turn it on an off in your custom code.

Adding Validation to Your MCS Code

Adding validation to your code requires a few steps. The first thing you need is your API. I have created a RAML file for my sample API and you can use it to create the same service that I am using for this blog entry. I named the API HelloValidation.

#%RAML 0.8
title: HelloValidation
version: 1.0
baseUri: /mobile/custom/HelloValidation
protocols: [HTTPS]
schemas:
— simplegreeting: |
{
“$schema”: “http://json-schema.org/draft-04/schema#",
“definitions”: {},
“id”: “http://oracle.com/simplegreeting",
“properties”: {
“simplegreeting”: {
“id”: “/properties/simplegreeting”,
“type”: “string”
}
},
“type”: “object”
}

/simplegreeting:
displayName: Simple Greeting
get:
description: |
Get a simple, validated greeting

protocols: [HTTPS]
queryParameters:
id:
displayName: User ID
description: |
The unique ID of the user

type: number
minimum: 1000
maximum: 9999
example: |
1234

required: true
responses:
200:
body:
application/json:
schema: simplegreeting
example: |
{ “simplegreeting” : “Hello John” }

Now you need a JSON validator package. There are several out there but I chose the “jsonschema” package from npm because it seemed easy to use. Please note that I did not do an exhaustive (or even cursory) examination of all available JSON validators so my use of jsonschema is not an endorsement in any way, just a handy example. Feel free to substitute with the validator of your choice.

From MCS download the javascript scaffold for the HelloValidation service and unzip it onto your local hard drive for editing.

Open a command window and navigate to the directory that contains your HelloValidation service.

Type in the following command:
npm install jsonschemma

Once the installation is complete, you will see a node_modules directory. We now need to make your code aware of the existence of this package. Open up the package.json file and the package-lock.json file and compare them. Update the package.json file so that it looks like the following (assuming the version number of jsonschema hasn’t changed since I wrote this).

{
“name”: “hellovalidation”,
“version”: “1.0”,
“description”: “Provide a validated greeting to the caller”,
“main”: “hellovalidation.js”,
“oracleMobile”: {
“dependencies”: {
“apis”: {},
“connectors”: {}
}
},
“dependencies”: {
“jsonschema”: {
“version”: “1.1.1”,
“resolved”: “https://registry.npmjs.org/jsonschema/-/jsonschema-1.1.1.tgz",
“integrity”: “sha1-PO3o4+QR03eHLu+8n98mODy8Ptk=”
}
}
}

Next you need to modify the code for each of the GET methods to provide a validated response. We will also use this code to text invalid requests and responses. Open the hellovalidation.js file. The first thing we want to do is to add some validation to the {id} query parameter on the GET method for simplevalidation. Here is the finished function and I will go over the more interesting lines of code to explain exactly what is going on.

module.exports = function(service) {
var validationActive = true;

/**
* The file samples.txt in the archive that this file was packaged with contains some example code.
*/

service.get(‘/mobile/custom/HelloValidation/simplegreeting’, function(req,res) {
// Get the “id” query parameter as a number. It is a string by default
var id = parseInt(req.query.id);

if(validationActive) {
// Initialize our validator object
var Validator = require(‘jsonschema’).Validator;
var v = new Validator();

// Create a schema for numeric values between 1000 and 9999
var idSchema = {“type”: “number”, “minimum”: 1000, “maximum”: 9999};

console.info(“validating an id with the value: “ + id);
// Validate the query parameter
var vRes = v.validate(id, idSchema);
if(vRes.errors.length > 0) {
// There was an error in the ID. Handle it
console.info(“bad ID: “ + id);
} else {
// Validation passed.
console.info(“good ID: “ + id);
}
console.info(vRes); // Write the validation results to the log.
}

// Create our result object
var result = { “simplegreeting” : “Hello John” };

if(validationActive) {
// Now create our result schema
var resultSchema = {
“$schema”: “http://json-schema.org/draft-04/schema#",
“definitions”: {},
“id”: “http://oracle.com/simplegreeting",
“properties”: {
“simplegreeting”: {
“id”: “/properties/simplegreeting”,
“type”: “string”
}
},
“type”: “object”
}
console.info(v.validate(result, resultSchema));
}

var statusCode = 200; // Success
res.status(statusCode).send(result);
});
};

Note the line near the top of the code:
var validationActive = true;
This is our switch to turning validation on and off. When you move the code to production, this allows you to quickly and easily turn off validation. Of course, you may wish to leave validation turned on in production, especially if your services are being called by partners or the public. It is entirely possible that they may send bad query parameters or payloads either accidentally or deliberately.

Naturally in production code you would want to send errors back to the caller, either in the header or in the body of the response. This example is not meant to show coding best practices, only to show how easy it is to add JSON validation to your projects

Oracle Developers

Aggregation of articles from Oracle & partners engineers, Groundbreaker ambassadors & the developer community on all things Oracle Cloud and its technologies. The views expressed are those of authors solely and do not necessarily reflect Oracle's. Contact @jimgris or @brhubart

Jeff Davies

Written by

Long time software engineer, software architect, technical evangelist and motorcycle enthusiast.

Oracle Developers

Aggregation of articles from Oracle & partners engineers, Groundbreaker ambassadors & the developer community on all things Oracle Cloud and its technologies. The views expressed are those of authors solely and do not necessarily reflect Oracle's. Contact @jimgris or @brhubart

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade