Friday, January 16, 2015

Playing with JSON Schema

All the new ( 'vNext' ) stuff coming from Microsoft seems to be using JSON configuration files and less XML configuration. Today I was looking into my Azure Scheduled Job configuration and saw this:

{
  "$schema": "http://schemastore.org/schemas/json/webjob-publish-settings.json",
  "webJobName": "myjob-dev",
  "startTime": "2015-01-15T00:00:00+01:00",
  "endTime": "2015-01-16T00:00:00+01:00",
  "jobRecurrenceFrequency": "Day",
  "interval": 1,
  "runMode": "Scheduled"
}

Following the link to the JSON schema file shows you what it looks like:

{
 "title": "JSON schema for Azure Webjobs configuration files",
 "$schema": "http://json-schema.org/draft-04/schema#",

 "type": "object",
 "required": [ "runMode" ],

 "definitions": {
  "shared": {
   "properties": {
    "webJobName": {
     "type": "string",
     "description": "The name of the Azure Webjob."
    },
    "startTime": {
     "type": "string",
     "format": "date-time",
     "description": "The start time of a scheduled job. Example. 2014-06-11T00:00:00-08:00"
    },
    "endTime": {
     "type": "string",
     "format": "date-time",
     "description": "The end time of a scheduled job. Example. 2014-06-12T00:00:00-08:00"
    },
    "jobRecurrenceFrequency": {
     "type": "string",
     "enum": [ "Second", "Minute", "Hour", "Day", "Week", "Month" ],
     "description": "The frequency metric used with the 'interval' property."
    },
    "interval": {
     "type": "integer",
     "description": "The interval of how often the Azure Webjob should run. Use it with the 'intervalType' property."
    }
   }
  },
  "scheduled": {
   "required": [ "webJobName", "startTime", "endTime", "jobRecurrenceFrequency", "interval" ],
   "allOf": [ { "$ref": "#/definitions/shared" } ],
   "properties": {
    "runMode": {
     "type": "string",
     "enum": [ "Scheduled" ],
     "description": "Determines the run mode of the Azure Webjob. \n\n Triggered: manually triggered \n Scheduled: runs on a specific schedule \n Continuous: runs all the time"
    }
   }
  },
  "notScheduled": {
   "required": [ "runMode" ],
   "allOf": [ { "$ref": "#/definitions/shared" } ],
   "properties": {
    "runMode": {
     "type": "string",
     "enum": [ "Continuous", "OnDemand" ],
     "description": "Determines the run mode of the Azure Webjob. \n\n Triggered: manually triggered \n Scheduled: runs on a specific schedule \n Continuous: runs all the time"
    }
   }
  }
 },

 "oneOf": [
  { "$ref": "#/definitions/scheduled" },
  { "$ref": "#/definitions/notScheduled" }
 ]
}

So - JSON Schema for JSON is what XSD is for XML: you define a schema in which you define what information must or can be present inside an element.

I have to say I'm not sure what my position is on this. I'm a strong believer in 'the right tool for the job'. So if you want to write a textfile with information but want to enforce a schema - shouldn't you just use XML? XML with an XSD solved this problem.
You want to send data back and forth between a webserver and a client, without a lot of hassle and overhead and which works great with JavaScript ? Use JSON. JavaScript lets you get away with everything - so does JSON.

Don't get me wrong - I like all the developments in software and this surely adds to something. JSON configuration files wouldn't be possible in a product like Visual Studio if not for a schema. But one should not be affraid of it's dynamic nature and therefore make everything strongly typed. Embrace the dynamic nature of JavaScript and JSON or pick a different tool IMHO.

Anyway - I played around with it a bit and here are some interesting resources:

So here's my attempt at a schema:


{
   "definitions":{
      "car":{
         "title":"Car schema",
         "type":"object",
         "properties":{
            "make":{
               "description":"The manufacturer of the car",
               "type":"string"
            },
            "model":{
               "description":"The model of the car",
               "type":"string"
            }
         },
         "required":[ "make", "model" ]
      },
      "person":{
         "title":"Person schema",
         "type":"object",
         "properties":{
            "firstName":{
               "description":"The firstname of the person",
               "type":"string"
            },
            "lastName":{
               "description":"The family name of the person",
               "type":"string"
            },
            "cars":{
             "type" : "array",
             "items" : [ { "$ref":"#\/definitions\/car" } ]               
            }
         },
         "required":[
            "firstName",
            "lastName",
            "cars"
         ]
      }
   },
   "$ref":"#\/definitions\/person"
}

Which validates this JSON:


{
 "firstName" : "John",
 "lastName" : "Doe",
 "cars" : [
 { "make" : "Ford", "model" : "T" },
 { "make" : "Ford", "model" : "Galaxy" }
 ]
}


Note the $ref thing - makes everything nice and structured. Other than that it's all pretty straight forward.

We're going to see a whole lot more of JSON schema in the future I think - so you might as well read up on it!



No comments:

Post a Comment