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

  • Full Stack Hands-On Development with .NET

    In the fast-paced realm of modern software development, proficiency across a full stack of technologies is not just beneficial, it's essential. Microsoft has an entire stack of open source development components in its .NET platform (formerly known as .NET Core) that can be used to build an end-to-end set of applications.

  • .NET-Centric Uno Platform Debuts 'Single Project' for 9 Targets

    "We've reduced the complexity of project files and eliminated the need for explicit NuGet package references, separate project libraries, or 'shared' projects."

  • Creating Reactive Applications in .NET

    In modern applications, data is being retrieved in asynchronous, real-time streams, as traditional pull requests where the clients asks for data from the server are becoming a thing of the past.

  • AI for GitHub Collaboration? Maybe Not So Much

    No doubt GitHub Copilot has been a boon for developers, but AI might not be the best tool for collaboration, according to developers weighing in on a recent social media post from the GitHub team.

  • Visual Studio 2022 Getting VS Code 'Command Palette' Equivalent

    As any Visual Studio Code user knows, the editor's command palette is a powerful tool for getting things done quickly, without having to navigate through menus and dialogs. Now, we learn how an equivalent is coming for Microsoft's flagship Visual Studio IDE, invoked by the same familiar Ctrl+Shift+P keyboard shortcut.

Subscribe on YouTube