Practical .NET

Defining JSON Messages with JSON Schema

If you're building a RESTful Web service, you can provide both guidance and control around the JSON messages your service works with by replacing documentation with JSON Schemas.

Say what you want about the complexity of the original technologies for Web Services (WSDL and SOAP), but they did give you the ability to define the structure of the request and response messages for a Web Service's operations.

Without some technology to define messages, the specifications for those messages have to be communicated using examples and (pardon my language) documentation.

Those tools are "human readable" but not "machine readable." As a result, they can't be used to automate the process of validating messages. Developers building consumers have to fall back on their own judgement and submitting sample messages to the Web Service to see if they get rejected.

JSON Schema attempts to address this issue by providing, among other goals, a mechanism to specify the format of JSON messages in a way that's both human and machine readable. This has, in turn, fostered the creation of automated tools for validating specific messages against the specification.

JSON Schema borrows some ideas from XSD, the XML format for defining XML messages. For example, a JSON Schema is itself written in valid JSON; The format of a valid JSON Schema is specified by another JSON schema.

You can follow the progress of the specification at json-schema.org. While the goal is for JSON Schema to be an IETF standard, JSON Schema is still in draft format (the latest draft as of this writing -- draft-07(01) -- was published in January 2018). This hasn't stopped several vendors from creating validation tools based on the draft. Visual Studio, for example, has provided support for JSON Schema since Visual Studio 2013 (that's the reason you've been getting more editing support when modifying .json files like appsettings.json than you did in earlier versions of Visual Studio).

Defining a Schema
In JSON Schema, a schema describes the formats of instances (actual JSON documents). Schemas are identified by names that are URIs (similar to XML namespaces).

As you develop JSON Schemas you'll want to establish a naming convention for your schemas to ensure that two schemas don't ever have the same name. The standard practice with XML namespaces was to incorporate your organization's namespace into the URI (because who in their right mind would use some other organization's URL in their identifiers) which sounds like a good place to begin for designing your JSON URIs.

To begin creating a schema, add a JSON or JSON Schema file to your project. At the top of the file, you can specify the schema's id, the schema that should be used to validate the format of your schema, and a descriptive title. These are all defined using the keywords id, $schema and title, all of which are provided in the draft JSON Schema. Since you can expect your schema to evolve over time, you should probably also include the version keyword. You can also specify the kind of instance that the schema will be used to validate which, typically, will be "object."

While the draft-07 schema is available, Visual Studio only supports schemas based on draft-04. Therefore, I'd begin my schema like this:

{
  "id": "http://www.phvis.com/customerinforequest",
  "$schema": "http://json-schema.org/draft-04/schema#",
  "title": "Customer Information Request",
  "version": "1.0.0",
  "type": "object"

To define the components of your JSON file, you follow that introductory section with the properties keyword. The properties keyword allows you to specify all the properties that may be included in an actual document. Within the properties group, you can define each property that makes up your document using a variety of keywords. This example defines an object with a single string property called customerId with a specified format (using RegEx) and a default value:

  "properties": {
      "customerId": {
         "type": "string",
         "description": "This is the id that uniquely identifies the customer whose information is being requested."
         "pattern": "^[A-Z][0-9]{3}$",
         "default": "A000"
      }   
  }

As you can see, JSON Schema supports more than just validation. Even in this simple example, a schema could be used to provides hints to UI engines (through the pattern keyword) and documentation support (through the description keyword). The default keyword would support code generators.

Additional keywords let you define more constraints. In addition to the pattern keyword, you can use minimum and maximum to set limits for values. The enum keyword lets you specify a specific set of values that can be used with a property. It's not unusual for JSON objects to hold properties that contain arrays and, for those properties, you can specify both the minimum and maximum number of entries and whether all items in the array must be unique.

The #ref keyword lets you reference one part of a schema from another part to support reusability and extensibility. The required keyword lets you specify which properties must be present and which may be omitted (without the required keyword all the items in the properties group are assumed to be optional).

Listing 1 shows a complete schema file with the customerId property marked as required.

Listing 1: A JSON Schema

{
  "id": "http://www.phvis.com/customerinforequest",
  "$schema": "http://json-schema.org/draft-04/schema",
  "title": "Customer Information Request",
  "version": "1.0.0",
  "type": "object"
  "properties": {
      "customerId": {
         "type": "string",
         "description": "This is the id that uniquely identifies the customer whose information is being requested."
         "pattern": "^[A-Z][0-9]{3}$",
         "default": "A000"
      }   
  },
  "required": [ "customerId" ]
}

Using a Schema in Visual Studio
To use a JSON schema to validate a document in Visual Studio, you just need to associate the JSON document with your schema. If your version of Visual Studio supports JSON Schemas then, when editing a JSON file, you'll find a dropdown list at the top of the editing window where you can select from one of the schemas that Visual Studio knows about.

If you want to use a custom schema of your own that's part of your project, just click on your schema in Solution Explorer and then drag it to that dropdown list. Alternatively, you can use the $schema keyword in a JSON file to associate it with a schema. Assuming my schema is in a file called CustomerRequestSchema.json in the same folder as the JSON file I'm editing, I could add this $schema entry to have Visual Studio validate the file against the schema:

{
  "$schema": "RequestCustomerInformation.json",
  '...rest of JSON file…
}

You'll need to close and reopen the document to have your schema applied but, once you do, you'll get IntelliSense support when working with your JSON file.

Now you can ensure that the JSON documents you create match the JSON documents you want both for yourself and other developers.

About the Author

Peter Vogel is a system architect and principal in PH&V Information Services. PH&V provides full-stack consulting from UX design through object modeling to database design. Peter tweets about his VSM columns with the hashtag #vogelarticles. His blog posts on user experience design can be found at http://blog.learningtree.com/tag/ui/.

comments powered by Disqus

Featured

  • Diving Deep into .NET MAUI

    Ever since someone figured out that fiddling bits results in source code, developers have sought one codebase for all types of apps on all platforms, with Microsoft's latest attempt to further that effort being .NET MAUI.

  • Copilot AI Boosts Abound in New VS Code v1.96

    Microsoft improved on its new "Copilot Edit" functionality in the latest release of Visual Studio Code, v1.96, its open-source based code editor that has become the most popular in the world according to many surveys.

  • AdaBoost Regression Using C#

    Dr. James McCaffrey from Microsoft Research presents a complete end-to-end demonstration of the AdaBoost.R2 algorithm for regression problems (where the goal is to predict a single numeric value). The implementation follows the original source research paper closely, so you can use it as a guide for customization for specific scenarios.

  • Versioning and Documenting ASP.NET Core Services

    Building an API with ASP.NET Core is only half the job. If your API is going to live more than one release cycle, you're going to need to version it. If you have other people building clients for it, you're going to need to document it.

  • TypeScript Tops New JetBrains 'Language Promise Index'

    In its latest annual developer ecosystem report, JetBrains introduced a new "Language Promise Index" topped by Microsoft's TypeScript programming language.

Subscribe on YouTube